diff --git a/home/hosts/packages.nix b/home/hosts/packages.nix index 4deeafc..984df09 100644 --- a/home/hosts/packages.nix +++ b/home/hosts/packages.nix @@ -15,7 +15,6 @@ with pkgs; parallel pass ripgrep - sops tldr tree wget diff --git a/home/modules/ai-tools/opencode.nix b/home/modules/ai-tools/opencode.nix index 7366347..4706780 100644 --- a/home/modules/ai-tools/opencode.nix +++ b/home/modules/ai-tools/opencode.nix @@ -2,61 +2,51 @@ config, lib, pkgs, - lib', - osConfig ? null, - inputs ? null, ... }: let - sops = lib'.sopsAvailability config osConfig; - standalone = osConfig == null; + authReady = config.secrets.templatePath ? "opencode/auth.json"; in { - config = lib.mkIf config.ai-tools.opencode.enable ( - lib.optionalAttrs standalone { - sops = { - secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null { - opencode = [ "api-key" ]; - }; - templates."opencode/auth.json" = { - path = "${config.home.homeDirectory}/.local/share/opencode/auth.json"; - content = builtins.toJSON { - zai-coding-plan = { - type = "api"; - key = config.sops.placeholder."opencode/api-key"; - }; - }; - }; - }; - } - // { - warnings = - lib.optional (!sops.available) - "opencode is enabled, but sops templates are not available. the opencode API key will not be configured."; + config = lib.mkIf config.ai-tools.opencode.enable { + secrets.files.opencode = [ "api-key" ]; - home.packages = [ pkgs.opencode ]; - home.file.".config/opencode/opencode.json".text = builtins.toJSON { - "$schema" = "https://opencode.ai/config.json"; - permission = { - external_directory = { - "/run/secrets/" = "deny"; - "~/.config/sops/age/keys.txt" = "deny"; - "~/.ssh/id_rsa" = "deny"; - "~/.ssh/id_ed25519" = "deny"; - "~/.ssh/id_ecdsa" = "deny"; - "~/.ssh/id_dsa" = "deny"; - "/etc/ssh/ssh_host_rsa_key" = "deny"; - "/etc/ssh/ssh_host_ed25519_key" = "deny"; - "/etc/ssh/ssh_host_ecdsa_key" = "deny"; - "/etc/ssh/ssh_host_dsa_key" = "deny"; - }; - command = { - sops = "deny"; - }; + secrets.templates."opencode/auth.json" = { + path = ".local/share/opencode/auth.json"; + content = builtins.toJSON { + zai-coding-plan = { + type = "api"; + key = config.sops.placeholder."opencode/api-key"; }; - plugin = [ "@mohak34/opencode-notifier@latest" ]; }; - } - ); + }; + + warnings = + lib.optional (!authReady) + "opencode is enabled but its auth template is unavailable. the opencode API key will not be configured."; + + home.packages = [ pkgs.opencode ]; + home.file.".config/opencode/opencode.json".text = builtins.toJSON { + "$schema" = "https://opencode.ai/config.json"; + permission = { + external_directory = { + "/run/secrets/" = "deny"; + "~/.config/sops/age/keys.txt" = "deny"; + "~/.ssh/id_rsa" = "deny"; + "~/.ssh/id_ed25519" = "deny"; + "~/.ssh/id_ecdsa" = "deny"; + "~/.ssh/id_dsa" = "deny"; + "/etc/ssh/ssh_host_rsa_key" = "deny"; + "/etc/ssh/ssh_host_ed25519_key" = "deny"; + "/etc/ssh/ssh_host_ecdsa_key" = "deny"; + "/etc/ssh/ssh_host_dsa_key" = "deny"; + }; + command = { + sops = "deny"; + }; + }; + plugin = [ "@mohak34/opencode-notifier@latest" ]; + }; + }; } diff --git a/home/modules/anki/default.nix b/home/modules/anki/default.nix index a9064e8..cb90db9 100644 --- a/home/modules/anki/default.nix +++ b/home/modules/anki/default.nix @@ -2,60 +2,51 @@ config, lib, pkgs, - lib', - osConfig ? null, - inputs ? null, ... }: let cfg = config.anki; - sops = lib'.sopsAvailability config osConfig; - standalone = osConfig == null; + syncReady = config.secrets.path ? "anki/sync-user" && config.secrets.path ? "anki/sync-key"; in { options.anki.enable = lib.mkEnableOption "Anki"; - config = lib.mkIf cfg.enable ( - lib.optionalAttrs standalone { - sops.secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null { - anki = [ - "sync-user" - "sync-key" - ]; - }; - } - // { - warnings = lib.optional ( - !sops.available - ) "anki is enabled but sops secrets are not available. anki sync will not be configured."; + config = lib.mkIf cfg.enable { + secrets.files.anki = [ + "sync-user" + "sync-key" + ]; - programs.anki = { - enable = true; - package = config.nixgl.wrap pkgs.anki; - addons = with pkgs.ankiAddons; [ - (anki-connect.withConfig { - # https://git.sr.ht/~foosoft/anki-connect/tree/master/item/plugin/config.json - config = { - apiKey = null; - apiLogPath = null; - webBindAddress = "127.0.0.1"; - webBindPort = 8765; - webCorsOriginList = [ "http://localhost" ]; - ignoreOriginList = [ ]; - }; - }) - puppy-reinforcement - review-heatmap - ]; - profiles."User 1".sync = lib.mkIf sops.available { - usernameFile = "${sops.secrets."anki/sync-user".path}"; - keyFile = "${sops.secrets."anki/sync-key".path}"; - }; - }; + warnings = lib.optional ( + !syncReady + ) "anki is enabled but its secrets are unavailable. anki sync will not be configured."; - # allow Anki to write prefs - home.file."${config.xdg.dataHome}/Anki2/prefs21.db".enable = lib.mkForce false; - } - ); + programs.anki = { + enable = true; + package = config.nixgl.wrap pkgs.anki; + addons = with pkgs.ankiAddons; [ + (anki-connect.withConfig { + # https://git.sr.ht/~foosoft/anki-connect/tree/master/item/plugin/config.json + config = { + apiKey = null; + apiLogPath = null; + webBindAddress = "127.0.0.1"; + webBindPort = 8765; + webCorsOriginList = [ "http://localhost" ]; + ignoreOriginList = [ ]; + }; + }) + puppy-reinforcement + review-heatmap + ]; + profiles."User 1".sync = lib.mkIf syncReady { + usernameFile = config.secrets.path."anki/sync-user"; + keyFile = config.secrets.path."anki/sync-key"; + }; + }; + + # allow Anki to write prefs + home.file."${config.xdg.dataHome}/Anki2/prefs21.db".enable = lib.mkForce false; + }; } diff --git a/home/modules/git/default.nix b/home/modules/git/default.nix index 665dd59..f2e8829 100644 --- a/home/modules/git/default.nix +++ b/home/modules/git/default.nix @@ -1,22 +1,24 @@ { config, - inputs, lib, - lib', - osConfig ? null, ... }: let cfg = config.git; - sops = lib'.sopsAvailability config osConfig; - standalone = osConfig == null; + identities = [ + "personal" + "work" + ]; - personalEmail = sops.templates.".gitconfig.email".path; - workEmail = sops.templates.".gitconfig.work.email".path; + emailTemplate = key: ".gitconfig.${key}.email"; + emailInclude = + key: + lib.optionalAttrs (config.secrets.templatePath ? ${emailTemplate key}) { + include.path = config.secrets.templatePath.${emailTemplate key}; + }; - workSettings = { - include.path = workEmail; + workSettings = emailInclude "work" // { core.longpaths = true; user = { name = "Hektor Misplon"; @@ -47,123 +49,116 @@ in ./gitlab.nix ]; - config = lib.mkIf cfg.enable ( - lib.optionalAttrs standalone { - sops = { - secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null { - email = [ - "personal" - "work" - ]; - }; + config = lib.mkIf cfg.enable { + secrets.files.email = identities; - templates = { - ".gitconfig.email".content = '' - [user] - email = ${config.sops.placeholder."email/personal"} - ''; - ".gitconfig.work.email".content = '' - [user] - email = ${config.sops.placeholder."email/work"} - ''; - }; - }; - } - // { - warnings = lib.optional ( - !config.nvim.enable - ) "'git.enable' is enabled without 'nvim.enable' (not using 'nvimdiff')"; + secrets.templates = lib.genAttrs' identities ( + key: + lib.nameValuePair (emailTemplate key) { + content = '' + [user] + email = ${config.sops.placeholder."email/${key}"} + ''; + } + ); - xdg.configFile."git/ignore".source = ./global.gitignore; + warnings = lib.optional ( + !config.nvim.enable + ) "'git.enable' is enabled without 'nvim.enable' (not using 'nvimdiff')"; - programs.git = { - enable = true; - settings = lib.mkMerge [ - { - user = { - name = "Hektor Misplon"; - username = "hektor"; - signingKey = "AEB98353B8D72E465C4236435151AF79E723F21C"; - }; - alias = { - d = "diff"; - ds = "diff --staged"; - a = "add"; - ap = "add -p"; - c = "commit"; - cm = "commit -m"; - cam = "commit --amend"; - l = ''log --pretty=format:(%an)\ \ %h\ \ %ad\ \ %s --date=short''; - s = "status --short"; - sv = "status --verbose"; - co = "checkout"; - cob = "checkout -b"; - pullr = "pull --rebase --autostash"; - pushf = "push --force-with-lease"; - al = "!git config -l | grep alias | cut -c 7-"; - alf = "!git config -l | grep alias | cut -c 7- | fzf"; - "al-" = - ''!git config --local --unset $(git config -l | grep alias | cut --delimiter="=" --fields=1 | fzf)''; - rs = "restore --staged"; - rb = "rebase"; - rbi = "rebase -i"; - wt = "worktree"; - wtc = ''config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"''; - }; - color = { - ui = "auto"; - diff = { - meta = "yellow bold"; - commit = "green bold"; - frag = "magenta bold"; - old = "red bold"; - new = "green bold"; - whitespace = "red reverse"; - }; - "diff-highlight" = { - oldNormal = "red bold"; - oldHighlight = "red bold 52"; - newNormal = "green bold"; - newHighlight = "green bold 22"; - }; - branch = { - current = "normal bold"; - local = "normal"; - remote = "normal italic"; - }; - status = { - added = "green"; - changed = "yellow"; - untracked = "normal italic"; - }; - }; - credential.helper = "cache --timeout=3600"; - init.defaultBranch = "main"; - log = { - date = "relative"; - abbrevCommit = true; - }; - merge.conflictStyle = "diff3"; - diff.colorMoved = "zebra"; - commit.gpgSign = false; - interactive.singleKey = true; - pull.rebase = true; - rerere.enabled = true; - } - (lib.mkIf config.nvim.enable { - core.editor = "nvim"; - diff.tool = "nvimdiff"; - merge.tool = "nvimdiff"; - difftool.prompt = false; - mergetool = { - prompt = false; - keepBackup = false; - }; - }) - ]; + xdg.configFile."git/ignore".source = ./global.gitignore; - includes = [ - { path = personalEmail; } + programs.git = { + enable = true; + settings = lib.mkMerge [ + { + user = { + name = "Hektor Misplon"; + username = "hektor"; + signingKey = "AEB98353B8D72E465C4236435151AF79E723F21C"; + }; + alias = { + d = "diff"; + ds = "diff --staged"; + a = "add"; + ap = "add -p"; + c = "commit"; + cm = "commit -m"; + cam = "commit --amend"; + l = ''log --pretty=format:(%an)\ \ %h\ \ %ad\ \ %s --date=short''; + s = "status --short"; + sv = "status --verbose"; + co = "checkout"; + cob = "checkout -b"; + pullr = "pull --rebase --autostash"; + pushf = "push --force-with-lease"; + al = "!git config -l | grep alias | cut -c 7-"; + alf = "!git config -l | grep alias | cut -c 7- | fzf"; + "al-" = + ''!git config --local --unset $(git config -l | grep alias | cut --delimiter="=" --fields=1 | fzf)''; + rs = "restore --staged"; + rb = "rebase"; + rbi = "rebase -i"; + wt = "worktree"; + wtc = ''config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"''; + }; + color = { + ui = "auto"; + diff = { + meta = "yellow bold"; + commit = "green bold"; + frag = "magenta bold"; + old = "red bold"; + new = "green bold"; + whitespace = "red reverse"; + }; + "diff-highlight" = { + oldNormal = "red bold"; + oldHighlight = "red bold 52"; + newNormal = "green bold"; + newHighlight = "green bold 22"; + }; + branch = { + current = "normal bold"; + local = "normal"; + remote = "normal italic"; + }; + status = { + added = "green"; + changed = "yellow"; + untracked = "normal italic"; + }; + }; + credential.helper = "cache --timeout=3600"; + init.defaultBranch = "main"; + log = { + date = "relative"; + abbrevCommit = true; + }; + merge.conflictStyle = "diff3"; + diff.colorMoved = "zebra"; + commit.gpgSign = false; + interactive.singleKey = true; + pull.rebase = true; + rerere.enabled = true; + } + (lib.mkIf config.nvim.enable { + core.editor = "nvim"; + diff.tool = "nvimdiff"; + merge.tool = "nvimdiff"; + difftool.prompt = false; + mergetool = { + prompt = false; + keepBackup = false; + }; + }) + ]; + + includes = + lib.optional (config.secrets.templatePath ? ${emailTemplate "personal"}) { + path = config.secrets.templatePath.${emailTemplate "personal"}; + } + ++ [ { condition = "gitdir:~/work/"; contents = workSettings; @@ -175,7 +170,6 @@ in contentSuffix = "gitconfig-work"; } ]; - }; - } - ); + }; + }; } diff --git a/home/modules/secrets/default.nix b/home/modules/secrets/default.nix index 79c5e9d..2f9df6f 100644 --- a/home/modules/secrets/default.nix +++ b/home/modules/secrets/default.nix @@ -2,24 +2,94 @@ config, lib, pkgs, + inputs, + lib', + osConfig ? null, ... }: + +let + cfg = config.secrets; + sops = lib'.sopsAvailability config osConfig; + standalone = !sops.osAvailable; + + sopsDir = "${toString inputs.nix-secrets}/secrets"; +in { + imports = [ ./vault.nix ]; + options.secrets = { enable = lib.mkEnableOption "secrets"; + vault.enable = lib.mkEnableOption "vault CLI"; - vault = { - enable = lib.mkEnableOption "vault CLI"; + files = lib.mkOption { + type = lib.types.attrsOf (lib.types.listOf lib.types.str); + }; + + templates = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule { + options = { + path = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + }; + content = lib.mkOption { + type = lib.types.str; + }; + }; + } + ); + }; + + path = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + readOnly = true; + }; + + templatePath = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + readOnly = true; }; }; - imports = [ ./vault.nix ]; + config = lib.mkMerge [ + { + secrets.path = lib.optionalAttrs sops.available ( + lib.mapAttrs (_: secret: secret.path) sops.secrets + ); - config = lib.mkIf config.secrets.enable { - home.packages = with pkgs; [ - age - age-plugin-yubikey - sops - ]; - }; + secrets.templatePath = lib.optionalAttrs sops.available ( + lib.mapAttrs (_: template: template.path) sops.templates + ); + } + (lib.mkIf cfg.enable ( + lib.optionalAttrs standalone { + sops = { + secrets = lib'.mkSopsSecrets sopsDir null cfg.files; + + templates = lib.mapAttrs ( + _: t: + { + inherit (t) content; + } + // lib.optionalAttrs (t.path != null) { + path = "${config.home.homeDirectory}/${t.path}"; + } + ) cfg.templates; + }; + } + // { + home.packages = [ + pkgs.age + pkgs.age-plugin-yubikey + pkgs.sops + ]; + + warnings = lib.optional ( + !sops.available && (cfg.files != { } || cfg.templates != { }) + ) "secrets declared, but sops unavailable."; + } + )) + ]; } diff --git a/home/modules/taskwarrior/default.nix b/home/modules/taskwarrior/default.nix index 9a062ea..590453c 100644 --- a/home/modules/taskwarrior/default.nix +++ b/home/modules/taskwarrior/default.nix @@ -2,15 +2,11 @@ config, lib, pkgs, - lib', - osConfig ? null, - inputs ? null, ... }: let - sops = lib'.sopsAvailability config osConfig; - standalone = osConfig == null; + syncReady = config.secrets.templatePath ? "taskrc.d/sync"; syncHook = pkgs.writers.writePython3 "on-exit.sync.py" { flakeIgnore = [ "E501" ]; } '' # Source: @@ -61,111 +57,102 @@ in { options.taskwarrior.enable = lib.mkEnableOption "taskwarrior"; - config = lib.mkIf config.taskwarrior.enable ( - lib.optionalAttrs standalone { - sops = { - secrets = lib'.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" null { - taskwarrior = [ - "sync-server-url" - "sync-server-client-id" - "sync-encryption-secret" - ]; - }; + config = lib.mkIf config.taskwarrior.enable { + secrets.files.taskwarrior = [ + "sync-server-url" + "sync-server-client-id" + "sync-encryption-secret" + ]; - templates."taskrc.d/sync" = { - content = '' - sync.server.url=${config.sops.placeholder."taskwarrior/sync-server-url"} - sync.server.client_id=${config.sops.placeholder."taskwarrior/sync-server-client-id"} - sync.encryption_secret=${config.sops.placeholder."taskwarrior/sync-encryption-secret"} - ''; - }; + secrets.templates."taskrc.d/sync".content = '' + sync.server.url=${config.sops.placeholder."taskwarrior/sync-server-url"} + sync.server.client_id=${config.sops.placeholder."taskwarrior/sync-server-client-id"} + sync.encryption_secret=${config.sops.placeholder."taskwarrior/sync-encryption-secret"} + ''; + + warnings = + lib.optional (!syncReady) + "taskwarrior is enabled but its sync template is unavailable. taskwarrior sync will not be configured."; + + home.file = { + ".local/share/task/hooks/on-exit.sync.py".source = syncHook; + ".local/share/task/scripts/sync-and-notify.sh".source = lib.getExe syncAndNotify; + }; + + programs.taskwarrior = { + enable = true; + package = pkgs.taskwarrior3; + colorTheme = "dark-256"; + config = { + # taskrc.d/aliases + "alias.a" = "add"; + "alias.burndown" = "burndown.daily"; + "alias.e" = "modify"; + "alias.rm" = "delete"; + + # taskrc.d/colors + "color.active" = "bold white on black"; + "color.alternate" = ""; + "color.blocked" = "gray15"; + "color.blocking" = "bold"; + "color.due" = ""; + "color.due.today" = ""; + "color.overdue" = ""; + "color.scheduled" = ""; + "color.uda.priority.H" = "bold"; + "color.uda.priority.L" = ""; + "color.uda.priority.M" = ""; + "color.until" = ""; + + # taskrc.d/contexts + "context.home.read" = "project:home"; + "context.home.write" = "project:home"; + "context.studies.read" = "project:studies"; + "context.studies.write" = "project:studies"; + "context.work.read" = "tags:work"; + + # taskrc.d/reports + "report.in.columns" = "id,description"; + "report.in.description" = "Inbox (untagged)"; + "report.in.filter" = "status:pending tags.none:"; + "report.in.labels" = "ID,Description"; + "report.in.sort" = "entry+"; + "report.minimal.columns" = "id,description"; + "report.minimal.labels" = ","; + "report.next.columns" = + "id,start.age,entry.age,depends,project,tags,scheduled.countdown,due.relative,until.remaining,description"; + "report.next.filter" = "status:pending -WAITING -BLOCKED limit:page"; + "report.next.labels" = "ID,Active,Age,Deps,Project,Tag,S,Due,Until,Description"; + "report.recent.columns" = "id,description,entry"; + "report.recent.description" = "Recently added"; + "report.recent.labels" = "ID,Description,Age"; + "report.recent.sort" = "entry+"; + + # taskrc.d/udas + "uda.url.label" = "URL"; + "uda.url.type" = "string"; + + # taskrc.d/urgency + "urgency.uda.priority.L.coefficient" = "-1.0"; + "urgency.user.project.admin.coefficient" = "1.0"; + "urgency.user.project.creative.coefficient" = "0.0"; + "urgency.user.project.groceries.coefficient" = "0.5"; + "urgency.user.project.home.coefficient" = "0.2"; + "urgency.user.project.personal.coefficient" = "0.5"; + "urgency.user.project.side.coefficient" = "0.0"; + "urgency.user.project.studies.coefficient" = "1.0"; + + # misc + "news.version" = "3.5.0"; + "rc.json.array" = "on"; + "rc.verbose" = "nothing"; + "search.case.sensitive" = "no"; + "recurrence" = "off"; + "reserved.lines" = "3"; }; - } - // { - warnings = - lib.optional (!sops.available) - "taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured."; - - home.file = { - ".local/share/task/hooks/on-exit.sync.py".source = syncHook; - ".local/share/task/scripts/sync-and-notify.sh".source = lib.getExe syncAndNotify; - }; - - programs.taskwarrior = { - enable = true; - package = pkgs.taskwarrior3; - colorTheme = "dark-256"; - config = { - # taskrc.d/aliases - "alias.a" = "add"; - "alias.burndown" = "burndown.daily"; - "alias.e" = "modify"; - "alias.rm" = "delete"; - - # taskrc.d/colors - "color.active" = "bold white on black"; - "color.alternate" = ""; - "color.blocked" = "gray15"; - "color.blocking" = "bold"; - "color.due" = ""; - "color.due.today" = ""; - "color.overdue" = ""; - "color.scheduled" = ""; - "color.uda.priority.H" = "bold"; - "color.uda.priority.L" = ""; - "color.uda.priority.M" = ""; - "color.until" = ""; - - # taskrc.d/contexts - "context.home.read" = "project:home"; - "context.home.write" = "project:home"; - "context.studies.read" = "project:studies"; - "context.studies.write" = "project:studies"; - "context.work.read" = "tags:work"; - - # taskrc.d/reports - "report.in.columns" = "id,description"; - "report.in.description" = "Inbox (untagged)"; - "report.in.filter" = "status:pending tags.none:"; - "report.in.labels" = "ID,Description"; - "report.in.sort" = "entry+"; - "report.minimal.columns" = "id,description"; - "report.minimal.labels" = ","; - "report.next.columns" = - "id,start.age,entry.age,depends,project,tags,scheduled.countdown,due.relative,until.remaining,description"; - "report.next.filter" = "status:pending -WAITING -BLOCKED limit:page"; - "report.next.labels" = "ID,Active,Age,Deps,Project,Tag,S,Due,Until,Description"; - "report.recent.columns" = "id,description,entry"; - "report.recent.description" = "Recently added"; - "report.recent.labels" = "ID,Description,Age"; - "report.recent.sort" = "entry+"; - - # taskrc.d/udas - "uda.url.label" = "URL"; - "uda.url.type" = "string"; - - # taskrc.d/urgency - "urgency.uda.priority.L.coefficient" = "-1.0"; - "urgency.user.project.admin.coefficient" = "1.0"; - "urgency.user.project.creative.coefficient" = "0.0"; - "urgency.user.project.groceries.coefficient" = "0.5"; - "urgency.user.project.home.coefficient" = "0.2"; - "urgency.user.project.personal.coefficient" = "0.5"; - "urgency.user.project.side.coefficient" = "0.0"; - "urgency.user.project.studies.coefficient" = "1.0"; - - # misc - "news.version" = "3.5.0"; - "rc.json.array" = "on"; - "rc.verbose" = "nothing"; - "search.case.sensitive" = "no"; - "recurrence" = "off"; - "reserved.lines" = "3"; - }; - extraConfig = lib.optionalString sops.available '' - include ${sops.templates."taskrc.d/sync".path} - ''; - }; - } - ); + extraConfig = lib.optionalString syncReady '' + include ${config.secrets.templatePath."taskrc.d/sync"} + ''; + }; + }; } diff --git a/hosts/andromache/default.nix b/hosts/andromache/default.nix index 6ac1a5f..3de4e53 100644 --- a/hosts/andromache/default.nix +++ b/hosts/andromache/default.nix @@ -72,7 +72,7 @@ in sandboxing.enable = true; secrets = { enable = true; - nixSigningKey.enable = true; + nix = [ "signing-key" ]; }; ssh.enable = true; storage.enable = true; diff --git a/hosts/astyanax/default.nix b/hosts/astyanax/default.nix index 3525da2..ab08221 100644 --- a/hosts/astyanax/default.nix +++ b/hosts/astyanax/default.nix @@ -74,7 +74,7 @@ in wol.wakes = [ "andromache" ]; zfs.enable = true; - secrets.nixSigningKey.enable = true; + secrets.nix = [ "signing-key" ]; restic-backup.enable = true; tailscale.enable = true; desktop.ly.enable = true; diff --git a/lib/secrets.nix b/lib/secrets.nix index c382dd9..d05d257 100644 --- a/lib/secrets.nix +++ b/lib/secrets.nix @@ -28,6 +28,7 @@ in { available = osSopsAvailable || hmSopsAvailable; + osAvailable = osSopsAvailable; secrets = if osSopsAvailable then osConfig.sops.secrets else config.sops.secrets; templates = if osSopsAvailable then osConfig.sops.templates else config.sops.templates; }; diff --git a/modules/git/default.nix b/modules/git/default.nix index 67556f9..0feed7e 100644 --- a/modules/git/default.nix +++ b/modules/git/default.nix @@ -9,21 +9,15 @@ in options.git.enable = lib.mkEnableOption "git"; config = lib.mkIf cfg.enable { - sops.templates = { - ".gitconfig.email" = { + sops.templates = lib.genAttrs' [ "personal" "work" ] ( + key: + lib.nameValuePair ".gitconfig.${key}.email" { inherit owner; content = '' [user] - email = ${config.sops.placeholder."email/personal"} + email = ${config.sops.placeholder."email/${key}"} ''; - }; - ".gitconfig.work.email" = { - inherit owner; - content = '' - [user] - email = ${config.sops.placeholder."email/work"} - ''; - }; - }; + } + ); }; } diff --git a/modules/secrets/default.nix b/modules/secrets/default.nix index d6723a8..a5a7c51 100644 --- a/modules/secrets/default.nix +++ b/modules/secrets/default.nix @@ -10,15 +10,14 @@ let cfg = config.secrets; inherit (config.host) username; - inherit (cfg) sopsDir; - owner = config.users.users.${username}.name; + sopsDir = "${toString inputs.nix-secrets}/secrets"; + owner = username; system = { email = [ "personal" "work" ]; - nix = lib.optional cfg.nixSigningKey.enable "signing-key"; } // lib.filterAttrs (_: lib.isList) cfg; in @@ -33,11 +32,6 @@ in options = { enable = lib.mkEnableOption "secrets management"; - sopsDir = lib.mkOption { - type = lib.types.str; - default = "${toString inputs.nix-secrets}/secrets"; - }; - user = lib.mkOption { type = lib.types.attrsOf (lib.types.listOf lib.types.str); default = { }; @@ -48,10 +42,6 @@ in default = owner; }; - nixSigningKey = { - enable = lib.mkEnableOption "nix signing key configuration"; - }; - yubikey = { enable = lib.mkEnableOption "set up Yubikey"; }; @@ -60,11 +50,9 @@ in }; config = lib.mkIf cfg.enable { - sops = { - secrets = lib'.mkSopsSecrets sopsDir null system // lib'.mkSopsSecrets sopsDir owner cfg.user; - }; + sops.secrets = lib'.mkSopsSecrets sopsDir null system // lib'.mkSopsSecrets sopsDir owner cfg.user; - nix.settings.secret-key-files = lib.mkIf cfg.nixSigningKey.enable [ + nix.settings.secret-key-files = lib.mkIf (system ? nix) [ config.sops.secrets."nix/signing-key".path ];