diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 00000000..458d23f1 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,14 @@ +keys: + - &user_ethan age10539mc6shf02hpa8huyjktdw3nfyavxdg8pt247wwvq4xrv8h5zs8nc0k0 + - &user_et age1s2dhv789xf9jjfr9pdjsww7rf4dutl3qmavgpurlwj6l5khdkfasd4v7xn + - &host_eMac age1hqq6znfaedyrmqkqqnaafa243cus77nts3e5vunxdl5xkfm6ffgqmf70r8 + - &host_mercury age1zkx88lththygcwj07xtz54tcvy6ltavnedrpskfpzcdh9tt2ngyq9gvqv5 + +creation_rules: + - path_regex: '^.*secrets\.(json|yml)' + key_groups: + - age: + - *user_ethan + - *user_et + - *host_eMac + - *host_mercury diff --git a/Justfile b/Justfile index 87c51bc7..417ebc31 100644 --- a/Justfile +++ b/Justfile @@ -47,3 +47,16 @@ move-rc-files: sudo mv /etc/bashrc /etc/bashrc.before-nix-darwin sudo mv /etc/zshrc /etc/zshrc.before-nix-darwin sudo mv /etc/zprofile /etc/zprofile.before-nix-darwin + +edit-secret file: + EDITOR="zeditor --wait" sops {{ file }} + +update-secret-files: + find . -regextype egrep -regex '^.*secrets\.(json|yml)' -execdir sops updatekeys {} -y ';' + +generate-user-age-key: + mkdir -p ~/.config/sops/age + nix shell nixpkgs#age --command sh -c "age-keygen -o ~/.config/sops/age/keys.txt" + +host-age-key: + nix shell nixpkgs#ssh-to-age --command sh -c "sudo cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age" diff --git a/flake.lock b/flake.lock index ce641d40..ae0940d7 100644 --- a/flake.lock +++ b/flake.lock @@ -4226,6 +4226,7 @@ "nixpkgs": "nixpkgs", "nixpkgs-master": "nixpkgs-master", "pragmatapro": "pragmatapro", + "sops-nix": "sops-nix", "tilde-secrets": "tilde-secrets", "treefmt": "treefmt_5" } @@ -4264,6 +4265,26 @@ "type": "github" } }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1775682595, + "narHash": "sha256-0E9PohY/VuESLq0LR4doaH7hTag513sDDW5n5qmHd1Q=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "d2e8438d5886e92bc5e7c40c035ab6cae0c41f76", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + }, "systems": { "locked": { "lastModified": 1681028828, diff --git a/flake.nix b/flake.nix index bf17d103..f1cbb348 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,9 @@ haumea.url = "github:nix-community/haumea"; haumea.inputs.nixpkgs.follows = "nixpkgs"; + sops-nix.url = "github:Mic92/sops-nix"; + sops-nix.inputs.nixpkgs.follows = "nixpkgs"; + treefmt.url = "github:numtide/treefmt-nix"; treefmt.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/lib/src/darwin.nix b/lib/src/darwin.nix index 6a5391f1..a57ef9da 100644 --- a/lib/src/darwin.nix +++ b/lib/src/darwin.nix @@ -5,8 +5,10 @@ let l = inputs.nixpkgs.lib // builtins; - sharedModules = (l.attrValues flake.darwinModules) - ++ [ inputs.home-manager.darwinModules.home-manager ]; + sharedModules = (l.attrValues flake.darwinModules) ++ (with inputs; [ + home-manager.darwinModules.home-manager + sops-nix.darwinModules.sops + ]); specialArgs = { inherit flake inputs secrets homeConfigurations; diff --git a/lib/src/hm.nix b/lib/src/hm.nix index d759a685..8925e0b5 100644 --- a/lib/src/hm.nix +++ b/lib/src/hm.nix @@ -5,7 +5,8 @@ let l = inputs.nixpkgs.lib // builtins; - sharedModules = l.attrValues flake.homeModules; + sharedModules = l.attrValues flake.homeModules + ++ [ inputs.sops-nix.homeManagerModules.sops ]; extraSpecialArgs = { inherit flake inputs secrets; diff --git a/modules/development/shell.nix b/modules/development/shell.nix index 78129764..70b27fbb 100644 --- a/modules/development/shell.nix +++ b/modules/development/shell.nix @@ -8,11 +8,13 @@ just nh nix-output-monitor + sops inputs.home-manager.packages.${system}.default ]; shellHook = '' export FLAKE_ROOT="${lib.getExe config.flake-root.package}" + export SOPS_AGE_KEY_FILE=$HOME/.config/sops/age/keys.txt ''; }; }; diff --git a/modules/development/treefmt.nix b/modules/development/treefmt.nix index ed99ff6d..739c7afb 100644 --- a/modules/development/treefmt.nix +++ b/modules/development/treefmt.nix @@ -16,6 +16,10 @@ }; prettier.enable = true; }; + settings.formatter = { + prettier.excludes = + [ "secrets.json" "**/secrets.json" "**/secrets.yml" ]; + }; }; in { treefmt.config = treefmtConfig; diff --git a/modules/profiles/home/sops.nix b/modules/profiles/home/sops.nix new file mode 100644 index 00000000..bf923bfa --- /dev/null +++ b/modules/profiles/home/sops.nix @@ -0,0 +1,8 @@ +{ config, ... }: { + sops = { + defaultSopsFile = ../../../secrets.json; + defaultSopsFormat = "json"; + + age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt"; + }; +} diff --git a/modules/profiles/system/core/nix-config.nix b/modules/profiles/system/core/nix-config.nix deleted file mode 100644 index 49d3d5c7..00000000 --- a/modules/profiles/system/core/nix-config.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ pkgs, ... }: { - nixpkgs = { - # NOTE: This relies on all hosts having the same `system`. If a system comes along that is different, this cannot - # be set to the flake-wide `pkgs`, as it is here: https://nix-darwin.github.io/nix-darwin/manual/index.html#opt-nixpkgs.pkgs - inherit pkgs; - - flake = { - setFlakeRegistry = true; - setNixPath = true; - }; - }; - - nix.gc.automatic = true; -} diff --git a/modules/profiles/system/core/nix-config/default.nix b/modules/profiles/system/core/nix-config/default.nix new file mode 100644 index 00000000..ffedf2c4 --- /dev/null +++ b/modules/profiles/system/core/nix-config/default.nix @@ -0,0 +1,30 @@ +{ config, pkgs, ... }: { + sops = { + secrets.nix-conf-github-pat = { sopsFile = ./secrets.json; }; + + templates."nix/nix-conf-access-tokens" = { + content = '' + access-tokens = github.com=${config.sops.placeholder.nix-conf-github-pat} + ''; + mode = "0777"; + }; + }; + + nixpkgs = { + # NOTE: This relies on all hosts having the same `system`. If a system comes along that is different, this cannot + # be set to the flake-wide `pkgs`, as it is here: https://nix-darwin.github.io/nix-darwin/manual/index.html#opt-nixpkgs.pkgs + inherit pkgs; + + flake = { + setFlakeRegistry = true; + setNixPath = true; + }; + }; + + nix = { + extraOptions = + "!include ${config.sops.templates."nix/nix-conf-access-tokens".path}"; + gc.automatic = true; + }; + +} diff --git a/modules/profiles/system/core/nix-config/secrets.json b/modules/profiles/system/core/nix-config/secrets.json new file mode 100644 index 00000000..70fce03d --- /dev/null +++ b/modules/profiles/system/core/nix-config/secrets.json @@ -0,0 +1,19 @@ +{ + "nix-conf-github-pat": "ENC[AES256_GCM,data:DjbmhR4UP3R3qpM7OC+UeSb0WyO8Oylg8pwCcy7bOAr7fpJ/loUy3A==,iv:Q3gjC/T4NGimB3VrcOKsVLjKLCMBD2I6aXU3wUc6e5g=,tag:k8qLHD9Rt1ImKarbOweSMg==,type:str]", + "sops": { + "age": [ + { + "recipient": "age10539mc6shf02hpa8huyjktdw3nfyavxdg8pt247wwvq4xrv8h5zs8nc0k0", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBV1BzVHpRYWMzN2lrTmR1\nTG1CdDc5a2lMbXZxNnc5RnlhMEg0aklyUFNzCkovbElTOGhIZjNuMHFsU3ZNQWhN\nc0VNeFhST3EybGR6eDZqbnhNNUFsTmsKLS0tIGZlK0JDRG5QWWFXdnByQjdZTkti\neVNrQWFCUll2d2VFbFVEdkF1YnhEa2MK0EhU2rJSFMHJ9SUCBWxdgXXOh1gyGKDr\nY0A7DVjbhqZqPUz0DMmnrTn7um7uvxJqy+QEwd/nDUtbHgh1Ws/urQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1hqq6znfaedyrmqkqqnaafa243cus77nts3e5vunxdl5xkfm6ffgqmf70r8", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnUkN1VFJoOGJBVUszMmJL\najVnZkZ5bTRHZkJVcXlSS0toNDl2N0dIU2tJCnN5Q0MxdmVxc2s3cTY3bjgxUDBV\nY3YxNFE2YnhNSG1ZR0xDa09MbitLM2sKLS0tIHp4QmhMaEJkWFV1Y1NxSUp5WnVv\nY2tlSjBING01Yi9PeXcvQjZLSWpCUzgKwb98LBNBawqlAEGIuZzBWSh7S/4fLJV5\nVsewLWRGyePe/IbekpnYpENvVVP7oap9QSsdIdlYGyg4zycnQN1w1w==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2026-04-11T03:31:33Z", + "mac": "ENC[AES256_GCM,data:fPoY/fftAipHIGZynbTtIFlGu0s/UZvfLJSCtWDp9YV/5osA5qlY4yUm8sI3wpnNnGBtuJ2Ia2lYTnpUQX5G+pRtKtkBSRJT3c7fZ1pGqE5cqUZWpiR2n8LXLV0kYypng9/uvPEvQp7Qu9P2it1DNzhWu/Buj1w7e2enEZadtXo=,iv:GX58fuVZS5lfp70s8wA2/rrpKclTssmWuGcOKCsJqX4=,tag:IfdXnsr3BCneTyxySd3ZyQ==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.12.1" + } +} diff --git a/modules/profiles/system/core/sops.nix b/modules/profiles/system/core/sops.nix new file mode 100644 index 00000000..a9915add --- /dev/null +++ b/modules/profiles/system/core/sops.nix @@ -0,0 +1,12 @@ +{ + sops = { + defaultSopsFormat = "json"; + defaultSopsFile = ../../../../secrets.json; + + age = { + sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + keyFile = "/var/lib/sops-nix/key.txt"; + generateKey = true; + }; + }; +} diff --git a/modules/suites/home.nix b/modules/suites/home.nix index 44ca348b..8f5bc0f6 100644 --- a/modules/suites/home.nix +++ b/modules/suites/home.nix @@ -19,6 +19,7 @@ with profiles; navi paths rippkgs + sops starship tmux.default tools.common diff --git a/modules/suites/system.nix b/modules/suites/system.nix index fc097709..73d5e2f6 100644 --- a/modules/suites/system.nix +++ b/modules/suites/system.nix @@ -5,7 +5,8 @@ with profiles; { base = [ core.lix - core.nix-config + core.nix-config.default + core.sops darwin.brew darwin.common darwin.system-defaults diff --git a/users/ethan/home.nix b/users/ethan/home.nix index e756ac25..6f2e23a2 100644 --- a/users/ethan/home.nix +++ b/users/ethan/home.nix @@ -7,7 +7,7 @@ ./profiles/vscode.nix ]; - home.packages = with pkgs; [ borgbackup nixd ]; + home.packages = with pkgs; [ restic nixd ]; home = { username = "ethan";