Added agenix-rekey

This commit is contained in:
2025-12-21 00:36:01 -05:00
parent f4b3ac54ef
commit 388af355bb
13 changed files with 241 additions and 47 deletions

169
flake.lock generated
View File

@@ -23,6 +23,30 @@
"type": "github" "type": "github"
} }
}, },
"agenix-rekey": {
"inputs": {
"devshell": "devshell",
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
],
"pre-commit-hooks": "pre-commit-hooks",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1759699908,
"narHash": "sha256-kYVGY8sAfqwpNch706Fy2+/b+xbtfidhXSnzvthAhIQ=",
"owner": "oddlama",
"repo": "agenix-rekey",
"rev": "42362b12f59978aabf3ec3334834ce2f3662013d",
"type": "github"
},
"original": {
"owner": "oddlama",
"repo": "agenix-rekey",
"type": "github"
}
},
"aquamarine": { "aquamarine": {
"inputs": { "inputs": {
"hyprutils": [ "hyprutils": [
@@ -146,6 +170,27 @@
"type": "github" "type": "github"
} }
}, },
"devshell": {
"inputs": {
"nixpkgs": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"elephant": { "elephant": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -184,6 +229,22 @@
} }
}, },
"flake-compat": { "flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-compat_2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1747046372, "lastModified": 1747046372,
@@ -199,7 +260,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-compat_2": { "flake-compat_3": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1751685974, "lastModified": 1751685974,
@@ -216,6 +277,27 @@
} }
}, },
"flake-parts": { "flake-parts": {
"inputs": {
"nixpkgs-lib": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": { "inputs": {
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
@@ -233,7 +315,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_2": { "flake-parts_3": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"nur", "nur",
@@ -254,7 +336,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_3": { "flake-parts_4": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"nvf", "nvf",
@@ -275,7 +357,7 @@
"type": "github" "type": "github"
} }
}, },
"flake-parts_4": { "flake-parts_5": {
"inputs": { "inputs": {
"nixpkgs-lib": [ "nixpkgs-lib": [
"stylix", "stylix",
@@ -331,6 +413,28 @@
} }
}, },
"gitignore": { "gitignore": {
"inputs": {
"nixpkgs": [
"agenix-rekey",
"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"
}
},
"gitignore_2": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"hyprland", "hyprland",
@@ -500,7 +604,7 @@
"hyprutils": "hyprutils", "hyprutils": "hyprutils",
"hyprwayland-scanner": "hyprwayland-scanner_2", "hyprwayland-scanner": "hyprwayland-scanner_2",
"nixpkgs": "nixpkgs_2", "nixpkgs": "nixpkgs_2",
"pre-commit-hooks": "pre-commit-hooks", "pre-commit-hooks": "pre-commit-hooks_2",
"systems": "systems_4", "systems": "systems_4",
"xdph": "xdph" "xdph": "xdph"
}, },
@@ -743,7 +847,7 @@
}, },
"mango": { "mango": {
"inputs": { "inputs": {
"flake-parts": "flake-parts", "flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_3", "nixpkgs": "nixpkgs_3",
"scenefx": "scenefx" "scenefx": "scenefx"
}, },
@@ -889,7 +993,7 @@
}, },
"nur": { "nur": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_3",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
] ]
@@ -935,8 +1039,8 @@
}, },
"nvf": { "nvf": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_3",
"flake-parts": "flake-parts_3", "flake-parts": "flake-parts_4",
"mnw": "mnw", "mnw": "mnw",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
@@ -984,6 +1088,29 @@
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"gitignore": "gitignore", "gitignore": "gitignore",
"nixpkgs": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735882644,
"narHash": "sha256-3FZAG+pGt3OElQjesCAWeMkQ7C/nB1oTHLRQ8ceP110=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "a5a961387e75ae44cc20f0a57ae463da5e959656",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"pre-commit-hooks_2": {
"inputs": {
"flake-compat": "flake-compat_2",
"gitignore": "gitignore_2",
"nixpkgs": [ "nixpkgs": [
"hyprland", "hyprland",
"nixpkgs" "nixpkgs"
@@ -1006,6 +1133,7 @@
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix", "agenix": "agenix",
"agenix-rekey": "agenix-rekey",
"elephant": "elephant", "elephant": "elephant",
"home-manager": "home-manager_2", "home-manager": "home-manager_2",
"hyprdynamicmonitors": "hyprdynamicmonitors", "hyprdynamicmonitors": "hyprdynamicmonitors",
@@ -1069,7 +1197,7 @@
"base16-helix": "base16-helix", "base16-helix": "base16-helix",
"base16-vim": "base16-vim", "base16-vim": "base16-vim",
"firefox-gnome-theme": "firefox-gnome-theme", "firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_4", "flake-parts": "flake-parts_5",
"gnome-shell": "gnome-shell", "gnome-shell": "gnome-shell",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
@@ -1282,6 +1410,27 @@
"type": "github" "type": "github"
} }
}, },
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"agenix-rekey",
"nixpkgs"
]
},
"locked": {
"lastModified": 1735135567,
"narHash": "sha256-8T3K5amndEavxnludPyfj3Z1IkcFdRpR23q+T0BVeZE=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "9e09d30a644c57257715902efbb3adc56c79cf28",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"walker": { "walker": {
"inputs": { "inputs": {
"elephant": [ "elephant": [

View File

@@ -21,6 +21,11 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
agenix-rekey = {
url = "github:oddlama/agenix-rekey";
inputs.nixpkgs.follows = "nixpkgs";
};
nvf = { nvf = {
url = "github:notashelf/nvf"; url = "github:notashelf/nvf";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@@ -60,7 +65,12 @@
}; };
outputs = outputs =
{ nixpkgs, ... }@inputs: {
self,
nixpkgs,
agenix-rekey,
...
}@inputs:
{ {
nixosConfigurations.vanta = nixpkgs.lib.nixosSystem { nixosConfigurations.vanta = nixpkgs.lib.nixosSystem {
system = "x86_64-linux"; system = "x86_64-linux";
@@ -68,11 +78,18 @@
inherit inputs; inherit inputs;
host = "vanta"; host = "vanta";
wallpaper = "twilight-village.png"; wallpaper = "twilight-village.png";
# Host public SSH key (e.g. /etc/ssh/ssh_host_ed25519_key.pub).
hostPubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAaDVBJdMDFL8r9NQCbaLe+DPHGhGzRv2N7+7m1/U8DP";
}; };
modules = [ modules = [
./modules/system ./modules/system
./hosts/vanta ./hosts/vanta
]; ];
}; };
agenix-rekey = agenix-rekey.configure {
userFlake = self;
nixosConfigurations = self.nixosConfigurations;
};
}; };
} }

View File

@@ -1,20 +1,42 @@
{ {
inputs, inputs,
config,
pkgs, pkgs,
lib,
host,
hostPubkey ? null,
... ...
}: }:
{ {
imports = [ imports = [
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
inputs.agenix-rekey.nixosModules.default
]; ];
environment.systemPackages = [ environment.systemPackages = [
inputs.agenix.packages.${pkgs.stdenv.hostPlatform.system}.default # CLI Tool # agenix-rekey's CLI tool replaces standard agenix's
inputs.agenix-rekey.packages.${pkgs.stdenv.hostPlatform.system}.default
]; ];
age.secrets = { age = {
tailscale-auth.file = ../../secrets/tailscale-auth.age; # Need to explicitly set identity paths because OpenSSH daemon is disabled
eclypsecloud-eclypse.file = ../../secrets/eclypsecloud-eclypse.age; # but the host keys are still generated via services.openssh.generateHostKeys = true
eclypse-password.file = ../../secrets/eclypse-password.age; identityPaths = map (key: key.path) config.services.openssh.hostKeys;
rekey = {
masterIdentities = [ "${inputs.self}/secrets/age-yubikey-identity-d9ed335b.pub" ];
storageMode = "local";
localStorageDir = ../../. + "/secrets/rekeyed/${host}";
}
# We only set the hostPubkey if one is supplied. For new hosts the pub key will not
# exist until it is generated after the first rebuild. Runtime decryption will fail
# but then the ssh host key will be generated in /etc/ssh and can be supplied
// lib.optionalAttrs (hostPubkey != null) {
inherit hostPubkey;
};
secrets = {
tailscale-auth.rekeyFile = ../../secrets/tailscale-auth.age;
eclypsecloud-eclypse.rekeyFile = ../../secrets/eclypsecloud-eclypse.age;
eclypse-password.rekeyFile = ../../secrets/eclypse-password.age;
};
}; };
} }

View File

@@ -1,4 +1,5 @@
{ {
pkgs,
... ...
}: }:
{ {
@@ -7,6 +8,10 @@
yubikey-touch-detector.enable = true; yubikey-touch-detector.enable = true;
}; };
environment.systemPackages = with pkgs; [
age-plugin-yubikey
];
services = { services = {
yubikey-agent.enable = true; yubikey-agent.enable = true;
}; };

View File

@@ -52,14 +52,10 @@
upower.enable = true; upower.enable = true;
# Enable the OpenSSH daemon. (Look into Fail2Ban in the future) # Disable SSH daemon but generate host keys anyway for secret rekeying
openssh = { openssh = {
enable = true; enable = false;
settings = { generateHostKeys = true;
PasswordAuthentication = false;
PermitRootLogin = "prohibit-password";
AllowUsers = [ "eclypse" ];
};
}; };
system76-scheduler.settings.cfsProfiles.enable = true; system76-scheduler.settings.cfsProfiles.enable = true;

View File

@@ -0,0 +1,7 @@
# Serial: 27501992, Slot: 1
# Name: agenix-rekey-alpha
# Created: Sat, 20 Dec 2025 06:01:41 +0000
# PIN policy: Once (A PIN is required once per session, if set)
# Touch policy: Always (A physical touch is required for every decryption)
# Recipient: age1yubikey1qvq48l020xg9xtt5epdpnzp3kvkm2vvc57357p58pyfq557a8q8hv84c82e
AGE-PLUGIN-YUBIKEY-14ZJ6XQVZM8KNXKCT2PKLW

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 7p4RPw HgBYYM/VqZ4KN4V4TrGmk86wPRhDgM+VaXfa3VlODRM
OdM//HvJTzB7/jw+c+6euiYz9ptUf/z22tzJSgxTD+w
-> B%P@9-grease
Zgr76aiZDhCWBdnbxoOptAfEuM1RWw1bN4rsUCec4VP0cDN856bCtaQjnWWbSTvv
YPHtmw
--- obv+bg63dTlnoke3tQdkAizcAqsYG2sUjYBZrhGZG68
(2<><04>$<24>Y@<40><>i<EFBFBD>7<EFBFBD>j<EFBFBD><02><>ar<61>7<EFBFBD>X$U<><0E>~<7E><>|<7C><>'<14><><EFBFBD>oo`<60><><EFBFBD><EFBFBD><11>DƆ{<7B>#<23>%<25><<m<>O)V<><56>2C<17><!<21>e<EFBFBD>ݺ(24<01><05><>~<7E><>

View File

@@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 7p4RPw FdmJ1odfweTU4HWPTeWuEcoIUq1V4ke28BWmlNNdNHg
9qi5QQHociRgSzZ97HifRDf+/Hh0cCZJzFsobpP1cpU
-> 4pq5-grease
yKZUs4lQM6BQgsyzMn3T1pvUt393/NvcRe7KwuTCDCU
--- N7NO5Ps2SG3SFNNnNNvYUSGgA0b5Dk7H6+x0rt6JtXA
Dl<EFBFBD>]e p<>(F0i3<<3C><><EFBFBD><EFBFBD><EFBFBD>Sm<53>E<7F>Eh<45><01><>S<EFBFBD>eX<><0F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>V$0<>Ŝ<EFBFBD><C59C><EFBFBD>c`<60><>%<25><><EFBFBD><EFBFBD><EFBFBD>Q<EFBFBD><51><EFBFBD><17>7&<26>X, <0B><>Lo<4C><6F>?QQ+<2B>~|%{<7B><><EFBFBD>-V<>%H<>):ց]Kx<4B><78>K<EFBFBD><4B>NX<4E><58>6<EFBFBD><36>ۦejO<><4F>#X<><58>

View File

@@ -1,19 +0,0 @@
# This file is NOT imported into the nix configuration, it is just for the agenix CLI
let
# System public ssh keys (/etc/ssh/)
vanta = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAaDVBJdMDFL8r9NQCbaLe+DPHGhGzRv2N7+7m1/U8DP";
in
{
# Tailscale auth key need to be up to date with a valid auth key in the tailscale
# dashboard. Single-use keys expire after a single machine connects, and even
# reusable keys expire after 90 days.
# Update tailscale-auth.age with `agenix -e tailscale-auth.age -i /path/to/private-ssh-key`
# Note: Only devices with the below public keys are allowed to edit tailscale-auth.age
"tailscale-auth.age".publicKeys = [ vanta ]; # Devices allowed to join the tailnet;
# Devices that can connect to EclypseCloud with the eclypse user.
"eclypsecloud-eclypse.age".publicKeys = [ vanta ];
# Devices that have the eclypse user
"eclypse-password.age".publicKeys = [ vanta ];
}

View File

@@ -1,6 +1,8 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 7p4RPw 7GuZj43+NoyPXf//ZLM99vossbJXOpDQSkBi3w51Wl8 -> piv-p256 2e0zWw ApoXPsP2VGfJnOt+dDk7DfssOkbM/3vkn4jwSfxD4UAj
FTMjlyml+T87LQffffY2AJL5IhTAJF2QlfFvhvZpvOs jtn4DCA/EyrTl9DW1hs84yd3RgVuDU77ggM218HiUdc
--- iONf8B3bUxXtCiv0EAv5QO0ZyhE5A6YfRbcxUr/awFg -> *E(-grease Ull1npy_ >F7 *?
<EFBFBD><0E><><EFBFBD>Tw<54><77>J`<60>~B IM+85AtRNlMrFgqk/uAG
<EFBFBD><11>;<3B>lOh<4F><68>{2<>?<3F><>P<EFBFBD><50>F>@m<>o<><6F>c<EFBFBD><1C>~X<>3<EFBFBD>@.g<0E>ھ<EFBFBD>eK<65><18>V7zphS<68><53>د6<D8AF><36>.W<><57>O@F  --- nxCTKF6R3E/qaTTgr7jZdz4ZLRE15NsJpyKHizEJnPw
<EFBFBD>><3E>"l<><6C><EFBFBD><14><>r<>sN<4E><7F>V*F<>I<7F>|<0E><>0X<30>8<EFBFBD><38>
<EFBFBD><EFBFBD> |P<><50><EFBFBD><1C>F<EFBFBD> <0C><>D<EFBFBD>\x<>Z<EFBFBD><5A>P<EFBFBD><50>]<5D>ʧ<EFBFBD>t-"n<>m<EFBFBD><6D><EFBFBD><EFBFBD><EFBFBD>&<26><>|<7C> %<25><><EFBFBD><EFBFBD><EFBFBD>