wip: secrets

This commit is contained in:
2026-04-11 20:48:47 +02:00
parent e2a26198f0
commit 631ad0d146
13 changed files with 172 additions and 92 deletions

View File

@@ -4,13 +4,19 @@
pkgs, pkgs,
myUtils, myUtils,
osConfig ? null, osConfig ? null,
inputs ? null,
... ...
}: }:
let let
sops = myUtils.sopsAvailability config osConfig; sops = myUtils.sopsAvailability config osConfig;
standalone = osConfig == null;
in in
{ {
sops.secrets = lib.mkIf standalone (
myUtils.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" "anki" [ "sync-user" "sync-key" ] { }
);
warnings = lib.optional ( warnings = lib.optional (
!sops.available && config.programs.anki.enable !sops.available && config.programs.anki.enable
) "anki is enabled but sops secrets are not available. anki sync will not be configured."; ) "anki is enabled but sops secrets are not available. anki sync will not be configured.";
@@ -24,8 +30,8 @@ in
review-heatmap review-heatmap
]; ];
profiles."User 1".sync = lib.mkIf sops.available { profiles."User 1".sync = lib.mkIf sops.available {
usernameFile = "${sops.secrets."anki-sync-user".path}"; usernameFile = "${sops.secrets."anki/sync-user".path}";
keyFile = "${sops.secrets."anki-sync-key".path}"; keyFile = "${sops.secrets."anki/sync-key".path}";
}; };
}; };
} }

View File

@@ -5,13 +5,31 @@
dotsPath, dotsPath,
myUtils, myUtils,
osConfig ? null, osConfig ? null,
inputs ? null,
... ...
}: }:
let let
sops = myUtils.sopsAvailability config osConfig; sops = myUtils.sopsAvailability config osConfig;
standalone = osConfig == null;
in in
{ {
sops = lib.mkIf standalone {
secrets = myUtils.mkSopsSecrets "${toString inputs.nix-secrets}/secrets" "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"}
'';
};
};
warnings = warnings =
lib.optional (!sops.available && config.programs.taskwarrior.enable) lib.optional (!sops.available && config.programs.taskwarrior.enable)
"taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured."; "taskwarrior is enabled, but sops templates are not available. taskwarrior sync will not be configured.";

View File

@@ -23,6 +23,7 @@ in
inherit lib config; inherit lib config;
device = "/dev/nvme1n1"; device = "/dev/nvme1n1";
}) })
../../modules/anki
../../modules/audio ../../modules/audio
../../modules/backups ../../modules/backups
../../modules/bluetooth ../../modules/bluetooth
@@ -31,17 +32,20 @@ in
../../modules/firewall ../../modules/firewall
../../modules/fonts ../../modules/fonts
../../modules/gaming ../../modules/gaming
../../modules/git
../../modules/hcloud ../../modules/hcloud
../../modules/keyboard ../../modules/keyboard
../../modules/localization ../../modules/localization
../../modules/networking ../../modules/networking
../../modules/nvidia ../../modules/nvidia
../../modules/ai-tools
(import ../../modules/secrets { inherit lib inputs config; }) (import ../../modules/secrets { inherit lib inputs config; })
../../modules/ssh ../../modules/ssh
../../modules/storage ../../modules/storage
../../modules/stylix ../../modules/stylix
../../modules/syncthing ../../modules/syncthing
../../modules/tailscale ../../modules/tailscale
../../modules/taskwarrior
../../modules/users ../../modules/users
../../modules/wol ../../modules/wol
../../modules/yubikey ../../modules/yubikey

View File

@@ -23,11 +23,14 @@ in
device = "/dev/nvme0n1"; device = "/dev/nvme0n1";
}) })
../../modules/desktops/niri ../../modules/desktops/niri
../../modules/anki
../../modules/audio ../../modules/audio
../../modules/backups ../../modules/backups
../../modules/bluetooth ../../modules/bluetooth
../../modules/git
../../modules/keyboard ../../modules/keyboard
../../modules/networking ../../modules/networking
../../modules/ai-tools
../../modules/users ../../modules/users
../../modules/localization ../../modules/localization
../../modules/fonts ../../modules/fonts
@@ -38,6 +41,7 @@ in
../../modules/docker ../../modules/docker
../../modules/nfc ../../modules/nfc
../../modules/firewall ../../modules/firewall
../../modules/taskwarrior
]; ];
home-manager.users.${config.host.username} = import ../../home/hosts/astyanax { home-manager.users.${config.host.username} = import ../../home/hosts/astyanax {

View File

@@ -12,20 +12,24 @@
./host.nix ./host.nix
./disk.nix ./disk.nix
../../modules/common ../../modules/common
../../modules/boot/bootloader.nix ../../modules/anki
../../modules/keyboard
../../modules/networking
../../modules/users
../../modules/audio ../../modules/audio
../../modules/localization ../../modules/boot/bootloader.nix
../../modules/x
../../modules/fonts ../../modules/fonts
../../modules/git
../../modules/keyboard
../../modules/localization
../../modules/networking
../../modules/ai-tools
../../modules/ssh ../../modules/ssh
../../modules/storage ../../modules/storage
../../modules/stylix ../../modules/stylix
(import ../../modules/secrets { (import ../../modules/secrets {
inherit lib inputs config; inherit lib inputs config;
}) })
../../modules/taskwarrior
../../modules/users
../../modules/x
]; ];
home-manager.users.${config.host.username} = import ../../home/hosts/vm { home-manager.users.${config.host.username} = import ../../home/hosts/vm {

View File

@@ -0,0 +1,24 @@
{ config, myUtils, ... }:
let
inherit (config.secrets) sopsDir username;
owner = config.users.users.${username}.name;
in
{
config.sops = {
secrets = myUtils.mkSopsSecrets sopsDir "opencode" [ "api-key" ] { inherit owner; };
templates."opencode/auth.json" = {
inherit owner;
path = "/home/${username}/.local/share/opencode/auth.json";
content = ''
{
"zai-coding-plan": {
"type": "api",
"key": "${config.sops.placeholder."opencode/api-key"}"
}
}
'';
};
};
}

11
modules/anki/default.nix Normal file
View File

@@ -0,0 +1,11 @@
{ config, myUtils, ... }:
let
inherit (config.secrets) sopsDir username;
owner = config.users.users.${username}.name;
in
{
config.sops = {
secrets = myUtils.mkSopsSecrets sopsDir "anki" [ "sync-user" "sync-key" ] { inherit owner; };
};
}

View File

@@ -1,6 +1,7 @@
{ {
lib, lib,
config, config,
myUtils,
... ...
}: }:
@@ -13,12 +14,12 @@ in
restic-backup = { restic-backup = {
repository = lib.mkOption { repository = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "b2:${config.sops.placeholder.b2-bucket-name}:${config.networking.hostName}"; default = "b2:${config.sops.placeholder."backblaze-b2/bucket-name"}:${config.networking.hostName}";
}; };
passwordFile = lib.mkOption { passwordFile = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = config.sops.secrets.restic-password.path; default = config.sops.secrets."restic/password".path;
}; };
paths = lib.mkOption { paths = lib.mkOption {
@@ -30,28 +31,18 @@ in
config = { config = {
sops = { sops = {
secrets = { secrets = lib.mkMerge [
restic-password = { (myUtils.mkSopsSecrets sopsDir "restic" [ "password" ] { })
sopsFile = "${sopsDir}/restic-password"; (myUtils.mkSopsSecrets sopsDir "backblaze-b2" [ "bucket-name" "account-id" "account-key" ] { })
}; ];
b2-bucket-name = {
sopsFile = "${sopsDir}/b2-bucket-name";
};
b2-account-id = {
sopsFile = "${sopsDir}/b2-account-id";
};
b2-account-key = {
sopsFile = "${sopsDir}/b2-account-key";
};
};
templates = { templates = {
"restic/repo-${config.networking.hostName}" = { "restic/repo-${config.networking.hostName}" = {
content = "b2:${config.sops.placeholder.b2-bucket-name}:${config.networking.hostName}"; content = "b2:${config.sops.placeholder."backblaze-b2/bucket-name"}:${config.networking.hostName}";
}; };
"restic/b2-env-${config.networking.hostName}" = { "restic/b2-env-${config.networking.hostName}" = {
content = '' content = ''
B2_ACCOUNT_ID=${config.sops.placeholder.b2-account-id} B2_ACCOUNT_ID=${config.sops.placeholder."backblaze-b2/account-id"}
B2_ACCOUNT_KEY=${config.sops.placeholder.b2-account-key} B2_ACCOUNT_KEY=${config.sops.placeholder."backblaze-b2/account-key"}
''; '';
}; };
}; };

29
modules/git/default.nix Normal file
View File

@@ -0,0 +1,29 @@
{
config,
...
}:
let
inherit (config.secrets) username;
owner = config.users.users.${username}.name;
in
{
config.sops.templates = {
".gitconfig.email" = {
inherit owner;
path = "/home/${username}/.gitconfig.email";
content = ''
[user]
email = ${config.sops.placeholder."email/personal"}
'';
};
".gitconfig.work.email" = {
inherit owner;
path = "/home/${username}/.gitconfig.work.email";
content = ''
[user]
email = ${config.sops.placeholder."email/work"}
'';
};
};
}

View File

@@ -1,6 +1,7 @@
{ {
lib, lib,
config, config,
myUtils,
... ...
}: }:
@@ -18,8 +19,7 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
sops.secrets.hcloud-token = { sops.secrets = myUtils.mkSopsSecrets sopsDir "hcloud" [ "api-token" ] {
sopsFile = "${sopsDir}/hcloud-token";
owner = config.users.users.${cfg.username}.name; owner = config.users.users.${cfg.username}.name;
}; };
@@ -31,7 +31,7 @@ in
[[contexts]] [[contexts]]
name = "server" name = "server"
token = "${config.sops.placeholder.hcloud-token}" token = "${config.sops.placeholder."hcloud/api-token"}"
''; '';
}; };
}; };

View File

@@ -2,6 +2,7 @@
lib, lib,
inputs, inputs,
config, config,
myUtils,
... ...
}: }:
@@ -9,13 +10,7 @@ let
cfg = config.secrets; cfg = config.secrets;
inherit (cfg) sopsDir; inherit (cfg) sopsDir;
owner = config.users.users.${cfg.username}.name; owner = config.users.users.${cfg.username}.name;
mkSopsSecrets = myUtils.mkSopsSecrets sopsDir;
mkSecret = name: {
${name} = {
sopsFile = "${sopsDir}/${name}";
inherit owner;
};
};
in in
{ {
imports = [ inputs.sops-nix.nixosModules.sops ]; imports = [ inputs.sops-nix.nixosModules.sops ];
@@ -46,61 +41,15 @@ in
age.keyFile = "/home/${cfg.username}/.config/sops/age/keys.txt"; age.keyFile = "/home/${cfg.username}/.config/sops/age/keys.txt";
secrets = lib.mkMerge [ secrets = lib.mkMerge [
(mkSecret "taskwarrior-sync-server-url") (mkSopsSecrets "email" [ "personal" "work" ] { inherit owner; })
(mkSecret "taskwarrior-sync-server-client-id") (lib.mkIf cfg.nixSigningKey.enable (
(mkSecret "taskwarrior-sync-encryption-secret") mkSopsSecrets cfg.nixSigningKey.name [ cfg.nixSigningKey.name ] { inherit owner; }
(mkSecret "anki-sync-user") ))
(mkSecret "anki-sync-key")
(mkSecret "email-personal")
(mkSecret "email-work")
(mkSecret "opencode-api-key")
(lib.mkIf cfg.nixSigningKey.enable (mkSecret cfg.nixSigningKey.name))
]; ];
templates = {
"taskrc.d/sync" = {
inherit owner;
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}
'';
};
".gitconfig.email" = {
inherit owner;
path = "/home/${cfg.username}/.gitconfig.email";
content = ''
[user]
email = ${config.sops.placeholder.email-personal}
'';
};
".gitconfig.work.email" = {
inherit owner;
path = "/home/${cfg.username}/.gitconfig.work.email";
content = ''
[user]
email = ${config.sops.placeholder.email-work}
'';
};
"opencode/auth.json" = {
inherit owner;
path = "/home/${cfg.username}/.local/share/opencode/auth.json";
content = ''
{
"zai-coding-plan": {
"type": "api",
"key": "${config.sops.placeholder.opencode-api-key}"
}
}
'';
};
};
}; };
nix.settings.secret-key-files = lib.mkIf cfg.nixSigningKey.enable [ nix.settings.secret-key-files = lib.mkIf cfg.nixSigningKey.enable [
config.sops.secrets.${cfg.nixSigningKey.name}.path config.sops.secrets."${cfg.nixSigningKey.name}/${cfg.nixSigningKey.name}".path
]; ];
}; };
} }

View File

@@ -0,0 +1,24 @@
{ config, myUtils, ... }:
let
inherit (config.secrets) sopsDir username;
owner = config.users.users.${username}.name;
in
{
config.sops = {
secrets = myUtils.mkSopsSecrets sopsDir "taskwarrior" [
"sync-server-url"
"sync-server-client-id"
"sync-encryption-secret"
] { inherit owner; };
templates."taskrc.d/sync" = {
inherit owner;
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"}
'';
};
};
}

View File

@@ -11,15 +11,31 @@
else else
throw "meta.nix required in ${hostDir}"; throw "meta.nix required in ${hostDir}";
mkSopsSecrets =
sopsDir: group: names: extraOpts:
let
file = "${group}.yaml";
in
lib.foldl' lib.mergeAttrs { } (
map (name: {
"${group}/${name}" = {
sopsFile = "${sopsDir}/${file}";
key = name;
}
// extraOpts;
}) names
);
sopsAvailability = sopsAvailability =
config: osConfig: config: osConfig:
let let
hmSopsAvailable = config ? sops && config.sops ? secrets;
osSopsAvailable = osConfig != null && osConfig ? sops && osConfig.sops ? secrets; osSopsAvailable = osConfig != null && osConfig ? sops && osConfig.sops ? secrets;
hmSopsAvailable = config ? sops && config.sops ? secrets;
preferOs = osSopsAvailable;
in in
{ {
available = hmSopsAvailable || osSopsAvailable; available = osSopsAvailable || hmSopsAvailable;
secrets = if hmSopsAvailable then config.sops.secrets else osConfig.sops.secrets; secrets = if preferOs then osConfig.sops.secrets else config.sops.secrets;
templates = if hmSopsAvailable then config.sops.templates else osConfig.sops.templates; templates = if preferOs then osConfig.sops.templates else config.sops.templates;
}; };
} }