Non stop entertainment! The wackiest NixOS configuration to-date. thevoid.cafe/projects/puzzlevision
nixos flake flake-parts dotfiles home-manager nix

🔧 Cleanup, set up SSH-Agent and use sops for puzzlevision passwords

thevoid.cafe a40b1c28 ddad17d3

verified
+173 -99
+2
.sops.yaml
··· 1 1 keys: 2 2 - &jo age1qcjcwh9tq8pzf2yr7m3hm2n3n3y5rlc30fpkr0eytju9w57ucgcsgcy79d 3 + - &jo_age age1gudgza8lv02nwec0pejqpp5t7zu0tzjsfkmvgvy3ckfscr9f4qrq2sl5dv 3 4 - &absolutesolver age1gudgza8lv02nwec0pejqpp5t7zu0tzjsfkmvgvy3ckfscr9f4qrq2sl5dv 4 5 creation_rules: 5 6 - path_regex: secrets/[^/]+\.(yaml|json|env|cfg)$ ··· 18 19 key_groups: 19 20 - age: 20 21 - *jo 22 + - *jo_age 21 23 22 24 - path_regex: homes/[^/]+/jo/secrets/.*\.(yaml|env|json|cfg)$ 23 25 key_groups:
+9
homes/x86_64-linux/jo/default.nix
··· 24 24 sshKeyFile = "${config.home.homeDirectory}/.ssh/id_ed25519"; 25 25 }; 26 26 27 + security.ssh = { 28 + enable = true; 29 + matchBlocks = { 30 + "git.tangled.sh" = { 31 + user = "git"; 32 + }; 33 + }; 34 + }; 35 + 27 36 ## Active system themes 28 37 themes.catppuccin.enable = true; 29 38
+1 -1
modules/home/cli/direnv/default.nix
··· 22 22 enable = true; 23 23 nix-direnv.enable = true; 24 24 25 - enableFishIntegration = mkIf (osConfig.${namespace}.users.defaultUserShell == pkgs.fish); 25 + enableFishIntegration = osConfig.${namespace}.system.shell.default == "fish"; 26 26 }; 27 27 }; 28 28 }
+10
modules/home/cli/fish/default.nix
··· 1 + { 2 + osConfig, 3 + namespace, 4 + ... 5 + }: 6 + { 7 + # Enable fish through home-manager if enable on system. 8 + # This is required for home.sessionVariables and stuff to work. 9 + programs.fish.enable = osConfig.${namespace}.system.shell.default == "fish"; 10 + }
+48
modules/home/security/ssh/default.nix
··· 1 + { 2 + lib, 3 + self, 4 + config, 5 + namespace, 6 + ... 7 + }: 8 + let 9 + inherit (lib) mkEnableOption mkIf types; 10 + inherit (self.lib) mkOpt; 11 + 12 + cfg = config.${namespace}.security.ssh; 13 + profile = config.${namespace}.profile; 14 + in 15 + { 16 + options.${namespace}.security.ssh = { 17 + enable = mkEnableOption "SSH agent and client configuration."; 18 + matchBlocks = mkOpt (types.attrsOf (types.anything)) { } "SSH match blocks for client config."; 19 + }; 20 + 21 + config = mkIf cfg.enable { 22 + # Enable ssh-agent and configure SSH CLI 23 + services.ssh-agent.enable = true; 24 + programs.ssh = { 25 + enable = true; 26 + 27 + matchBlocks = { 28 + "*" = { 29 + identityFile = profile.sshKeyFile; 30 + addKeysToAgent = "yes"; 31 + }; 32 + } 33 + // cfg.matchBlocks; 34 + }; 35 + 36 + # Set SSH_AUTH_SOCK manually, to beat Gnome/GCR 37 + home.sessionVariables = { 38 + SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/ssh-agent"; 39 + }; 40 + 41 + # Mask/Override GCR SSH component 42 + systemd.user.services.gcr-ssh-agent = { 43 + Unit.Description = "Disabled"; 44 + Service = lib.mkForce { }; 45 + Install.WantedBy = lib.mkForce [ ]; 46 + }; 47 + }; 48 + }
+4
modules/home/themes/catppuccin/default.nix
··· 42 42 ${namespace}.themes.catppuccin = { 43 43 gtk.enable = mkIf osConfig.${namespace}.desktop.gnome.enable true; 44 44 }; 45 + 46 + # Force override GTK theme files, even if gnome modified them 47 + xdg.configFile."gtk-3.0/gtk.css".force = true; 48 + xdg.configFile."gtk-4.0/gtk.css".force = true; 45 49 }; 46 50 }
+1 -18
modules/nixos/archetypes/workstation/default.nix
··· 1 1 { 2 2 lib, 3 - pkgs, 4 3 config, 5 4 namespace, 6 5 ... 7 6 }: 8 7 let 9 - inherit (lib) mkEnableOption mkIf mkDefault; 8 + inherit (lib) mkEnableOption mkIf; 10 9 11 10 cfg = config.${namespace}.archetypes.workstation; 12 11 in ··· 16 15 }; 17 16 18 17 config = mkIf cfg.enable { 19 - environment.sessionVariables = { 20 - MOZ_ENABLE_WAYLAND = "1"; # Firefox native Wayland support 21 - NIXOS_OZONE_WL = "1"; # Native Wayland in Chromium and Electron based applications 22 - }; 23 - 24 18 ${namespace} = { 25 - # Basic system functionality 26 19 system = { 27 20 networking.enable = true; 28 21 grub.enable = true; ··· 32 25 bluetooth.enable = true; 33 26 audio.enable = true; 34 27 kernel.enable = true; 35 - ssh.enable = true; 36 28 nix = { 37 29 enable = true; 38 30 use-lix = true; ··· 40 32 }; 41 33 }; 42 34 43 - # Services 44 - services.docker.enable = true; 45 - 46 35 # Desktop environment 47 36 desktop.gnome.enable = true; 48 37 }; 49 - 50 - environment.systemPackages = with pkgs; [ 51 - nano 52 - ]; 53 - 54 - time.timeZone = mkDefault "Europe/Berlin"; 55 38 }; 56 39 }
+10
modules/nixos/desktop/gnome/default.nix
··· 16 16 }; 17 17 18 18 config = mkIf cfg.enable { 19 + environment.sessionVariables = { 20 + MOZ_ENABLE_WAYLAND = "1"; # Firefox native Wayland support 21 + NIXOS_OZONE_WL = "1"; # Native Wayland in Chromium and Electron based applications 22 + }; 23 + 19 24 services.displayManager.gdm.enable = true; 20 25 services.desktopManager.gnome.enable = true; 21 26 ··· 38 43 ]; 39 44 40 45 programs.dconf.enable = true; 46 + 47 + # Enable gnome-keyring for secret management 41 48 services.gnome.gnome-keyring.enable = true; 49 + 50 + # Unlock gnome-keyring on login 51 + security.pam.services.gdm.enableGnomeKeyring = true; 42 52 43 53 environment.systemPackages = with pkgs; [ 44 54 refine
+10 -2
modules/nixos/services/docker/default.nix
··· 1 1 { 2 2 lib, 3 + pkgs, 3 4 config, 4 5 namespace, 5 6 ... ··· 15 16 }; 16 17 17 18 config = mkIf cfg.enable { 18 - # Enable docker 19 + # Enable docker and auto prune 19 20 virtualisation = { 20 - docker.enable = true; 21 + docker = { 22 + enable = true; 23 + autoPrune = { 24 + enable = true; 25 + dates = "weekly"; 26 + }; 27 + }; 28 + 21 29 oci-containers.backend = "docker"; 22 30 }; 23 31 };
-15
modules/nixos/services/home-manager/default.nix
··· 1 - { ... }: 2 - { 3 - # Todo: rewrite as recursive operation, based on ${namespace}.users 4 - system.userActivationScripts = { 5 - removeConflictingHomeManagerBackups = { 6 - text = '' 7 - rm -f /home/jo/.gtkrc-2.0.homeManagerBackupFileExtension 8 - rm -f /home/jo/.config/gtk-3.0/gtk.css.homeManagerBackupFileExtension 9 - rm -f /home/jo/.config/gtk-4.0/gtk.css.homeManagerBackupFileExtension 10 - ''; 11 - }; 12 - }; 13 - 14 - home-manager.backupFileExtension = "homeManagerBackupFileExtension"; 15 - }
+4
modules/nixos/system/home-manager/default.nix
··· 1 + { ... }: 2 + { 3 + home-manager.backupFileExtension = "hmbackup"; 4 + }
+9
modules/nixos/system/locale/default.nix
··· 33 33 example = "de"; 34 34 description = "Sets the keymap to be used by the system"; 35 35 }; 36 + 37 + timezone = mkOption { 38 + type = lib.types.str; 39 + default = "Europe/Berlin"; 40 + example = "Europe/Berlin"; 41 + description = "Sets the timezone to be used by the system."; 42 + }; 36 43 }; 37 44 38 45 config = mkIf cfg.enable { ··· 55 62 services.xserver = { 56 63 xkb.layout = cfg.keymap; 57 64 }; 65 + 66 + time.timeZone = cfg.timezone; 58 67 }; 59 68 }
+8 -1
modules/nixos/system/networking/default.nix
··· 15 15 }; 16 16 17 17 config = mkIf cfg.enable { 18 - networking.networkmanager.enable = true; 18 + # Enable systemd-resolved DNS backend 19 + services.resolved.enable = true; 20 + 21 + # Enable network manager and configure resolved as DNS backend 22 + networking.networkmanager = { 23 + enable = true; 24 + dns = "systemd-resolved"; 25 + }; 19 26 }; 20 27 }
-35
modules/nixos/system/ssh/default.nix
··· 1 - { 2 - lib, 3 - config, 4 - namespace, 5 - ... 6 - }: 7 - let 8 - inherit (lib) mkEnableOption mkIf; 9 - 10 - cfg = config.${namespace}.system.ssh; 11 - in 12 - { 13 - options.${namespace}.system.ssh = { 14 - enable = mkEnableOption "SSH key management and agent."; 15 - }; 16 - 17 - config = mkIf cfg.enable { 18 - # Add new keys to the relevant SSH agent on first use 19 - programs.ssh = { 20 - extraConfig = '' 21 - AddKeysToAgent yes 22 - ''; 23 - }; 24 - 25 - # Enable Gnome keyring for session overarching key persistence 26 - services.gnome.gnome-keyring.enable = true; 27 - 28 - security.pam.services = { 29 - login.enableGnomeKeyring = true; 30 - 31 - # Unlock keyring on GDM, if enabled 32 - gdm.enableGnomeKeyring = config.services.displayManager.gdm.enable; 33 - }; 34 - }; 35 - }
+9 -4
modules/nixos/users/default.nix
··· 27 27 isSystemUser = self.lib.mkBool false "Whether this user is considered a system user."; 28 28 initialPassword = 29 29 self.lib.mkOpt (types.nullOr types.str) null 30 - "Plaintext insecure initial user password, only recommended for testing."; 30 + "Plaintext insecure initial user password, generally not recommended."; 31 31 password = 32 32 self.lib.mkOpt (types.nullOr types.str) null 33 - "Plaintext insecure user password, only recommended for testing."; 33 + "Plaintext insecure user password, generally not recommended."; 34 34 hashedPasswordFile = 35 35 self.lib.mkOpt (types.nullOr types.str) null 36 36 "Secure, hashed user password stored in a separate file, recommended for production."; 37 37 hashedPassword = 38 38 self.lib.mkOpt (types.nullOr types.str) null 39 - "Secure, hashed password, stored in plaintext, fine to use."; 39 + "Hashed password, stored in plaintext, generally not recommended."; 40 40 extraGroups = 41 41 self.lib.mkOpt (types.listOf types.str) [ ] 42 42 "List of additional groups this user belongs to."; ··· 84 84 useUserPackages = true; 85 85 86 86 extraSpecialArgs = { 87 - inherit self system namespace; 87 + inherit 88 + inputs 89 + self 90 + system 91 + namespace 92 + ; 88 93 }; 89 94 90 95 users = lib.mapAttrs (
+10 -2
systems/x86_64-nixos/puzzlevision/default.nix
··· 1 1 { 2 2 inputs, 3 + config, 3 4 ... 4 5 }: 5 6 { ··· 12 13 ]; 13 14 14 15 # Configure Sops 15 - sops.defaultSopsFile = ./secrets/users.yaml; 16 16 sops.age.keyFile = "/var/lib/sops-nix/key.txt"; 17 17 18 + # Sops user password secret declarations 19 + sops.secrets.jo-password = { 20 + neededForUsers = true; 21 + sopsFile = ./secrets/users.yaml; 22 + key = "users/jo/password_hash"; 23 + }; 24 + 18 25 # Create some helpful groups for development 19 26 # and permission related reasons. 20 27 users.groups = { ··· 26 33 puzzlevision = { 27 34 users.jo = { 28 35 enable = true; 29 - hashedPassword = "$6$mvK9bT756Aok54Vt$vBRnT66Vb3HL0Y5rEMJlHvKkvzVQ.KUciInTmW3FCBFT00IuFMpz3q9RhXPLTLMRPho65bTg9hMnFPb84I774."; 36 + hashedPasswordFile = config.sops.secrets.jo-password.path; 30 37 extraGroups = [ 31 38 "wheel" 32 39 "docker" ··· 35 42 }; 36 43 37 44 archetypes.laptop.enable = true; 45 + services.docker.enable = true; 38 46 }; 39 47 40 48 # Minecraft bootloader theme
+23 -6
systems/x86_64-nixos/puzzlevision/hardware.nix
··· 14 14 inputs.nixos-hardware.nixosModules.common-cpu-intel 15 15 ]; 16 16 17 + # Add low-priority swapfile for hibernation 18 + swapDevices = [ 19 + { 20 + device = "/var/lib/swapfile"; 21 + size = 16 * 1024; 22 + priority = 1; # zram is 50, which means this is a true "last resort" 23 + } 24 + ]; 25 + 26 + # Enable ZRAM 27 + zramSwap = { 28 + enable = true; 29 + priority = 50; 30 + }; 31 + 17 32 # Some boot settings for intel CPU's 18 33 boot = { 34 + # Define device to resume on after hibernation 35 + resumeDevice = "/dev/mapper/luks-5fd4fc76-d5c5-46c3-b952-1a7a7ff3a1fc"; 36 + 37 + # Set hibernation resume offset kernel parameter 38 + kernelParams = [ 39 + "resume_offset=48152718" 40 + ]; 41 + 19 42 # Disable low power mode for rtw88 driver 20 43 extraModprobeConfig = '' 21 44 options rtw88_pci disable_aspm=y ··· 33 56 hardware = { 34 57 enableRedistributableFirmware = true; 35 58 enableAllHardware = true; 36 - }; 37 - 38 - # Enable ZRAM 39 - zramSwap = { 40 - enable = true; 41 - priority = 50; 42 59 }; 43 60 44 61 services = {
+15 -15
systems/x86_64-nixos/puzzlevision/secrets/users.yaml
··· 1 1 users: 2 2 jo: 3 - password_hash: ENC[AES256_GCM,data:fdHmZC03D7X5Z8/ghp/lAv61+TSTr8i3gpBuwZq94JFsJHoaMwTiE2IqHWg/HtcDfynZTsVKbepORXbUPxL02JaRYHJNNkRg8cMIu9ZMs2b2DqypGKq4gKXEUn0QyuN0G3m9Hw2F8B6GRg==,iv:d2ELe9iQR0c9jnoK/nhzXs7p7Kr2kkqQVUXrUlwIQjY=,tag:7DQ/zTbFPr1tsE4k79Fq7w==,type:str] 3 + password_hash: ENC[AES256_GCM,data:EsK8RkGVMKiDVS3gTdpfbW2vAHymeIGsZJhFkm4fwf104r30R0YC3wPciG4kSPFgJ9RcM7CSKdL9ab1X6ecurCK0j/lsxiC9ei4xgLP8jOmDVgMPxJUd/sZgiFAio07PdtP7ApWAE5Vezg==,iv:JAtUPZFnFOMuRK7IpQs0rkNgAfcbOMamVLJ5KDNVCDQ=,tag:sHs2GFiXY9BPkijlgEjwAg==,type:str] 4 4 sops: 5 5 age: 6 6 - recipient: age1qcjcwh9tq8pzf2yr7m3hm2n3n3y5rlc30fpkr0eytju9w57ucgcsgcy79d 7 7 enc: | 8 8 -----BEGIN AGE ENCRYPTED FILE----- 9 - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvSEdxL2pyZHRiVlFqOE1i 10 - MWpScjRSdEJJZjRmQ0dsRTBYSlFsSncyd1FnCjNDWEI1cHNuVGd4dEJDMXF2NnlI 11 - SFA3NFU3SkpGLzZMNjZtc1JHajhEeXMKLS0tIGhaSDVqSGxaZEwrdFZ6ZDF6a0cw 12 - ZmluTzlkNGFSTmZLNlVYdFBOWTQ2cDgKJL4o95JLEKFI3FUQ2+g4N0GWGohRtmW7 13 - fn7zxQhRFf8U9yE4gI3OBTEweoyJQh+m/JH6XCg7H5jrJjze5miSUQ== 9 + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0YkpabmJJaUZieWdheEFW 10 + czVqeStNRVdjOW1zeDlNM0xRb3ZGQ2l3Wlh3CkFDVlcvRUhCWUJwd1BzQndGYjVm 11 + WWNpL0wveGMrQmMzK0QxK2RsckNIUG8KLS0tIHNGamdBS2h2N21oazl2cHpmNDNy 12 + RVRPMlB0VmY3eWVIZlFzV05yc2xaUVUKqVX8fgs3+IR+EZcxprDLt9lNfUHd3CZx 13 + 7cEwi/ac6JLnsWroGB6IGqN1Kqzeaoyd7zeGrd3pElTqHgOIvZVNGA== 14 14 -----END AGE ENCRYPTED FILE----- 15 - - recipient: age1ajkq0lalyc75tjhdtpx2yshw5y3wt85fwjy24luf69rvpavg33vqw6c3tc 15 + - recipient: age1gudgza8lv02nwec0pejqpp5t7zu0tzjsfkmvgvy3ckfscr9f4qrq2sl5dv 16 16 enc: | 17 17 -----BEGIN AGE ENCRYPTED FILE----- 18 - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjdkFCaFZkZjJuc0dHdE03 19 - Z2N5ZnZrMnFIQ0R5U2NqMjFoWWZSNUl5Mm1FCmxIMDFNSGtOamhtZDJjdi82Ty9h 20 - VU0xN1pza2VpSDA1N01oN3FTUHNxcGcKLS0tIFZhVWFuQ1VXS2dyUEF6NHliNW9I 21 - N21SUVFML3Z3Y3FMV3RiV2pGOUJMd00KyoA9/4gSxQTIInRsiF0gdOqYHoI8s2cG 22 - DozFpSRzkrev6sSxEDJC8N/BmpVm2v8Wzpg572i1trEBQIjZMqqhJA== 18 + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqMDlObW9VNlJLcjIwSG50 19 + MHdoUmkrRmNWdWUzVUVHVTMreldpbW9peTJnCmNlU1NaTnlnNS9YdmdKQ0FWRWFL 20 + VnU1S2xxSVhNQi9RakZPQ29kQ2VHZDQKLS0tIFNBQ3BiUmJRc3J4cDU4eVlaYlF2 21 + ZnR6eXI2ejgxQ0RmNVFvOXJCV21TeE0KSgsG3hU9lVNoeLB58j9Ut/Rt9hfSReju 22 + Mw0Ts3iW4N+K68IcOLwd9W0xvqVXfuAsLQdLLZ0dl66oC/3TCd+yuA== 23 23 -----END AGE ENCRYPTED FILE----- 24 - lastmodified: "2025-05-22T00:25:40Z" 25 - mac: ENC[AES256_GCM,data:5oMgqzkL1+VIAnC28q5CH4Y5Po/B5zg2v3kJAlid71K2CKN2s0xrygTmgHYQ0QlO/BJR5kF1HrBVloAq81jTSDyF7XfrdvBzG4Iqs/kmvMC1ln4khf0ZxaH5Q3caGJSmAH6nXMPOglAwFQEm9BXNuknocuQwUEzB6rijQ3F+yXw=,iv:GGleCn9EX76JcSqzPdZOnDzbfYla1eGQY/srHnZdBVk=,tag:09eZjhMYV0RIUqShsJfN0w==,type:str] 24 + lastmodified: "2026-02-24T22:34:53Z" 25 + mac: ENC[AES256_GCM,data:hirDnXCg3TqOstnBGtQc5nUOEIqsW7cQUse4CiorJ9Q2XYR0wr6TRcbvyFH+tMX8pv+4kO1rGlhT370/lyHSXplOJ+h5swfblXwWrZGqEZ5cYCcWmZWqxRPOmV5XG7F+Me98rjEJ7H2/HtZ7Sc/x6Mw3lcRWS2TJ0cLXuFNVpl0=,iv:2SN59MqehZUmkgZCusI0joaITM/aVpfpnMh5jJbNrX4=,tag:ZJdQeBgxan/9FJVd8G1Dlg==,type:str] 26 26 unencrypted_suffix: _unencrypted 27 - version: 3.10.2 27 + version: 3.11.0