Commit 42810db
Changed files (34)
.helix
modules
hosts
roles
users
secrets
cache
hyacine
kevin
mobius
.helix/ignore
@@ -0,0 +1,1 @@
+/secrets/*
modules/core/nix/github-access-token.age
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> piv-p256 xCEwtQ A1uhE2zs8HRDwPmI6gfYiP80g5R0S3Iv3eXfpz4fhiRx
+fLB+VCjrZYZJNuo+t7VASqz8Vu7Nieg/oBDQ43c2+xU
+-> `LLrn-grease
+YtsqFt2Szrl5YK+6m2Lobmqamnn4QPtlQXYNK1l+78LQ3hTpZ3k
+--- 20FRUaR7JsqwU0z4OTDVg+7fa+2PRPYLmd8aXk3NcDk
+����K[ڶ�q�O3M��g{REu���������Cs�+w27?Hd��Qn|�T¼4N��p{f�R�0E_��TT��
+4��.��'��˽�q�������̄a���1;�ր�6�yw$L�w`��
\ No newline at end of file
modules/core/nix/tokens.nix
@@ -0,0 +1,18 @@
+{
+ den.aspects.core.nix.tokens = {
+ nixos = {config, ...}: {
+ nix.extraOptions = ''
+ !include ${config.vaultix.templates.nix-access-tokens.path}
+ '';
+
+ vaultix.secrets.github-access-token.file = ./github-access-token.age;
+ vaultix.templates.nix-access-tokens = {
+ content = ''
+ access-tokens = github.com=${config.vaultix.placeholder.github-access-token}
+ '';
+ mode = "0440";
+ group = "wheel";
+ };
+ };
+ };
+}
modules/hosts/hyacine/default.nix
@@ -8,6 +8,8 @@
'';
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINy57YGTUNEbBVs1YHD6m/zhJnJKnicNEaLB5fEcJln6 root@hyacine";
+
+ rootHashedPasswordFileAged = ./hashed-password.age;
};
den.users.access.by-host.hyacine.groups = [
modules/hosts/hyacine/hashed-password.age
Binary file
modules/hosts/kevin/default.nix
@@ -7,6 +7,8 @@
with Intel Core i7-14650HX, 32GB RAM and 2TB NVMe storage.
'';
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOO9CyAqGo/WbJkncrt1a9jxS1E+hd550SC4A08I/l0/ root@kevin";
+
+ rootHashedPasswordFileAged = ./hashed-password.age;
};
den.users.access.by-host.kevin = {
modules/hosts/kevin/hashed-password.age
Binary file
modules/hosts/mobius/default.nix
@@ -8,6 +8,7 @@
'';
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKSHlIARpQYDi744NML9QmFMxOEZwShfyj/ovQh6lCt7 root@mobius";
+ rootHashedPasswordFileAged = ./hashed-password.age;
};
den.users.access.by-host.mobius.groups = [
modules/hosts/mobius/hashed-password.age
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> piv-p256 xCEwtQ AkDA3lJDmcRiTrqgNPs74WwtwBdjnfST3kiZRqGFn4af
+utgxnKL2N/TeuM7Im9Dyd9f9zST+S9MsX+IaAEYEe8M
+-> #Ak+-grease wj` p_%xgDg MN;&
+OGQ2zAKwCikdzXMSvV6SqIDZiwoYZJf4xC+voQCJ2Dg
+--- n4+BxXEK3n9KPT5OexIkqGjT5o+SqecctiJIOe1Fnpc
+�V��x
���^2Ay���Y��QA�9s��p��Frc�'���=;#��]�X�������ɨ]�`C��/��Y��������������Gc?����g ��
���~���
\ No newline at end of file
modules/hosts/tribios/default.nix
@@ -7,6 +7,7 @@
with Rockchip RK3588S, 4GB RAM and 64GB eMMC storage.
'';
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQTx9RhZJa4WOAJyAUzlQLaFExcDv921sVsfM02vB9h root@tribios";
+ rootHashedPasswordFileAged = ./hashed-password.age;
};
den.users.access.by-host.tribios.groups = [
modules/hosts/tribios/hashed-password.age
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> piv-p256 xCEwtQ A/VgRdjiaPIxIjdTCYq7iNm/VSkySXnHvKvbpHYJTxQp
+G4n0yFMno/FUFfRQIUmLjTaBuB1jwVz2pK2EIY/UpY0
+-> +HGW~!I$-grease SN
+yvoWuedn6CdyaGhdkjm/lrcFLGZcV4gH2xKYT1uiKD+NfeXNXPKoFKXZpdPNPBYD
+ra9VDSlVgMuBss/h5Fnke2SpIEE8jcVpjT3Tj7eczAzF
+--- 4ZrMVAiVrZDI880IPPAbswMf91JF2tFIxQWCPG4Q6Wc
+�4�cWe�D�"��q�#��Xɘ��p�>H�Ȁ�eu5��U�H���ǘ,������{�Az�bso�Q�F�\����ֲn���\Xp|4�ġ�#ܭL��>$�G?
\ No newline at end of file
modules/hosts/default.nix
@@ -1,5 +1,22 @@
{den, ...}: {
den.schema.host.includes = [
den.batteries.hostname
+
+ ({host, ...}: {
+ name = "${host.name}/root/password";
+
+ nixos = {
+ config,
+ lib,
+ ...
+ }:
+ lib.optionalAttrs (host.rootHashedPasswordFileAged != null) (let
+ secretName = "hashed-password-user-root";
+ in {
+ users.users.root.hashedPasswordFile = config.vaultix.secrets.${secretName}.path;
+ vaultix.secrets.${secretName}.file = host.rootHashedPasswordFileAged;
+ vaultix.beforeUserborn = [secretName];
+ });
+ })
];
}
modules/hosts/schema.nix
@@ -96,6 +96,12 @@
type = lib.types.nullOr lib.types.str;
default = null;
};
+
+ rootHashedPasswordFileAged = lib.mkOption {
+ description = "Age encrypted hashed password file path for host root user.";
+ type = lib.types.nullOr lib.types.path;
+ default = null;
+ };
};
};
}
modules/roles/default.nix
@@ -6,6 +6,7 @@
core.nix.nh
core.nix.nixpkgs
core.nix.state-versions
+ core.nix.tokens
core.hardware.cpu.intel
core.hardware.graphic.intel
@@ -21,6 +22,8 @@
core.systemd
core.time-sync
core.utils
+
+ secrets.vaultix
];
};
}
modules/secrets/age-yubikey-identity.pub
@@ -0,0 +1,7 @@
+# Serial: 34752807, Slot: 1
+# Name: age identity for Nix configuration
+# Created: Mon, 25 May 2026 10:01:34 +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: age1yubikey1qf38em555plx705xy9x5nvdv5tuksendzwngm3n45fdkz4jcw33hjapxgmu
+AGE-PLUGIN-YUBIKEY-1YAY3YQ5ZCSSNPDGQUXFL7
modules/secrets/vaultix.nix
@@ -0,0 +1,77 @@
+{
+ den,
+ inputs,
+ config,
+ self,
+ withSystem,
+ lib,
+ ...
+}: {
+ # Use my fork version for some flake module improve
+ flake-file.inputs.vaultix = {
+ url = "github:HPCesia/vaultix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ inputs.flake-parts.follows = "flake-parts";
+ inputs.pre-commit-hooks.inputs.flake-compat.follows = "flake-compat";
+ };
+
+ imports = [(inputs.vaultix.flakeModules.default or {})];
+
+ flake.vaultix = {
+ identity = ./age-yubikey-identity.pub;
+ extraPackages = pkgs: [pkgs.age-plugin-yubikey];
+ nodes = lib.filterAttrs (_: nixos: nixos.config ? vaultix) self.nixosConfigurations;
+ };
+ den.schema.flake-parts.includes = [den.aspects.secrets.vaultix];
+
+ den.aspects.secrets._.vaultix.includes = [
+ den.aspects.secrets.vaultix.flake
+ den.aspects.secrets.vaultix.os
+ ];
+
+ den.aspects.secrets._.vaultix._.flake = {
+ devshell = {system, ...}: {
+ commands = [
+ {
+ package = config.flake.vaultix.app.${system}.edit;
+ help = "view and edit secrets managed by vaultix";
+ category = "[secret management]";
+ }
+ {
+ help = "cache secrets managed by vaultix for all hosts";
+ name = "cache-secret";
+ command = "nix run .#vaultix.app.${system}.renc";
+ category = "[secret management]";
+ }
+ ];
+ };
+ };
+
+ den.aspects.secrets._.vaultix._.os = {host, ...}: let
+ hasImpermanence = host.hasAspect den.aspects.core.impermanence;
+ persistPrefix = lib.optionalString hasImpermanence "/persist";
+ in {
+ nixos = {
+ pkgs,
+ config,
+ ...
+ } @ args: {
+ imports = [
+ (import (inputs.vaultix.outPath + "/module") (args // {inherit self;}))
+ ];
+
+ vaultix = {
+ package = withSystem host.system (
+ {inputs', ...}: inputs'.vaultix.packages.default
+ );
+ settings = {
+ hostPubkey = host.pubKey;
+ hostKeys = map (key: key // {path = persistPrefix + key.path;}) config.services.openssh.hostKeys;
+ };
+ };
+
+ services.userborn.enable = true;
+ users.mutableUsers = false;
+ };
+ };
+}
modules/users/hpcesia/default.nix
@@ -20,5 +20,8 @@
}
];
};
+ system = {
+ hashedPasswordAged = ./hashed-password.age;
+ };
};
}
modules/users/hpcesia/hashed-password.age
Binary file
modules/users/default.nix
@@ -5,5 +5,15 @@
name = "users/description";
user.description = user.identity.displayName;
})
+ ({user, ...}: {
+ name = "users/password";
+ nixos = {config, ...}: let
+ secretName = "hashed-password-user-${user.userName}";
+ in {
+ users.users.${user.userName}.hashedPasswordFile = config.vaultix.secrets.${secretName}.path;
+ vaultix.secrets.${secretName}.file = user.system.hashedPasswordAged;
+ vaultix.beforeUserborn = [secretName];
+ };
+ })
];
}
modules/users/schema.nix
@@ -50,6 +50,10 @@ in {
system = mkOption {
type = types.submodule {
options = {
+ hashedPasswordAged = mkOption {
+ type = types.path;
+ description = "Age encryped hashed password file for user";
+ };
settings = mkOption {
type = types.attrsOf (types.attrsOf types.anything);
default = {};
secrets/cache/hyacine/4083f995cfe813448d451523942c7a562d6a58d0e75c8760f88d57579cdb6335
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> ssh-ed25519 PtFVIA /USYvMesKQJ9CbQbTVmH6xZEBhLAm2L7r9cX5n7kGFg
+t5nV5mIpdCzAe4E26+1mPi+bL5/qafCGtPLJ/Q9Nik8
+-> [;yD?WV-grease !}ooK)(g UGZy c"wOFv6
+DaSSPfbp8TPHUQQyYZdOuIjuULdJQBpM
+--- DjpOjJacSE9+sMIbxex8XAu0HguLibDSIHSOemMWK4A
+T\�$7��EZ�y�lG�HDzi2��H��)���M�n�8���%S���`�fA^���������_\9�.�J�#�c�詠:�k^rSo�)�#��i��/L��t���)
\ No newline at end of file
secrets/cache/hyacine/6ccff82816241ee2c72c68160cfcf84b1f1ab5bf8413098476e276ed0c5f8819
Binary file
secrets/cache/hyacine/73d2d398df550d6bf3625792564725190abd8a5b5a0f2881e1a4372375fed947
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> ssh-ed25519 PtFVIA vDZvLNZlp0rMssg+/OPN3coEmHiRdMSJ1tVn5Yeu/G0
+ssec5l3ij3L3AeZyS/pweBnDSrMGGxkKtF+jf82/TzU
+-> $^-grease QYgTt }D?q`9W^ ,xp; E+X
+f765wJyIpkyP67EDzjeD9eUZ97q0GTG8yqYW4XIiYrdAhKpuy4QBY/08hnDO16CG
+yYq36giIuSYh7Ifm8EFTIw9/WBtuIOQggVfEjNpqSwioMtruu0CdeC2w
+--- zwydhTzExtvuXP1XoJfAozBlUVx7S0196WNgLX1oN+M
+�>x�������x3?x:���~Z;Y�Ue`>4.B�k��k1�"Đ2�Ҋ��
��%� d�5 ��Ю.eNu�"��������a��JiUxy*����x�U��M��j��
\ No newline at end of file
secrets/cache/kevin/9d9d5b63e578329ff73a1033dc0fded97e832e51a202b3a9fb69945e04bb8450
Binary file
secrets/cache/kevin/b16a6dda679e392e2ea17a79b0ab7737f807f7c267ae04bedc275c87c4ac4fd6
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> ssh-ed25519 WM7kiQ bSFrcnLyHCmFUMR5Uq88NODNeVkNNG9rPtuPfJCfpWg
+H+ALpWA/RTQ/QkiqeIWKWFQl1ELr+5ty6OPB2lMR5Rc
+-> hL8ZfCQm-grease 71R dw
+svaUn8WAOtafXERuAg/kTGbPbA
+--- A4RB9EfpxEbBL1CUbG0SCoSHsZ+Oj8Np/r1gNbwtHAw
+?d�Ϝ��'JB=�C]����_#�j��A��ks�y�楼���nӅ��>�G�TE}�R����F#c ���t^-�vTG���n�厬��T�*���W���2G�H'�B
\ No newline at end of file
secrets/cache/kevin/ed4826ab5cd420ac983c82fdd40b226007e33323907a4f54c1f32f2c16d8d086
Binary file
secrets/cache/mobius/16053f4c60da485591e51136babdf6653b9601b222cb661cc34b560652bb51bf
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> ssh-ed25519 qzANJQ 55Hdi4zPfvJgwpzM2YQsEj8HSZZ8Zq8EneYBOitnbkQ
+gZfeoPLLJgwDskY1yd1oBcFU0BLUV9eliXf5YxDluh0
+-> ~zagg-grease R /2$N5<R
+
+--- YYi6isBjwkMFdmploSGpnK7o1RGDSNlzJrbdiySRYig
+Z�6�.�?��X�,Ҥ�{
+����r���و[-63��(X.`ݎL��~�o���}����+���B�KO�������(q�(���9���#����7��O�K���v�1I�~�:k�A�iN���
\ No newline at end of file
secrets/cache/mobius/59a931cf1c9c08590b0d403381a075e33ec7e96e1c96bd6d2d5483184cc0ffd1
Binary file
secrets/cache/mobius/eb320cc75148082b697f42700a57382be3143b316cebec258bd3aadbb4757505
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> ssh-ed25519 qzANJQ 6IRccm1koe3Pva9xgZ/FJ/Mcj4lUbO8qvCnwhjyimBQ
+AJ9BfB7GdBQRbiE35dCjhk3bxWzFx3/fxH68/wwRf2Y
+-> j-_y`7-grease tr<Jcr<
+PT9Rebk2F7He5qtCbMDzdcdiU/R+73FrdViqErojVSI9Vf6AvjmEYOYGeRb5Ji2k
+WK3HFTf8mRyQjQEimqA4pViRfOQtJDJ/2Nnj0Y6YYtWoHXu4FZ1mgw
+--- TAqkGiBOq4EYxlXG9Gezn/K57yvVtlPwIDZTePzC/ys
+cSP��?kc���*���D����t��be��6'�}�j��oA
Šp��,�G�4��5�jt�Jٛm�D/��O�,aP��",]��*֬.:O����~�J_�?+)O�
\ No newline at end of file
secrets/cache/tribios/5d9514cf683942f70983700faf03771f8e94b53cc3dec5db9655b00b8e72d731
Binary file
secrets/cache/tribios/6c29bd3abf0990af816945d4650ef47dd2e34c49c3b8e4da2791c186598d5f72
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> ssh-ed25519 1YGZAA 8154svAwgoIq6ehIuyVNbvV7W7raEdOQAOfbODW78mA
+tW9zartMsmlYO7BXbLQNkkviAKtLW+fBZrYIfyEGlfs
+-> 29;j#="X-grease
+q1KqZsjnV7YuAR6YWFcTUiFrkmitR2plnPZ2dIsqov+4EnbyNTGZEHe67rBEYaOk
+tJ0J2U6l/smMI3HI8V9euFJ11w
+--- nDApoV6wfyYthfYitJqGsQNejCLI0ajQxJuvUnBTJFk
+u��Ą7���#Fv>;������$C���$�sy�봊M�qi�C^��%��&�ƃ����������ԫFd�`����2q�͊"fO䅊I`��z7KM�(�
\ No newline at end of file
secrets/cache/tribios/b87ba904d835d51840f9c2efd9b4aacb19182269adfa477826850816ee1dafe7
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> ssh-ed25519 1YGZAA ZEGxtcharu8IipjdqdojuR1ED2S62LXV8Iy2Qi4cXzs
+WPOHDzzlAXlj6MtXPULExVEMYf/foUK3ATUkR6Cc4Kg
+-> Anb,+-grease
+tUwnXII4kz/wxBVieWLrOc0d6m7TovT2eZbUY5fzfzgtNYJQojwwuwwZRChOtWZ3
+fEimvXiECQvho8/qGpT06ipijtW699CJQzIrqyE
+--- dDiK56e9r4GRjWK98/CkututbCrcxt1mpsdRpSpuJOw
+�o�|0�2+������b����$��rצ�+u�VaDž��:��Ӱ:�����Sa2�ޗ傱�(8)�z0���L�j�N��8����S�S�}���b��$
\ No newline at end of file
flake.lock
@@ -1,5 +1,36 @@
{
"nodes": {
+ "advisory-db": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1781072009,
+ "narHash": "sha256-WhB6bdXmPVmuFPRLFDz2NTdW/oAwni7lmhIXJ3YWRpQ=",
+ "owner": "rustsec",
+ "repo": "advisory-db",
+ "rev": "02c8054e58f23460910a494cc1b068752338392e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "rustsec",
+ "repo": "advisory-db",
+ "type": "github"
+ }
+ },
+ "crane": {
+ "locked": {
+ "lastModified": 1780532242,
+ "narHash": "sha256-D+BsdpxmtUwtqGoY0IXPhHgTlmqgcZKCEo1oMyn7ep0=",
+ "owner": "ipetkov",
+ "repo": "crane",
+ "rev": "59a82a1222dd3b2080b5cc52a1a2e8d5f1b77f37",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ipetkov",
+ "repo": "crane",
+ "type": "github"
+ }
+ },
"den": {
"locked": {
"lastModified": 1781621963,
@@ -103,6 +134,28 @@
"type": "github"
}
},
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "vaultix",
+ "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"
+ }
+ },
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -177,6 +230,31 @@
"type": "github"
}
},
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": [
+ "flake-compat"
+ ],
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "vaultix",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1778507602,
+ "narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "type": "github"
+ }
+ },
"root": {
"inputs": {
"den": "den",
@@ -188,7 +266,34 @@
"home-manager": "home-manager",
"impermanence": "impermanence",
"import-tree": "import-tree",
- "nixpkgs": "nixpkgs"
+ "nixpkgs": "nixpkgs",
+ "vaultix": "vaultix"
+ }
+ },
+ "vaultix": {
+ "inputs": {
+ "advisory-db": "advisory-db",
+ "crane": "crane",
+ "flake-parts": [
+ "flake-parts"
+ ],
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "pre-commit-hooks": "pre-commit-hooks"
+ },
+ "locked": {
+ "lastModified": 1782644541,
+ "narHash": "sha256-IHoXhygrRubHNVAj8EQj19pPjJuQnROMz0KwS2cM4vk=",
+ "owner": "HPCesia",
+ "repo": "vaultix",
+ "rev": "5f9e16430df813ad440bda342b8972752f3bb72f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "HPCesia",
+ "repo": "vaultix",
+ "type": "github"
}
}
},
flake.nix
@@ -34,5 +34,13 @@
};
import-tree.url = "github:denful/import-tree";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ vaultix = {
+ url = "github:HPCesia/vaultix";
+ inputs = {
+ flake-parts.follows = "flake-parts";
+ nixpkgs.follows = "nixpkgs";
+ pre-commit-hooks.inputs.flake-compat.follows = "flake-compat";
+ };
+ };
};
}