diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.org | 19 | ||||
| -rw-r--r-- | flake.nix | 1 | ||||
| -rw-r--r-- | secrets/secrets.nix | 199 |
4 files changed, 91 insertions, 129 deletions
@@ -16,3 +16,4 @@ config.tf.json .terraform .terraform.lock.hcl /.envrc.local +/secrets/identity.txt @@ -59,18 +59,29 @@ nix run github:nix-community/nixos-anywhere -- --flake .#rivendell --build-on re Update records through the [[https://dash.cloudflare.com/2c659eeaf2ae9a0206c589c706b3748e/fcuny.net][console]]. * Secrets -Start by synchronizing the SSH key by running =sync-ssh-key= in the repository. Then, to create or edit a secret: +Get the identity under =secrets/identity.txt= with: #+begin_src sh cd (git rev-parse --show-toplevel)/secrets -agenix -i ~/.ssh/agenix -e users/fcuny/llm.age +age-plugin-yubikey --list --slot 1 > identity.txt #+end_src -And to rekey a secret: +To create or edit a secret: #+begin_src sh cd (git rev-parse --show-toplevel)/secrets -agenix -i ~/.ssh/agenix -r +agenix -i identity.txt -e users/fcuny/llm.age #+end_src +And to rekey the secrets: +#+begin_src sh +cd (git rev-parse --show-toplevel)/secrets +agenix -i identity.txt -r +#+end_src + +You can validate that the file is correct with: +#+begin_src sh +cd (git rev-parse --show-toplevel)/secrets +nix eval --file secrets.nix +#+end_src * Network ** Wireguard *** New host @@ -288,7 +288,6 @@ inherit (pre-commit-check) shellHook; buildInputs = pre-commit-check.enabledPackages; packages = with pkgs; [ - _1password-cli agenix.packages.${system}.default git just diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 3e0c38a..6c0b0a6 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -1,130 +1,81 @@ +# run `nix eval --file secrets.nix` to check that the file is properly generated let - hosts = { - bree = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFM4wZaYwz8kuu6lNrdrN6QOyouGQ0v1ye+Iwh1jawNi"; - mba = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDLQTIPZraE+jpMqGkh8yUhNFzRJbMarX5Mky3nETw6c"; - mbp = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINXiA49xsrOJp7wOTYeX5+9o3gly8LyN6gvJoNVQmswv"; - rivendell = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID76U5kt8DfBbuP16rMzfBTVTpjjPFKWnnheMALaCQEd"; - argonath = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHi9jHqRjpMzXlznTXi4nEtlRlFfyIzB6Ur9A+HDfFoq"; - }; - users = { - fcuny = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKdyJepi/NyO6d9eP8m48Ga/gdjB5ENHRXYM1ZqFZR8t"; - }; - age = [ + inherit (builtins) + all + any + attrValues + concatMap + elem + elemAt + filter + getFlake + hasAttr + isList + length + listToAttrs + split + ; + + flake = getFlake (toString ../.); + + last = list: elemAt list (length list - 1); + + flatten = x: if isList x then concatMap flatten x else [ x ]; + + unique = + list: + let + go = + acc: remaining: + if remaining == [ ] then + acc + else + let + head = builtins.head remaining; + tail = builtins.tail remaining; + in + if elem head acc then go acc tail else go (acc ++ [ head ]) tail; + in + go [ ] list; + + hostsWithRequiredAttrs = + requiredAttrs: hosts: filter (host: all (attr: hasAttr attr host) requiredAttrs) hosts; + + hostConfigsList = + (map (host: host.config) (attrValues flake.nixosConfigurations)) + ++ (map (host: host.config) (attrValues flake.darwinConfigurations)); + + hostsWithSecrets = hostsWithRequiredAttrs [ "publicKey" "age" ] hostConfigsList; + + toLocalSecretPath = path: last (split "/secrets/" path); + + secretsList = unique ( + flatten ( + map ( + host: map (secret: toLocalSecretPath (toString secret.file)) (attrValues host.age.secrets) + ) hostsWithSecrets + ) + ); + + getPublicKeysForSecret = + secretName: + let + hostsUsingSecret = filter ( + host: + any (secret: secretName == toLocalSecretPath (toString secret.file)) (attrValues host.age.secrets) + ) hostsWithSecrets; + in + unique (map (host: host.publicKey) hostsUsingSecret); + + fcuny = [ "age1yubikey1qv92lk8ckjm2qs900h89pz9myl3nfjnz7fc0eluppexyfgc0pfnjusaje3w" "age1yubikey1qd30fnnxd2uh9lgw0dr7nwvmn003rmzkrg87xfw67gdsf7u0lhm3kd4w8ul" "age1yubikey1qwrxced5j32ks5cc5aqffwz68yva9ukkz6tx5xm2sjn8swl2evtlsjlmsy9" - ]; in -{ - "acme-cloudflare-env.age".publicKeys = [ - users.fcuny - hosts.argonath - ] - ++ age; - - "restic-pw.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - "restic-nas-smb-config.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - # ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINE3mdcVS7+DPr7MZzIh3JsuI5t4z83j7ZAdAYxFLW4S rsync-nas - "rsync-ssh-nas.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - # this is the SSH key we use to access the remote builder. - "ssh-remote-builder.age".publicKeys = [ - users.fcuny - hosts.mba - ] - ++ age; - - "miniflux-oidc.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - "grafana-oidc.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - # generated with: - # openssl rand 64 | openssl base64 -A | tr '+/' '-_' | tr -d '=' - "authelia-storage-key.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - # generated with: - # openssl rand 64 | openssl base64 -A | tr '+/' '-_' | tr -d '=' - "authelia-jwt-key.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - # generated with: - # authelia crypto pair rsa generate - "authelia-jwks.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - "authelia-users.yaml.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - "bree/wireguard.age".publicKeys = [ - users.fcuny - hosts.bree - ] - ++ age; - - "bree/disk-passphrase.age".publicKeys = [ - users.fcuny - hosts.bree - ] - ++ age; - - "bree/disk-unlock-key.age".publicKeys = [ - users.fcuny - hosts.bree - ] - ++ age; - - "rivendell/wireguard.age".publicKeys = [ - users.fcuny - hosts.rivendell - ] - ++ age; - - "argonath/wireguard.age".publicKeys = [ - users.fcuny - hosts.argonath - ] - ++ age; - - "anthropic-api-key.age".publicKeys = [ - users.fcuny - hosts.mba - hosts.mbp - ] - ++ age; -} +listToAttrs ( + map (secretName: { + name = secretName; + value.publicKeys = fcuny ++ (getPublicKeysForSecret secretName); + }) secretsList +) |
