Rename secrets

This commit is contained in:
Christopher Mühl 2026-01-05 12:08:42 +01:00
parent 3cce82ce03
commit 0ccb9c51b2
No known key found for this signature in database
GPG key ID: 925AC7D69955293F
37 changed files with 282 additions and 165 deletions

View file

@ -1,27 +1,19 @@
# ++ 80_Hg: Mercury
#
# Minimal environment for a workbase VirtualBox on macOS
{ {
lib, lib,
pkgs, pkgs,
inputs, inputs,
... ...
}: }: {
with lib._elements; {
imports = [ imports = [
./hardware.nix ./hardware.nix
./disko.nix ./disko.nix
]; ];
elements = { bosun = {
hostname = "mercury"; # quirks = ["avahi" "docker"];
users = ["christopher"];
quirks = ["avahi" "docker"];
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD";
}; };
};
system.stateVersion = "24.11"; system.stateVersion = "24.11";
@ -46,7 +38,7 @@ with lib._elements; {
disko.devices.disk.main.device = "/dev/sda"; disko.devices.disk.main.device = "/dev/sda";
boot.loader.grub.enable = true; boot.loader.grub.enable = true;
networking.hostName = "mercury"; networking.hostName = "aepplet";
time.timeZone = "Europe/Berlin"; time.timeZone = "Europe/Berlin";
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [

View file

@ -1,7 +1,9 @@
{ {inputs, ...}: {
disko.devices = { imports = [
disk = { inputs.disko.nixosModules.default
main = { ];
disko.devices.disk.main = {
type = "disk"; type = "disk";
content = { content = {
type = "gpt"; type = "gpt";
@ -31,6 +33,4 @@
}; };
}; };
}; };
};
};
} }

View file

@ -7,34 +7,18 @@
config, config,
inputs, inputs,
... ...
}: }: {
with lib._elements; {
imports = [ imports = [
inputs.flatpak.nixosModules.nix-flatpak inputs.flatpak.nixosModules.nix-flatpak
./hardware.nix ./hardware.nix
./disko.nix ./disko.nix
./metrics.nix ./metrics.nix
./musnix.nix
]; ];
elements = { bosun = {
hostname = "cobalt"; #quirks = ["avahi" "docker" "nix-ld"];
users = ["christopher"];
quirks = ["avahi" "docker" "nix-ld"];
wm = enabled;
secrets = {
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD"; key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPjqieS4GkYAa1WRYZpxjgYsj7VGZ9U+rTFCkX8M0umD";
needs.victoriametricsEnvFile.rekeyFile = "victoria.env.age";
};
};
# Set the default drive
disko.devices.disk.main.device = "/dev/nvme1n1";
musnix = {
enable = true;
rtcqs.enable = true;
}; };
qt = { qt = {

View file

@ -1,8 +1,13 @@
{ {inputs, ...}: {
imports = [
inputs.disko.nixosModules.disko
];
disko.devices = { disko.devices = {
disk = { disk = {
main = { main = {
type = "disk"; type = "disk";
device = "/dev/nvme1n1";
content = { content = {
type = "gpt"; type = "gpt";
partitions = { partitions = {

View file

@ -4,6 +4,8 @@
pkgs, pkgs,
... ...
}: { }: {
bosun.secrets.victoriametricsEnvFile = "victoria.env.age";
services = { services = {
telegraf = { telegraf = {
enable = true; enable = true;

View file

@ -0,0 +1,12 @@
{inputs, ...}: {
imports = [
inputs.musnix.nixosModules.default
];
musnix = {
enable = true;
rtcqs.enable = true;
};
users.users.toph.extraGroups = ["audio"];
}

View file

@ -78,8 +78,7 @@
... ...
}: { }: {
imports = [ imports = [
inputs.agenix-rekey.flakeModule inputs.agenix-rekey.flakeModules.default
inputs.disko.flakeModules.default
inputs.home-manager.flakeModules.home-manager inputs.home-manager.flakeModules.home-manager
./modules/flake ./modules/flake
]; ];

View file

@ -1,40 +0,0 @@
# All hosts automatically include this module. This also means that it is necessary for
# every host to specify the option `elements.secrets.key = "key";`.
{
config,
system,
inputs,
pkgs,
lib,
...
}:
with lib; let
cfg = config.elements.secrets;
in {
options = {
elements.secrets = {
rekeyPath = mkOption {
type = types.str;
default = config.elements.hostname;
};
key = mkOption {
type = types.str;
};
needs = mkOption {
type = types.attrsOf (types.either types.str types.attrs);
default = {};
};
};
};
config = {
environment.systemPackages = [
pkgs.age-plugin-yubikey
inputs.agenix-rekey.packages.${system}.default
];
age = lib._elements.agenixRekeyConfig inputs.self cfg;
};
}

View file

@ -3,5 +3,6 @@
./hosts.nix ./hosts.nix
./args.nix ./args.nix
./formatter.nix ./formatter.nix
./lib
]; ];
} }

View file

@ -6,15 +6,31 @@
imports = [inputs.easy-hosts.flakeModule]; imports = [inputs.easy-hosts.flakeModule];
config.easy-hosts = { config.easy-hosts = {
shared.modules = [
../generic/default.nix
];
perClass = class: {
modules = [
"${self}/modules/${class}/default.nix"
];
};
hosts = { hosts = {
endurance = {}; endurance = {
path = ../../configurations/nixos/endurance;
class = "nixos";
};
vasa = { vasa = {
arch = "aarch64"; path = ../../configurations/darwin/vasa;
class = "darwin"; class = "darwin";
}; };
aepplet = {}; aepplet = {
path = ../../configurations/nixos/aepplet;
class = "nixos";
};
}; };
}; };
} }

View file

@ -0,0 +1,11 @@
{
lib,
inputs,
...
}: {
flake.lib = lib.fixedPoints.makeExtensible (final: {
secrets = import ./secrets.nix {inherit inputs lib;};
inherit (final.secrets) mkSecret;
});
}

View file

@ -0,0 +1,10 @@
{
inputs,
lib,
...
}: let
inherit (inputs) self;
in {
mkSecret = config: {
};
}

View file

@ -0,0 +1,6 @@
{
imports = [
./profiles.nix
./secrets.nix
];
}

View file

@ -0,0 +1,10 @@
{lib, ...}: let
inherit (lib) mkEnableOption;
in {
options.bosun.profiles = {
graphical.enable = mkEnableOption "Graphical interface";
headless.enable = mkEnableOption "Headless";
workstation.enable = mkEnableOption "Workstation";
server.enable = mkEnableOption "Server";
};
}

View file

@ -0,0 +1,78 @@
{
config,
system,
inputs,
pkgs,
lib,
self,
...
}:
with lib; let
cfg = config.bosun;
in {
imports = [
inputs.agenix.nixosModules.default
inputs.agenix-rekey.nixosModules.default
# inputs.agenix.homeManagerModules.default
];
options.bosun = {
rekeyPath = mkOption {
type = types.str;
default = config.networking.hostName;
};
key = mkOption {
type = types.str;
};
secrets = mkOption {
type = types.attrsOf (types.either types.str types.attrs);
default = {};
};
};
# TODO: Make this work for both home manager and nixos
config = {
environment.systemPackages = [
pkgs.age-plugin-yubikey
inputs.agenix-rekey.packages.${system}.default
];
age = {
# general host setup
rekey = {
hostPubkey = cfg.key;
# See https://github.com/oddlama/agenix-rekey?tab=readme-ov-file#local
# for potential effects of this decision.
storageMode = "local";
localStorageDir = self + "/secrets/rekeyed/${cfg.rekeyPath}";
# Used to decrypt stored secrets for rekeying.
masterIdentities = [
(self + "/secrets/keys/master-identity.pub")
];
# Keys that will always be encrypted for. These act as backup keys in
# case the master identities are somehow lost.
extraEncryptionPubkeys = [
"age1zd8wxnmgf04qcan9cvs0736valy8407f497fw9j0auwf072yadzqqdqsj9"
];
};
# map all simplified secrets from `config.bosun.secrets` to their
# respective `config.age.secrets` mapping
secrets =
lib.attrsets.mapAttrs (
name: secret: (
if builtins.isString secret
then {rekeyFile = self + "/secrets/${secret}";}
else secret // {rekeyFile = self + "/secrets/${secret.rekeyFile}";}
)
)
cfg.secrets;
};
};
}

5
modules/home/default.nix Normal file
View file

@ -0,0 +1,5 @@
{
imports = [
./secrets.nix
];
}

37
modules/home/secrets.nix Normal file
View file

@ -0,0 +1,37 @@
{
inputs,
lib,
config,
...
}:
with lib; let
cfg = config.bosun;
in {
imports = [
inputs.agenix.homeManagerModules.default
# inputs.agenix-rekey.homeManagerModules.default
];
options.bosun = {
rekeyPath = mkOption {
type = types.str;
};
key = mkOption {
type = types.str;
};
secrets = mkOption {
type = types.attrsOf (types.either types.str types.attrs);
default = {};
};
};
config.age =
(lib.bosun.mkAgenixConfig inputs.self cfg)
// {
identityPaths = ["${config.home.homeDirectory}/.ssh/key"];
secretsDir = "${config.home.homeDirectory}/.local/share/agenix/agenix";
secretsMountPoint = "${config.home.homeDirectory}/.local/share/agenix/agenix.d";
};
}

View file

@ -1,40 +0,0 @@
{
pkgs,
inputs,
lib,
config,
...
}:
with lib; let
cfg = config.elements.secrets;
in {
imports = [
inputs.agenix.homeManagerModules.default
inputs.agenix-rekey.homeManagerModules.default
];
options = {
elements.secrets = {
rekeyPath = mkOption {
type = types.str;
};
key = mkOption {
type = types.str;
};
needs = mkOption {
type = types.attrsOf (types.either types.str types.attrs);
default = {};
};
};
};
config.age =
(lib._elements.agenixRekeyConfig inputs.self cfg)
// {
identityPaths = ["${config.home.homeDirectory}/.ssh/key"];
secretsDir = "${config.home.homeDirectory}/.local/share/agenix/agenix";
secretsMountPoint = "${config.home.homeDirectory}/.local/share/agenix/agenix.d";
};
}

View file

@ -1,6 +0,0 @@
{...}: {
imports = [
./core
./core/users.nix
];
}

View file

@ -0,0 +1,7 @@
{
imports = [
./services
./system.nix
./users.nix
];
}

View file

@ -18,18 +18,17 @@ in
}; };
}; };
config = let config = {
mkIfUser = name: mkIf (elem name cfg.users); bosun.secrets.tophPassword = "toph-password.age";
#secretFor = name: file: mkIfUser name {rekeyFile = ./../../../.. + "/secrets/${file}";};
in {
# age.secrets.christopher-password = secretFor "christopher" "christopher-password.age";
programs.fish.enable = true; programs.fish.enable = true;
users = { users = {
users.christopher = mkIfUser "christopher" { users.toph = {
isNormalUser = true; isNormalUser = true;
# passwordFile = config.age.secrets.christopher-password.path; passwordFile = config.age.secrets.tophPassword.path;
shell = pkgs.fish; shell = pkgs.fish;
extraGroups = [ extraGroups = [
"wheel" "wheel"
"docker" "docker"
@ -37,13 +36,14 @@ in
"uinput" "uinput"
"pico" "pico"
]; ];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBEqcR3f71g7yuxQtUewrqdoEh8jDHtkB1973GF0EQ6q christopher@all" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBEqcR3f71g7yuxQtUewrqdoEh8jDHtkB1973GF0EQ6q christopher@all"
]; ];
}; };
groups.christopher = { groups.toph = {
members = ["christopher"]; members = ["toph"];
gid = 1000; gid = 1000;
}; };
}; };

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 /u/eYA a2YtLIFiK8lETFr+I/Yixme90wgJX/X+kW2KpCFWGiM
xm/9eER61LCPTiRUi24Qh3gQq1OV8s9BQjgxRJfLvKs
-> vEX:@rY-grease #.ah Wz?~ Gr|K[7W -.UYxQ#
CTEhaEVZInKKSMg6Vzb54cghIPT7PbUy57qgdWwXx6lvbnnIxsqnRUwBhLK8sT3w
Sx+t1v8/cuDK
--- nzehXvl4h/fS4/3W2Rsn0Uu1E9NUsEIR6ni5qOA/U1I
®<EFBFBD>i«8<EFBFBD>üæÅKØ£„®Ù¾eÖ„™L•“ž+KV´ÉŒnC(?˜¶±C

View file

@ -0,0 +1,10 @@
age-encryption.org/v1
-> ssh-ed25519 /u/eYA uWoNFabVJzmA1L8l124lyvnvAFgsQ9rh/Okags2UrxU
vGenkj0xh5FbxTnS91XEz2qAoILYZS5skYHaadaNIBo
-> F"k"3;+O-grease (5t/PH
zBRuwDmTbpClRyVeC77vgGo4aDE2/KxWdcJK1gXvu60DxzUfyjlF3SjKLGBx4qIp
--- VxGN6ddpUyGJNbtKpOIoo7dZ3Xy1vxX1GA5f3EXef7g
‡ÿ&`j‰•¼˜×àZ<C3A0>»å=s§ Þ¯·8ôéoz´Ò<C2B4>Óçïrˆ–ÌñÎß%*}Ù÷æÇpMuœ` …ÙoK¶«œÐÁ~
l23v˰
9qxÍ—g|žòc:2.ÓN bÕÁ°i‡‡8cdJ*z#<14>°ÊYð[7ƶÇ=¿}{ó<> <0C>g <09>Y`gûçw,*\Ûr/B<>Ü[ ƒ±ðÙ&»

10
secrets/toph-password.age Normal file
View file

@ -0,0 +1,10 @@
age-encryption.org/v1
-> X25519 j/67yub+Kz8oFNN07MHKeCXXwNS0D39nkc+SqAV8UgM
89AdrCsf4LxQJBl+Q/Xr+GotScOBaP3FpgFEmEnCAQg
-> piv-p256 Kmn3OQ AjPU/LUjzP+YtoJ8yUeL1uwsA69KSeGNA3EoYcdxhhzs
a6I1KQkU49lFg/5WAxKcPWu39tUBJbbFsNYS2PFFZSA
-> 5{Mh-grease k^I'> 8jI;`F8F QO]Z. ?A?`
SDGA88nlZIKe3/d/ArbzO47BdBBf
--- bH47GyWwrNHQGcm6j2AaKnCVaxVzVPGRtBBjJb0zoW4
ÂÚ•CG0X{xB[°(s eK,9Ö:_oˆk¸öô·V+ãhá*