Compare commits

..

5 Commits

Author SHA1 Message Date
Alexander e9ac72d162 Nixos update 26-07-2026 2026-07-26 14:26:41 +02:00
Alexander e68498cd42 Nixos update 19-07-2026 2026-07-19 13:54:34 +02:00
Alexander 2b9e446876 Integrate with yubikey 2026-07-16 13:50:15 +02:00
Alexander 7313f718df Add some more themes 2026-07-16 11:45:06 +02:00
Alexander 233e463f87 Lock with hyprland on idle 2026-07-12 16:12:37 +02:00
8 changed files with 424 additions and 193 deletions
+81
View File
@@ -405,6 +405,87 @@ dov = {
};
#+end_src
** YubiKey
Provides PAM U2F authentication (touch YubiKey for login/sudo) and a seamless SSH agent backed by the YubiKey PIV applet.
#+begin_src nix
dov = {
yubikey.enable = true;
};
#+end_src
*** PAM U2F (login & sudo)
After enabling the module and rebuilding, enroll your YubiKey:
1. Create the YubiKey config directory:
#+begin_src sh
mkdir -p ~/.config/Yubico
#+end_src
2. Generate the U2F key mapping (touch YubiKey when prompted):
#+begin_src bash
nix-shell -p pam_u2f --run 'pamu2fcfg -u fujin' > ~/.config/Yubico/u2f_keys
#+end_src
*Nushell users:* use ~out>~ instead of ~>~:
#+begin_src
nix-shell -p pam_u2f --run 'pamu2fcfg -u fujin' out> ~/.config/Yubico/u2f_keys
#+end_src
3. Add a backup YubiKey (optional):
#+begin_src bash
nix-shell -p pam_u2f --run 'pamu2fcfg -u fujin -n' >> ~/.config/Yubico/u2f_keys
#+end_src
4. Rebuild and switch:
#+begin_src sh
sudo nixos-rebuild switch --flake .#fujin
#+end_src
5. Test:
#+begin_src sh
sudo true # should prompt to touch YubiKey
#+end_src
The default mode is =sufficient= (touch key *or* type password). If the key is absent or not enrolled, the normal password prompt follows — you cannot lock yourself out.
*** SSH with FIDO2-backed keys
The module enables the standard OpenSSH agent (not GPG agent's SSH emulation, which doesn't reliably support =-sk= keys). The YubiKey uses FIDO2 — the same interface that PAM U2F uses — so no PIV/pcscd setup is needed for SSH.
1. Generate a FIDO2-backed SSH key (one-time, touch YubiKey when prompted):
#+begin_src sh
ssh-keygen -t ed25519-sk -C "yubikey@fujin"
#+end_src
*Resident key* (recoverable on a new machine without the stub file):
#+begin_src sh
ssh-keygen -t ed25519-sk -O resident -C "yubikey@fujin"
#+end_src
2. Load the key into the agent (once per login session, enter passphrase):
#+begin_src sh
ssh-add ~/.ssh/id_ed25519_sk
#+end_src
*After a rebuild*, log out and back in so the shell picks up the new =SSH_AUTH_SOCK=. In an existing session:
#+begin_src sh
export SSH_AUTH_SOCK=/run/user/$(id -u)/ssh-agent
#+end_src
3. Copy the public key to remote hosts:
#+begin_src sh
ssh-copy-id -i ~/.ssh/id_ed25519_sk.pub susano
#+end_src
4. Test:
#+begin_src sh
ssh susano # touch YubiKey, no password
#+end_src
Each SSH authentication requires a physical YubiKey touch. The passphrase is only asked when loading the key into the agent (step 2), not per-connection.
*Note:* The key stub (~/.ssh/id_ed25519_sk) is tied to this specific generation — regenerating produces a different key. Back it up or use =-O resident=.
* Notes and Configuration Details
** Remote Build Configuration
To leverage remote builds (e.g., building fujin configurations on izanagi), you need to set up SSH keys for the root user:
+19
View File
@@ -0,0 +1,19 @@
# Backlog
<!-- SECTION: ENTRIES -->
<!-- SECTION: Nixos -->
- [ ] [P2] Add nushell completion for rebuild script *(priority: P2)*
<!-- SECTION: HISTORY -->
<!-- SECTION: Nixos -->
| Timestamp | Item ID | Action | Details |
|-----------|---------|--------|---------|
| 2026-07-26T11:58:28.175Z | n-dk597m | item_created | Add nushell completion for rebuild script |
<!-- SECTION: INTEGRITY -->
<!-- saved: 2026-07-26T11:58:28Z | checksum: sha256:1805e1b08cf2b01e73cdd1dd28269bd5ccf5ccdeaf584ff43d5a68edd3d17cfc | entries: 1 | history: 1 -->
Generated
+137 -173
View File
@@ -20,11 +20,11 @@
]
},
"locked": {
"lastModified": 1782073106,
"narHash": "sha256-dnS5SaZlPqR1E0dPXaPc+lFkBwLUbAgbwsVMk7uA6dY=",
"lastModified": 1784368054,
"narHash": "sha256-zF1iJkBQSDWmRO4/LEeHR1SpKY0lqZaxkoQJpPS9K9U=",
"owner": "hyprwm",
"repo": "aquamarine",
"rev": "6d6e2384f381def4ea4ea81543cba4bbdac72457",
"rev": "9b5f14d9483445e766294eb8fbe0b8f370269ed0",
"type": "github"
},
"original": {
@@ -127,11 +127,11 @@
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1783009466,
"narHash": "sha256-Y4rMf21OEgsoD5Fexu5FoqLJEdDGOIttZ5uM9acIM0s=",
"lastModified": 1784907296,
"narHash": "sha256-UYyGETnsSfPDTFIq/+1Uwe0C5fhqE2cgFXpYHnv8cUc=",
"owner": "9001",
"repo": "copyparty",
"rev": "be31a744852a4c04db4c046c91b509ee163e2b61",
"rev": "10db4236bf864a2f57b3cb2db42eb93a456ea698",
"type": "github"
},
"original": {
@@ -166,11 +166,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1783102384,
"narHash": "sha256-DGkEbz6R7XORnFmWsHwIW0pM55QKAVmtm0OAOJvTUUY=",
"lastModified": 1785062976,
"narHash": "sha256-3PQYC0Gm9NfAJbko6JTtFBlujtXWm7L5VZpUVJRu04c=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "8eb5fada90f17ad128506ed6b2b5b2369494719b",
"rev": "ecf4a1a2d40f5cf118e7ffa255212ffba6036151",
"type": "github"
},
"original": {
@@ -183,11 +183,11 @@
"firefox-gnome-theme": {
"flake": false,
"locked": {
"lastModified": 1779670703,
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=",
"lastModified": 1782007937,
"narHash": "sha256-PbnJr+eB+9Czol3ReI83dUgEhcn0sDK6TSy6ODTQm88=",
"owner": "rafaelmardojai",
"repo": "firefox-gnome-theme",
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9",
"rev": "981bd332015397fb1ca033fa982bd61635160c78",
"type": "github"
},
"original": {
@@ -254,11 +254,29 @@
]
},
"locked": {
"lastModified": 1778716662,
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
"lastModified": 1782949081,
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_3": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": {
"lastModified": 1772408722,
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
"type": "github"
},
"original": {
@@ -300,24 +318,6 @@
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1681202837,
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"fromYaml": {
"flake": false,
"locked": {
@@ -376,43 +376,23 @@
"type": "github"
}
},
"gitignore_2": {
"inputs": {
"nixpkgs": [
"hyprland",
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"gnome-shell": {
"flake": false,
"locked": {
"lastModified": 1767737596,
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
"host": "gitlab.gnome.org",
"lastModified": 1776175984,
"narHash": "sha256-RJFlFW8GiMei6oqUGrMkGEvVqOH8U7Q8abc1yK4VKD8=",
"owner": "GNOME",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
"rev": "e0fdc4c13250e9a9b8ea9594c83925274f4a5dca",
"type": "gitlab"
},
"original": {
"host": "gitlab.gnome.org",
"owner": "GNOME",
"ref": "50.1",
"repo": "gnome-shell",
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
"type": "github"
"type": "gitlab"
}
},
"home-manager": {
@@ -444,11 +424,11 @@
]
},
"locked": {
"lastModified": 1781497404,
"narHash": "sha256-9GAF8sSsnkyCVCWkomXR0T+zdSxyUlfPt6neQidimdg=",
"lastModified": 1783963347,
"narHash": "sha256-r376E2XpakiXwModDHIxlvB6qLq4iFVEq730vxOO4JY=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "1285cd3d6882a9847f2d56ed5541b3350c8a6162",
"rev": "a45a7c451455a51ae740ec3bce4024b312809c29",
"type": "github"
},
"original": {
@@ -532,11 +512,11 @@
"xdph": "xdph"
},
"locked": {
"lastModified": 1783110106,
"narHash": "sha256-PRnnFkTfQ+sQHSrcWw0512zEMNp5/1WHJeVuDf6FmxI=",
"lastModified": 1784980432,
"narHash": "sha256-MZQi0zqZ8c7eIxhhQzC5z7PHh8LWGRRjYqkX0GYbYBg=",
"ref": "refs/heads/main",
"rev": "14fa1fd0273973b7a40966b4fa9e081d6bf67dae",
"revCount": 7549,
"rev": "453d96e92739a2a0b865cf9166d48ba14ec14b7b",
"revCount": 7646,
"type": "git",
"url": "https://github.com/hyprwm/Hyprland"
},
@@ -578,11 +558,11 @@
]
},
"locked": {
"lastModified": 1782563850,
"narHash": "sha256-rs/EzgrgPHbCtJjFZN4aR1HYldH/0NtGAempWVpWQTs=",
"lastModified": 1784196523,
"narHash": "sha256-ahtKMGXFJdlQNhatQm1+BBU/pGfGYnAqQt3vWvq4p8s=",
"owner": "hyprwm",
"repo": "hyprland-guiutils",
"rev": "5ba080ee036c30cb2485f2647ff8a61f7aa08178",
"rev": "a6ccb6cb112ed5a244c0191fb972347ecfa893e0",
"type": "github"
},
"original": {
@@ -608,11 +588,11 @@
]
},
"locked": {
"lastModified": 1782769258,
"narHash": "sha256-HAhqQOoz4S0gzIOMnClL49B+rMT7zdp3UDWeqxtMs/k=",
"lastModified": 1784102347,
"narHash": "sha256-piRpwar7VZI3YviYo0a/UMFz9+rLesfv3nRLGKxjVGg=",
"owner": "hyprwm",
"repo": "hyprland-plugins",
"rev": "71b8953d7d92dbebe87a6ff9895bdd30e7495873",
"rev": "7644cecdb947060682891a0db2a0cdc5c0b9e704",
"type": "github"
},
"original": {
@@ -739,11 +719,11 @@
]
},
"locked": {
"lastModified": 1783002634,
"narHash": "sha256-xGqHIUK0wIZoW7SiMalwvO6uGOO/VrlQwoRobpE7dDI=",
"lastModified": 1784323413,
"narHash": "sha256-XnAVV+H4f8Xdv0yZcSwJ5kCjLyE8fHxPeLX6a3HSrAU=",
"owner": "hyprwm",
"repo": "hyprutils",
"rev": "41fb809557abd29a57151b6e1aaeabd05f9437e1",
"rev": "5f03477ab3a005ff27c527486f551883535aea2f",
"type": "github"
},
"original": {
@@ -811,11 +791,11 @@
"nixpkgs": "nixpkgs_6"
},
"locked": {
"lastModified": 1783008200,
"narHash": "sha256-7019KmcP2U7kx3l60Z5Pgc5SRwbTMHJ2CDuJ/kdhlFA=",
"lastModified": 1783209925,
"narHash": "sha256-NO94JBjSI4jHPaSxXhaZDv3oT7lKpoCzLxjAbWdSjwc=",
"owner": "Lxtharia",
"repo": "minegrub-theme",
"rev": "32272c8e674635c2aefae8fbe2243084dccc6ea0",
"rev": "d0aec4523e1800c3196227dc420d326891292508",
"type": "github"
},
"original": {
@@ -846,11 +826,11 @@
]
},
"locked": {
"lastModified": 1781513248,
"narHash": "sha256-YLeEcfvlQiNXP9bVoIwyB+NMjMxJmkwv/y+AP/7RWYo=",
"lastModified": 1784537139,
"narHash": "sha256-cfJ+PdNNx++NukHKATYBNBnNdIudcDt/BJ7VbFhXx9Q=",
"owner": "Mic92",
"repo": "nix-ld",
"rev": "b320f5cb8b7f141c224c3631539cd0c45fcf7ee3",
"rev": "9fef86f17a711a04399b0f0bf5d8fb7680d5f13b",
"type": "github"
},
"original": {
@@ -900,11 +880,11 @@
"nixpkgs": "nixpkgs_7"
},
"locked": {
"lastModified": 1782562157,
"narHash": "sha256-a7+T6QSeowynwZ1ZJJbP8T8ntAytvrui8kFGJmIZt2c=",
"lastModified": 1784723954,
"narHash": "sha256-1CfD8ZUjCkTgjsneLZ/lxCHhgDfqxxE7/GX0MmsgiqA=",
"owner": "NixOS",
"repo": "nixos-hardware",
"rev": "a9cf7546a938c737b079e738de73934a13de9784",
"rev": "a017f5b72210026af5b3ac5949f08d94380a6fbd",
"type": "github"
},
"original": {
@@ -945,13 +925,28 @@
"type": "github"
}
},
"nixpkgs-lib_2": {
"locked": {
"lastModified": 1772328832,
"narHash": "sha256-e+/T/pmEkLP6BHhYjx6GmwP5ivonQQn0bJdH9YrRB+Q=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "c185c7a5e5dd8f9add5b2f8ebeff00888b070742",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1782847225,
"narHash": "sha256-JC9PjqKYG9ve5U8aDOLQipp3+KLANBHUvGdLZlxzdKI=",
"lastModified": 1784856561,
"narHash": "sha256-J+Bx1Z6Oeoj2FgnBhRMKyUhhtDoOpTgXYaVLZpDjW4A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "95ca1e203c0750115fd4a6f17d5a245dfe6b1edd",
"rev": "597283ad8aa0b331c788e97c4c262d58877074ef",
"type": "github"
},
"original": {
@@ -963,25 +958,11 @@
},
"nixpkgs_10": {
"locked": {
"lastModified": 1682134069,
"narHash": "sha256-TnI/ZXSmRxQDt2sjRYK/8j8iha4B4zP2cnQCZZ3vp7k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fd901ef4bf93499374c5af385b2943f5801c0833",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_11": {
"locked": {
"lastModified": 1781074563,
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=",
"lastModified": 1784007870,
"narHash": "sha256-djcLt/JJphyNt4eDY9XTly+/WbCK5lqWq9lSgCmJkkQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca",
"rev": "18b9261cb3294b6d2a06d03f96872827b8fe2698",
"type": "github"
},
"original": {
@@ -1023,11 +1004,11 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1782723713,
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
"lastModified": 1784796856,
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
"type": "github"
},
"original": {
@@ -1039,11 +1020,11 @@
},
"nixpkgs_5": {
"locked": {
"lastModified": 1782467914,
"narHash": "sha256-pGvFkM8N0xEkIIXDe5YYfbEAvHrk4IxBrjB/x8OomhE=",
"lastModified": 1784356753,
"narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e73de5be04e0eff4190a1432b946d469c794e7b4",
"rev": "61b7c44c4073f0b827768aff0049561b5110ea5a",
"type": "github"
},
"original": {
@@ -1121,11 +1102,11 @@
]
},
"locked": {
"lastModified": 1783105496,
"narHash": "sha256-ZoNxJhEDgEIAH8PM1Qmx6pTzhD6ICkGAe+GYuLKsLq0=",
"lastModified": 1785062220,
"narHash": "sha256-p3Wxo+5p0Y6E3LwA3DdwMMse/GtcaPUmqLilPVfJPe4=",
"owner": "noctalia-dev",
"repo": "noctalia",
"rev": "2abf8758481fa82cc5e5bf5a53269107293cc7ff",
"rev": "e1a4d27f2f2494db2c6e7636b514d1770b16c776",
"type": "github"
},
"original": {
@@ -1146,11 +1127,11 @@
]
},
"locked": {
"lastModified": 1780281641,
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=",
"lastModified": 1783439237,
"narHash": "sha256-WUr8JF2v3n4Y30E5dxv4sAgNJXpVDBoCQNoQ/V4+n4o=",
"owner": "nix-community",
"repo": "NUR",
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01",
"rev": "b70bb66c7bcd162642f3a609bc16843c7059f503",
"type": "github"
},
"original": {
@@ -1162,18 +1143,17 @@
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": "gitignore_2",
"nixpkgs": [
"hyprland",
"nixpkgs"
]
},
"locked": {
"lastModified": 1781733627,
"narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=",
"lastModified": 1784288435,
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
"owner": "cachix",
"repo": "git-hooks.nix",
"rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39",
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
"type": "github"
},
"original": {
@@ -1264,11 +1244,11 @@
]
},
"locked": {
"lastModified": 1783104586,
"narHash": "sha256-vSLKc7m34/g5xH4dwmNZSqxc5OcHeE3qiG3EIz6bJKs=",
"lastModified": 1783174389,
"narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "1ebd41717762d837d5115f7108522c29cdb00fbb",
"rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9",
"type": "github"
},
"original": {
@@ -1285,11 +1265,11 @@
"nix-filter": "nix-filter"
},
"locked": {
"lastModified": 1782237065,
"narHash": "sha256-Oxtr8k+qu4Kd/7BJ5eo8Pfoje8PDIO1YK2+mhCkHRhQ=",
"lastModified": 1784576463,
"narHash": "sha256-XVm8Bi8XasjMP2VOisrPAuJvrB6+rQZW+/TL9kr2Ogs=",
"owner": "zjeffer",
"repo": "split-monitor-workspaces",
"rev": "968a6a603cabf8ab8f5ce5a402e8ed3bfcae69ce",
"rev": "c8a03d993f71a3ae73179ce354e7a54859055f02",
"type": "github"
},
"original": {
@@ -1318,11 +1298,11 @@
"tinted-zed": "tinted-zed"
},
"locked": {
"lastModified": 1783101802,
"narHash": "sha256-/Ti+wDco0f3C9s94RxyBKJyc0BklwYh0a/jFWKeHNYw=",
"lastModified": 1784676123,
"narHash": "sha256-ndyanKzw90yX2nUVFmTuYqXidUNymtMfgmIHyNdhht0=",
"owner": "nix-community",
"repo": "stylix",
"rev": "718c14e8ecba215a65ff955c187fadb9732ddd01",
"rev": "66714e5ce44269ecc58c20d9196da8dbe1b27a31",
"type": "github"
},
"original": {
@@ -1376,21 +1356,6 @@
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"thefuck": {
"inputs": {
"flake-utils": "flake-utils_2",
@@ -1432,11 +1397,11 @@
"tinted-schemes": {
"flake": false,
"locked": {
"lastModified": 1777806186,
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=",
"lastModified": 1781968807,
"narHash": "sha256-yYO3Vw2M0y3TAUqt+9+Mj0zwP3XDTF5/PXcPhhFQ1ZM=",
"owner": "tinted-theming",
"repo": "schemes",
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795",
"rev": "2ccef2f4b22e3cab5a9292811f7133a07eeba4a7",
"type": "github"
},
"original": {
@@ -1448,11 +1413,11 @@
"tinted-tmux": {
"flake": false,
"locked": {
"lastModified": 1778379944,
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=",
"lastModified": 1782012462,
"narHash": "sha256-2iDiD8DQLwS1lGuD9TS8WlvNyDoTs6krWntJbtB2zGo=",
"owner": "tinted-theming",
"repo": "tinted-tmux",
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d",
"rev": "8c4e750f738a742bd73377ee41d3dadedebedef4",
"type": "github"
},
"original": {
@@ -1464,11 +1429,11 @@
"tinted-zed": {
"flake": false,
"locked": {
"lastModified": 1778378178,
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=",
"lastModified": 1782009766,
"narHash": "sha256-VUhBjpGvWqHI7rWeyMYb/u87YJSXHKfVV6S+IelWeO8=",
"owner": "tinted-theming",
"repo": "base16-zed",
"rev": "9cd816033ff969415b190722cddf134e78a5665f",
"rev": "5e8350bcd354e3241ab681a265fa6ef060c40be1",
"type": "github"
},
"original": {
@@ -1479,11 +1444,11 @@
},
"unstable": {
"locked": {
"lastModified": 1782723713,
"narHash": "sha256-oPXCU/SSUokcGaJREHibG1CBX3+s/W7orDWQOZDsEeQ=",
"lastModified": 1784796856,
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b5aa0fbd538984f6e3d201be0005b4463d8b09f8",
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
"type": "github"
},
"original": {
@@ -1500,11 +1465,11 @@
]
},
"locked": {
"lastModified": 1783099620,
"narHash": "sha256-prQSM9PGnrfSaqknJOZ3DCQKbpMiXAWLVC5SHbjLcJ4=",
"lastModified": 1784913159,
"narHash": "sha256-JWq0BfjO4ktpH5USfQNQzdvHpIDT8fSKD5K7LvdMRFs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "b2e4390ff35319c52935d6a700b615da4c0f204d",
"rev": "079a3b5d1aa6a719920a51316253b7d6dd22738d",
"type": "github"
},
"original": {
@@ -1541,15 +1506,14 @@
},
"vscode-server": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_10"
"flake-parts": "flake-parts_3"
},
"locked": {
"lastModified": 1770124655,
"narHash": "sha256-yHmd2B13EtBUPLJ+x0EaBwNkQr9LTne1arLVxT6hSnY=",
"lastModified": 1784312229,
"narHash": "sha256-2uHCSUw341o3my1R0U0YCfbnMEazylxb58evWsjGL50=",
"owner": "nix-community",
"repo": "nixos-vscode-server",
"rev": "92ce71c3ba5a94f854e02d57b14af4997ab54ef0",
"rev": "2f984dfbe7e5271b5c413d3e734374cc1306c921",
"type": "github"
},
"original": {
@@ -1586,11 +1550,11 @@
]
},
"locked": {
"lastModified": 1782311043,
"narHash": "sha256-07zLc2M3/ax+JsjxGTft17/Joua41LHE9/9AC/F9zeU=",
"lastModified": 1784371182,
"narHash": "sha256-S8A1lezEalltWcCp3gAic5lssS0xTSISK6fKODefhOk=",
"owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland",
"rev": "882ad01e195ce201b07c618bbee44a0cad8b9e5a",
"rev": "08d99f727944dd15e4740090305e31c5fb92a50a",
"type": "github"
},
"original": {
@@ -1602,14 +1566,14 @@
"zen-browser": {
"inputs": {
"home-manager": "home-manager_2",
"nixpkgs": "nixpkgs_11"
"nixpkgs": "nixpkgs_10"
},
"locked": {
"lastModified": 1783063269,
"narHash": "sha256-XVOopPVgoWPlhuJajUYNTK/M9j/L/llD6vdH5JE9EKs=",
"lastModified": 1785039979,
"narHash": "sha256-vZjuRK0UgvChYGMeQ8daxiETJ5KQyGx+8u8YHdw5e/g=",
"owner": "0xc000022070",
"repo": "zen-browser-flake",
"rev": "b86380c97016a1c79f535f286a34c0f5b4270a1b",
"rev": "6f5e680db7d105ecf02b4e0d752d48d9083da6c9",
"type": "github"
},
"original": {
+83 -19
View File
@@ -6,7 +6,8 @@ let
cfg = config.dov.dynamic-theme;
schemes = "${pkgs.base16-schemes}/share/themes";
# Single source of truth for builtin themes
# Curated defaults — covers the popular schemes without blowing up
# build memory. Users can add more via `dov.dynamic-theme.themes`.
builtinThemes = {
gruvbox = {
dark = "${schemes}/gruvbox-dark-hard.yaml";
@@ -16,9 +17,42 @@ let
dark = "${schemes}/catppuccin-mocha.yaml";
light = "${schemes}/catppuccin-latte.yaml";
};
nord = {
dark = "${schemes}/nord.yaml";
light = "${schemes}/nord-light.yaml";
};
solarized = {
dark = "${schemes}/solarized-dark.yaml";
light = "${schemes}/solarized-light.yaml";
};
tokyo-night = {
dark = "${schemes}/tokyo-night-dark.yaml";
light = "${schemes}/tokyo-night-light.yaml";
};
rose-pine = {
dark = "${schemes}/rose-pine.yaml";
light = "${schemes}/rose-pine-dawn.yaml";
};
one = {
dark = "${schemes}/onedark.yaml";
light = "${schemes}/one-light.yaml";
};
material = {
dark = "${schemes}/material-darker.yaml";
light = "${schemes}/material-lighter.yaml";
};
google = {
dark = "${schemes}/google-dark.yaml";
light = "${schemes}/google-light.yaml";
};
github = {
dark = "${schemes}/github-dark.yaml";
light = "${schemes}/github.yaml";
};
};
# Generate all theme-variant combinations
# Generate all theme-variant combinations from the configured themes.
# Each theme produces a "-dark" and "-light" variant.
themeVariants = concatMapAttrs (name: theme: {
"${name}-dark" = { scheme = theme.dark; polarity = "dark"; };
"${name}-light" = { scheme = theme.light; polarity = "light"; };
@@ -112,28 +146,42 @@ in {
};
});
default = builtinThemes;
description = "Available themes with dark and light variants";
description = ''
Available themes with dark and light variants. Each entry
generates two specialisations (`<name>-dark` and
`<name>-light`). Add more here to extend the defaults.
'';
};
doomThemes = mkOption {
type = types.attrsOf types.str;
default = {
gruvbox-dark = "doom-gruvbox";
gruvbox-light = "doom-one-light";
catppuccin-dark = "doom-one";
catppuccin-light = "doom-one-light";
};
# Auto-generate sane defaults from the configured themes, then
# overlay specific overrides for schemes that ship a dedicated
# doom-theme.
default =
let
generated = concatMapAttrs (name: _: {
"${name}-dark" = "doom-one";
"${name}-light" = "doom-one-light";
}) cfg.themes;
in generated // {
"gruvbox-dark" = "doom-gruvbox";
"solarized-dark" = "doom-solarized-dark";
"solarized-light" = "doom-solarized-light";
"tokyo-night-dark" = "doom-tokyo-night";
"nord-dark" = "doom-nordic";
"material-dark" = "doom-material";
"rose-pine-dark" = "doom-rose-pine";
"catppuccin-dark" = "doom-catppuccin-mocha";
"catppuccin-light" = "doom-catppuccin-latte";
};
description = ''
Mapping from theme variant name (e.g. "gruvbox-dark") to the Doom
Emacs theme symbol (e.g. "doom-gruvbox") that theme-switch will
live-load via emacsclient when switching to that variant. Variants
absent from this map are left unchanged in Emacs.
Only themes actually installed in Doom will load; the defaults use
themes bundled with doom-themes (so they work out of the box, though
catppuccin variants fall back to generic dark/light). For accurate
catppuccin colours, install the `catppuccin-theme` Emacs package and
map the variants to `catppuccin-mocha` / `catppuccin-latte`.
Mapping from variant name (e.g. "gruvbox-dark") to the Doom
Emacs theme symbol. Defaults are auto-generated from the
configured themes (dark doom-one, light doom-one-light)
with overrides for schemes that have a dedicated doom-theme.
Only themes installed in Doom will load; others are silently
skipped.
'';
};
@@ -213,5 +261,21 @@ in {
Install.WantedBy = [ "graphical-session.target" ];
};
}
# Nushell tab-completion: declares `theme-switch`'s argument signature
# so nushell completes variant names natively (takes priority over
# carapace's generic fallback). `extraConfig` is `types.lines`, so it
# merges cleanly with the carapace completer from hm-modules/shell/nu.
(mkIf config.programs.nushell.enable {
programs.nushell.extraConfig = ''
def "nu-complete theme-variants" [] {
"${availableVariants}" | split row " "
}
extern theme-switch [
variant: string@"nu-complete theme-variants"
]
'';
})
]);
}
+2
View File
@@ -121,6 +121,8 @@
display-manager.ly.enable = true;
gaming.enable = true;
yubikey.enable = true;
};
###
+1
View File
@@ -15,5 +15,6 @@
./gitlab
./jenkins
./gaming
./yubikey
];
}
+1 -1
View File
@@ -18,7 +18,7 @@ listener {
listener {
timeout = 300 # 5min
on-timeout = loginctl lock-session # lock screen when timeout has passed
on-timeout = hyprlock # lock screen when timeout has passed
}
# listener {
+100
View File
@@ -0,0 +1,100 @@
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.dov.yubikey;
in {
options.dov.yubikey = {
enable = mkEnableOption "YubiKey integration (PAM U2F + SSH agent)";
pamControl = mkOption {
type = types.enum [ "sufficient" "required" ];
default = "sufficient";
description = ''
PAM control flag for U2F authentication.
- "sufficient": touch YubiKey OR type password (default).
Can't lock yourself out if the key is missing or not
enrolled, the normal password prompt follows.
- "required": touch YubiKey AND type password (true 2FA).
'';
};
pamServices = mkOption {
type = types.listOf types.str;
default = [ "login" "sudo" ];
description = ''
PAM services to enable U2F for. Scoped per-service rather
than globally so that e.g. sshd is not affected.
'';
};
authFile = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Central U2F authfile path. When null, uses the default
per-user location (~/.config/Yubico/u2f_keys). Set to a
nix-store path for a central, non-user-writable mapping.
Generate mappings with:
pamu2fcfg -u &lt;username&gt;
'';
};
};
config = mkIf cfg.enable (mkMerge [
{
# --- Shared infrastructure: smart card daemon + device access ---
# hardware.gpgSmartcards installs the CCID udev rules that give
# pcscd permission to open the YubiKey's smart-card USB interface.
hardware.gpgSmartcards.enable = true;
services.pcscd.enable = true;
services.udev.packages = with pkgs; [
yubikey-personalization
libfido2
];
environment.systemPackages = with pkgs; [
yubikey-manager # `ykman` CLI
pam_u2f # `pamu2fcfg` for key enrollment
libfido2 # `fido2-token` management
];
}
# --- PAM U2F: touch YubiKey for login / sudo ---
{
security.pam.u2f = {
enable = true;
control = cfg.pamControl;
settings = {
cue = true; # "Please touch the device."
interactive = true; # "Insert your U2F device, then press ENTER."
nouserok = true; # fall through to password if key not enrolled yet
} // optionalAttrs (cfg.authFile != null) {
inherit (cfg) authFile;
};
};
# Enable U2F per-service, not globally (avoids enabling for sshd).
security.pam.services = genAttrs cfg.pamServices (_: {
u2fAuth = true;
});
}
# --- SSH agent for FIDO2 (-sk) keys ---
# yubikey-agent is incompatible with YubiKey firmware 5.7.x (PIV
# management key auth changed). GPG agent's SSH emulation doesn't
# reliably handle -sk keys. Use the standard OpenSSH agent instead,
# which is the same software stack that created the key.
{
programs.gnupg.agent.enableSSHSupport = mkForce false;
programs.ssh.startAgent = true;
}
]);
}