diff --git a/README.md b/README.md index a39e27cb..60c056ca 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ These are the NixOS configurations for my systems. I run nothing other than NixO ## To-do +- [ ] Write my own Dynamic DNS updater to replace the removed Glauca one using [knsupdate][]. - [ ] Consider reworking [kittywitch/nixexprs][] and [kittywitch/nixfiles-base][]. - [x] In-housed [kittywitch/nixexprs][] as [exprs][]. - [x] Merged my local changes with [exprs][]. @@ -134,7 +135,6 @@ They are available within this repo as [exprs][]. | nixfiles/secrets | Meta + NixOS + home-manager | Helper for tf-nix’s secrets. | | nixfiles/deploy | Meta + NixOS + home-manager | tf-nix deployment integration | | nixfiles/network | Meta | Enables node to host config assignment & NixOS module. | -| nixfiles/dyndns | NixOS | Dynamic DNS using [glauca.digital][]. | | nixfiles/monitoring | NixOS | Grafana, Prometheus, Loki, node-exporter, netdata, promtail, … | | nixfiles/theme | home-manager | Abstractions for themes. SASS templating. | | hexchen/yggdrasil | NixOS | Yggdrasil ease of use module. | @@ -196,6 +196,7 @@ Please use `nix-shell` or [direnv/direnv][]. The shell is not compatible with [n [CI]: #ci [Dependencies]: #dependencies [Commands]: #commands + [knsupdate]: https://www.knot-dns.cz/docs/2.4/html/man_knsupdate.html [kittywitch/nixexprs]: https://github.com/kittywitch/nixexprs [kittywitch/nixfiles-base]: https://github.com/kittywitch/nixfiles-base [exprs]: overlays/exprs @@ -254,7 +255,6 @@ Please use `nix-shell` or [direnv/direnv][]. The shell is not compatible with [n [znc]: config/services/znc/default.nix [arcnmx/tf-nix]: https://github.com/arcnmx/tf-nix [nix-community/impermanence]: https://github.com/nix-community/impermanence - [glauca.digital]: https://glauca.digital [arcnmx/ci]: https://github.com/arcnmx/ci [6]: ci/nodes.nix [niv-cron]: ci/niv-cron.nix diff --git a/config/hosts/beltane/nixos.nix b/config/hosts/beltane/nixos.nix index 85c30e5c..c267eef8 100644 --- a/config/hosts/beltane/nixos.nix +++ b/config/hosts/beltane/nixos.nix @@ -104,7 +104,6 @@ with lib; }; network = { - dns.dynamic = true; addresses = { private = { enable = true; diff --git a/config/modules/home/secrets.nix b/config/modules/home/secrets.nix index 48e3fbd0..767023bb 100644 --- a/config/modules/home/secrets.nix +++ b/config/modules/home/secrets.nix @@ -1,10 +1,18 @@ -{ config, lib, nixos, ... }: +{ config, nixos, lib, ... }: with lib; - let secretType = types.submodule ({ name, ... }: { + options = { + path = mkOption { type = types.str; }; + field = mkOption { + type = types.str; + default = ""; + }; + }; + }); + repoSecretType = types.submodule ({ name, ... }: { options = { source = mkOption { type = types.path; @@ -14,20 +22,22 @@ let }; }; }); + cfg = config.kw.secrets; in { options.kw = { - secrets = mkOption { - type = types.nullOr (types.listOf types.str); - default = null; - }; - repoSecrets = mkOption { - type = types.nullOr (types.attrsOf secretType); - default = null; + secrets = { + variables = mkOption { + type = types.attrsOf secretType; + default = {}; + }; + repo = mkOption { + type = types.attrsOf repoSecretType; + default = {}; + }; }; }; - config = mkIf (config.kw.secrets != null) { - deploy.tf.variables = genAttrs config.kw.secrets (n: { externalSecret = true; }); - kw.repoSecrets = nixos.kw.repoSecrets; + config = { + kw.secrets.repo = nixos.kw.secrets.repo; }; } diff --git a/config/modules/meta/deploy.nix b/config/modules/meta/deploy.nix index 41039fd9..512fb956 100644 --- a/config/modules/meta/deploy.nix +++ b/config/modules/meta/deploy.nix @@ -22,7 +22,6 @@ let modules = [ tfModule "${toString sources.tf-nix}/modules" - ./secrets.nix ]; }; in diff --git a/config/modules/meta/secrets.nix b/config/modules/meta/secrets.nix deleted file mode 100644 index a3d70a23..00000000 --- a/config/modules/meta/secrets.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ config, lib, ... }: - -with lib; - -{ - options = let tf = config; in - { - variables = mkOption { - type = types.attrsOf (types.submodule ({ name, config, ... }: { - options.externalSecret = mkEnableOption "Is ths secret to be templated into a command provided?"; - config = mkIf config.externalSecret { - type = "string"; - value.shellCommand = "${tf.commandPrefix} ${tf.folderPrefix}${tf.folderDivider}${escapeShellArg name}"; - sensitive = true; - }; - })); - }; - commandPrefix = mkOption { - type = types.nullOr types.str; - default = null; - }; - folderPrefix = mkOption { - type = types.str; - default = ""; - }; - folderDivider = mkOption { - type = types.str; - default = ""; - }; - }; -} diff --git a/config/modules/nixos/default.nix b/config/modules/nixos/default.nix index 58758fcc..d85698ae 100644 --- a/config/modules/nixos/default.nix +++ b/config/modules/nixos/default.nix @@ -9,7 +9,6 @@ (import sources.anicca).modules.nixos ./deploy.nix ./monitoring.nix - ./dyndns.nix ./secrets.nix (sources.tf-nix + "/modules/nixos/secrets.nix") (sources.tf-nix + "/modules/nixos/secrets-users.nix") diff --git a/config/modules/nixos/dyndns.nix b/config/modules/nixos/dyndns.nix deleted file mode 100644 index 257d3c6b..00000000 --- a/config/modules/nixos/dyndns.nix +++ /dev/null @@ -1,55 +0,0 @@ -{ config, pkgs, lib, tf, ... }: - -with lib; - -{ - options = { - network.dns.dynamic = mkEnableOption "Enable Glauca Dynamic DNS Updater"; - }; - - config = mkIf (false) { - kw.secrets = [ - "hexdns-key" - "hexdns-secret" - "hexdns-host" - ]; - - secrets.files.kat-glauca-dns = { - text = '' - user="${tf.variables.hexdns-key.ref}" - pass="${tf.variables.hexdns-secret.ref}" - hostname="${tf.variables.hexdns-host.ref}" - ''; - }; - - systemd.services.kat-glauca-dns = - let updater = pkgs.writeShellScriptBin "glauca-dyndns" '' - #!/usr/bin/env bash - set -eu - - ip4=$(${pkgs.curl}/bin/curl -s --ipv4 https://dns.glauca.digital/checkip) - ip6=$(${pkgs.curl}/bin/curl -s --ipv6 https://dns.glauca.digital/checkip) - source $passFile - echo "$ip4, $ip6" - ${pkgs.curl}/bin/curl -u ''${user}:''${pass} --data-urlencode "hostname=''${hostname}" --data-urlencode "myip=''${ip4}" "https://dns.glauca.digital/nic/update" - echo "" - ${pkgs.curl}/bin/curl -u ''${user}:''${pass} --data-urlencode "hostname=''${hostname}" --data-urlencode "myip=''${ip6}" "https://dns.glauca.digital/nic/update" - ''; in - { - serviceConfig = { - ExecStart = "${updater}/bin/glauca-dyndns"; - }; - environment = { passFile = config.secrets.files.kat-glauca-dns.path; }; - wantedBy = [ "default.target" ]; - }; - - systemd.timers.kat-glauca-dns = { - timerConfig = { - Unit = "kat-glauca-dns.service"; - OnBootSec = "5m"; - OnUnitActiveSec = "1h"; - }; - wantedBy = [ "default.target" ]; - }; - }; -} diff --git a/config/modules/nixos/monitoring.nix b/config/modules/nixos/monitoring.nix index a540ae1f..f38e65d2 100644 --- a/config/modules/nixos/monitoring.nix +++ b/config/modules/nixos/monitoring.nix @@ -91,9 +91,12 @@ in (mkIf cfg.server.enable { network.firewall.private.tcp.ports = [ 9090 ]; - kw.secrets = [ - "grafana-admin-pass" - ]; + kw.secrets.variables = { + grafana-admin-pass = { + path = "services/grafana"; + field = "admin"; + }; + }; secrets.files.grafana-admin-pass = { text = "${tf.variables.grafana-admin-pass.ref}"; diff --git a/config/modules/nixos/secrets.nix b/config/modules/nixos/secrets.nix index e79b23cf..fafb1e48 100644 --- a/config/modules/nixos/secrets.nix +++ b/config/modules/nixos/secrets.nix @@ -4,6 +4,15 @@ with lib; let secretType = types.submodule ({ name, ... }: { + options = { + path = mkOption { type = types.str; }; + field = mkOption { + type = types.str; + default = ""; + }; + }; + }); + repoSecretType = types.submodule ({ name, ... }: { options = { source = mkOption { type = types.path; @@ -13,19 +22,36 @@ let }; }; }); + cfg = config.kw.secrets; in { options.kw = { - secrets = mkOption { - type = types.nullOr (types.listOf types.str); - default = null; - }; - repoSecrets = mkOption { - type = types.nullOr (types.attrsOf secretType); - default = null; + secrets = { + command = mkOption { + type = types.str; + }; + variables = mkOption { + type = types.attrsOf secretType; + default = {}; + }; + repo = mkOption { + type = types.attrsOf repoSecretType; + default = {}; + }; }; }; - config = mkIf (config.kw.secrets != null) { - deploy.tf.variables = genAttrs config.kw.secrets (n: { externalSecret = true; }); - }; + config = lib.mkMerge [ + { + kw.secrets.variables = lib.mkMerge (mapAttrsToList (username: user: user.kw.secrets.variables) config.home-manager.users); + } + (mkIf (cfg.variables != {}) { + deploy.tf.variables = mapAttrs' (name: content: + nameValuePair name ({ + value.shellCommand = "${cfg.command} ${content.path}" + optionalString (content.field != "") " -f ${content.field}"; + type = "string"; + sensitive = true; + }) + ) cfg.variables; + }) + ]; } diff --git a/config/profiles/base/secrets.nix b/config/profiles/base/secrets.nix index 877d1874..6118be0f 100644 --- a/config/profiles/base/secrets.nix +++ b/config/profiles/base/secrets.nix @@ -6,4 +6,8 @@ persistentRoot = "/var/lib/kat/secrets"; external = true; }; + + kw.secrets.command = let + bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.secrets.repo.bitw.source} "$@"''; + in "${bitw}/bin/bitw get"; } diff --git a/config/services/fusionpbx/default.nix b/config/services/fusionpbx/default.nix index 66801be5..47b946b3 100644 --- a/config/services/fusionpbx/default.nix +++ b/config/services/fusionpbx/default.nix @@ -1,4 +1,4 @@ -{ config, pkgs, tf, ... }: +{ config, pkgs, tf, lib, ... }: with lib; { deploy.tf.dns.records.services_fusionpbx = { @@ -7,10 +7,11 @@ cname.target = "${config.network.addresses.private.domain}."; }; - kw.secrets = [ - "fusionpbx-username" - "fusionpbx-password" - ]; + kw.secrets.variables = mapListToAttrs (field: + nameValuePair "fusionpbx-${field}" { + path = "services/fusionpbx"; + inherit field; + }) ["username" "password"]; secrets.files.fusionpbx_env = { text = '' diff --git a/config/services/gitea/default.nix b/config/services/gitea/default.nix index 50f4dba2..c903370d 100644 --- a/config/services/gitea/default.nix +++ b/config/services/gitea/default.nix @@ -1,9 +1,12 @@ { config, lib, pkgs, tf, ... }: { - kw.secrets = [ - "gitea-mail-pass" - ]; + kw.secrets.variables = { + gitea-mail-pass = { + path = "secrets/mail-kittywitch"; + field = "gitea-pass"; + }; + }; secrets.files.gitea-mail-passfile = { text = '' diff --git a/config/services/knot/default.nix b/config/services/knot/default.nix index ee8669e5..6d71ddf0 100644 --- a/config/services/knot/default.nix +++ b/config/services/knot/default.nix @@ -1,28 +1,29 @@ { config, lib, tf, pkgs, ... }: { - kw.secrets = [ "knot-dnsupdate" ]; + kw.secrets.variables = { + katdns-key = { + path = "secrets/katdns"; + field = "notes"; + }; + }; network.firewall.public = { tcp.ports = [ 53 ]; udp.ports = [ 53 ]; }; - secrets.files.knot-dnsupdate = { - text = "${tf.variables.knot-dnsupdate.ref}"; + secrets.files.katdns-keyfile = { + text = "${tf.variables.katdns-key.ref}"; owner = "knot"; group = "knot"; }; -/* environment.etc."katdns/zones/kittywit.ch.zone".text = let - dns = pkgs.dns; - in dns.lib.toString "kittywit.ch" (import ./kittywit.ch.nix { inherit dns lib; }); */ - services.knot = { enable = true; extraConfig = builtins.readFile ./knot.yaml; keyFiles = [ - config.secrets.files.knot-dnsupdate.path + config.secrets.files.katdns-keyfile.path ]; }; } diff --git a/config/services/mail/default.nix b/config/services/mail/default.nix index d075a3c8..843ceea8 100644 --- a/config/services/mail/default.nix +++ b/config/services/mail/default.nix @@ -5,11 +5,17 @@ with lib; { imports = [ sources.nixos-mailserver.outPath ]; - kw.secrets = [ - "mail-domainkey-kitty" - "mail-kat-hash" - "mail-gitea-hash" - ]; + kw.secrets.variables = (mapListToAttrs (field: + nameValuePair "mail-${field}-hash" { + path = "secrets/mail-kittywitch"; + field = "${field}-hash"; + }) ["gitea" "kat"] + // { + mail-domainkey-kitty = { + path = "secrets/mail-kittywitch"; + field = "notes"; + }; + }); deploy.tf.dns.records.services_mail_mx = { tld = config.network.dns.tld; diff --git a/config/services/matrix/default.nix b/config/services/matrix/default.nix index 6b7f1986..3ffe806f 100644 --- a/config/services/matrix/default.nix +++ b/config/services/matrix/default.nix @@ -13,13 +13,14 @@ with lib; LC_CTYPE = "C"; ''; - kw.secrets = [ - "matrix-registration" - "mautrix-telegram-api-hash" - "mautrix-telegram-api-id" - "mautrix-telegram-as-token" - "mautrix-telegram-hs-token" - ]; + kw.secrets.variables = (mapListToAttrs (field: + nameValuePair "mautrix-telegram-${field}" { + path = "secrets/mautrix-telegram"; + inherit field; + }) ["api-hash" "api-id" "as-token" "hs-token"] + // { matrix-registration = { + path = "secrets/matrix-registration"; + }; }); secrets.files.mautrix-telegram-env = { text = '' diff --git a/config/services/murmur/default.nix b/config/services/murmur/default.nix index 59ef8d14..eae88df4 100644 --- a/config/services/murmur/default.nix +++ b/config/services/murmur/default.nix @@ -14,9 +14,12 @@ in }; }; - kw.secrets = [ - "murmur-password" - ]; + kw.secrets.variables = { + murmur-password = { + path = "social/mumble"; + field = "password"; + }; + }; secrets.files.murmur-config = { text = '' diff --git a/config/services/nginx/default.nix b/config/services/nginx/default.nix index 8305bad4..178580dc 100644 --- a/config/services/nginx/default.nix +++ b/config/services/nginx/default.nix @@ -5,7 +5,7 @@ with lib; { secrets.files.dns_creds = { text = '' - RFC2136_NAMESERVER='${tf.variables.katdns-addr.ref}' + RFC2136_NAMESERVER='${tf.variables.katdns-address.ref}' RFC2136_TSIG_ALGORITHM='hmac-sha512.' RFC2136_TSIG_KEY='${tf.variables.katdns-name.ref}' RFC2136_TSIG_SECRET='${tf.variables.katdns-key.ref}' diff --git a/config/services/syncplay/default.nix b/config/services/syncplay/default.nix index 6f04c670..a0088fec 100644 --- a/config/services/syncplay/default.nix +++ b/config/services/syncplay/default.nix @@ -3,10 +3,14 @@ with lib; { - kw.secrets = [ - "syncplay-pass" - "syncplay-salt" - ]; + + kw.secrets.variables = let + fieldAdapt = field: if field == "pass" then "password" else field; + in mapListToAttrs (field: + nameValuePair "syncplay-${field}" { + path = "services/media/syncplay"; + field = fieldAdapt field; + }) ["pass" "salt"]; users.users.syncplay = { isSystemUser = true; }; diff --git a/config/services/vaultwarden/default.nix b/config/services/vaultwarden/default.nix index 4a36c2a8..1cbcb81d 100644 --- a/config/services/vaultwarden/default.nix +++ b/config/services/vaultwarden/default.nix @@ -1,7 +1,11 @@ { config, pkgs, lib, tf, ... }: { - kw.secrets = lib.singleton "vaultwarden-admin-token"; + kw.secrets.variables = { + vaultwarden-admin-token = { + path = "secrets/vaultwarden"; + }; + }; secrets.files.vaultwarden-env = { text = '' diff --git a/config/services/znc/default.nix b/config/services/znc/default.nix index 8d20d1b4..28e29a69 100644 --- a/config/services/znc/default.nix +++ b/config/services/znc/default.nix @@ -50,7 +50,25 @@ in { network.firewall.public.tcp.ports = singleton 5001; - kw.secrets = [ "znc-softnet-address" "znc-espernet-pass" "znc-liberachat-pass" "znc-savebuff-pass" "znc-espernet-cert" "znc-liberachat-cert" "znc-softnet-cert" ]; + kw.secrets.variables = let + fieldAdapt = field: if field == "cert" then "notes" else if field == "pass" then "password" else field; + in listToAttrs (concatMap (network: + map (field: + nameValuePair "znc-${network}-${field}" { + path = "social/irc/${network}"; + field = fieldAdapt field; + }) ["cert" "pass"] + ) ["liberachat" "espernet"] + ++ map (field: + nameValuePair "znc-softnet-${field}" { + path = "social/irc/softnet"; + field = fieldAdapt field; + }) ["cert" "address"] + ++ singleton (nameValuePair "znc-savebuff-pass" { + path = "social/irc/znc"; + field = "savebuff"; + }) + ); secrets.files.softnet-cert = { text = tf.variables.znc-softnet-cert.ref; @@ -141,7 +159,7 @@ in AltNick = "katrin"; AutoClearChanBuffer = false; AutoClearQueryBuffer = false; - LoadModule = [ "clientbuffer autoadd" "clientaway" "savebuff ${tf.variables.znc-savebuff-pass.ref}" ]; + LoadModule = [ "clientbuffer autoadd" "buffextras" "clientaway" "savebuff ${tf.variables.znc-savebuff-pass.ref}" ]; Network.softnet = { Server = "${tf.variables.znc-softnet-address.ref}"; Nick = "kat"; @@ -166,7 +184,7 @@ in }; }; }) - (mkIf config.deploy.profile.trusted (import config.kw.repoSecrets.znc.source)) + (mkIf config.deploy.profile.trusted (import config.kw.secrets.repo.znc.source)) ]; configFile = config.secrets.files.znc-config.path; }; diff --git a/config/targets/common/default.nix b/config/targets/common/default.nix index d72c7031..0a2da2dc 100644 --- a/config/targets/common/default.nix +++ b/config/targets/common/default.nix @@ -1,31 +1,26 @@ { config, ... }: { - commandPrefix = "pass"; - folderPrefix = "secrets"; - folderDivider = "/"; - - variables.rfc2136-key = { - externalSecret = true; - }; - variables.rfc2136-secret = { - externalSecret = true; - }; - - variables.katdns-addr = { - externalSecret = true; + variables.katdns-address = { + value.shellCommand = "bitw get secrets/katdns -f address"; + type = "string"; + sensitive = true; }; variables.katdns-name = { - externalSecret = true; + value.shellCommand = "bitw get secrets/katdns -f username"; + type = "string"; + sensitive = true; }; variables.katdns-key = { - externalSecret = true; + value.shellCommand = "bitw get secrets/katdns -f password"; + type = "string"; + sensitive = true; }; providers.katdns = { type = "dns"; inputs.update = { - server = config.variables.katdns-addr.ref; + server = config.variables.katdns-address.ref; key_name = config.variables.katdns-name.ref; key_secret = config.variables.katdns-key.ref; key_algorithm = "hmac-sha512"; @@ -33,13 +28,4 @@ }; dns.zones."kittywit.ch." = { provider = "dns.katdns"; }; - - providers.dns = { - inputs.update = { - server = "ns1.as207960.net"; - key_name = config.variables.rfc2136-key.ref; - key_secret = config.variables.rfc2136-secret.ref; - key_algorithm = "hmac-sha512"; - }; - }; } diff --git a/config/users/kat/media/syncplay.nix b/config/users/kat/media/syncplay.nix index 3a5725c6..758d0a3a 100644 --- a/config/users/kat/media/syncplay.nix +++ b/config/users/kat/media/syncplay.nix @@ -3,9 +3,12 @@ with lib; { - kw.secrets = [ - "syncplay-pass" - ]; + kw.secrets.variables = { + syncplay-pass = { + path = "services/media/syncplay"; + field = "password"; + }; + }; programs.syncplay = { enable = true; diff --git a/config/users/kat/personal/bitw.nix b/config/users/kat/personal/bitw.nix index 08e9d386..f51c388f 100644 --- a/config/users/kat/personal/bitw.nix +++ b/config/users/kat/personal/bitw.nix @@ -1,7 +1,7 @@ { config, pkgs, lib, ... }: with lib; { programs.rbw = { enable = true; - package = mkIf config.deploy.profile.trusted (pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.repoSecrets.bitw.source} "$@"''); + package = mkIf config.deploy.profile.trusted (pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.secrets.repo.bitw.source} "$@"''); settings = { email = "kat@kittywit.ch"; base_url = "https://vault.kittywit.ch"; diff --git a/config/users/kat/personal/taskwarrior.nix b/config/users/kat/personal/taskwarrior.nix index c041089a..f5471be4 100644 --- a/config/users/kat/personal/taskwarrior.nix +++ b/config/users/kat/personal/taskwarrior.nix @@ -1,7 +1,15 @@ { config, pkgs, tf, lib, ... }: +with lib; + { - kw.secrets = [ "taskwarrior-key" "taskwarrior-creds" ]; + kw.secrets.variables = let + fieldAdapt = field: if field == "key" then "notes" else field; + in mapListToAttrs (field: + nameValuePair "taskwarrior-${field}" { + path = "services/taskwarrior"; + field = fieldAdapt field; + }) ["key" "credentials"]; secrets.files = { taskw_key = { @@ -11,7 +19,7 @@ }; taskw_config = { text = '' - taskd.credentials=${tf.variables.taskwarrior-creds.ref} + taskd.credentials=${tf.variables.taskwarrior-credentials.ref} ''; owner = "kat"; group = "users"; diff --git a/config/users/kat/personal/weechat.nix b/config/users/kat/personal/weechat.nix index eaee2353..1dc2f9cf 100644 --- a/config/users/kat/personal/weechat.nix +++ b/config/users/kat/personal/weechat.nix @@ -3,7 +3,7 @@ { home.file = lib.mkIf config.deploy.profile.trusted ( let - bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.repoSecrets.bitw.source} "$@"''; + bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.secrets.repo.bitw.source} "$@"''; in { ".local/share/weechat/sec.conf".text = '' diff --git a/config/users/kat/services/weechat/default.nix b/config/users/kat/services/weechat/default.nix index 9aa01885..f2eded08 100644 --- a/config/users/kat/services/weechat/default.nix +++ b/config/users/kat/services/weechat/default.nix @@ -1,10 +1,16 @@ { config, lib, nixos, pkgs, tf, ... }: { - kw.secrets = [ - "matrix-pass" - "znc-pass" - ]; + kw.secrets.variables = { + matrix-pass = { + path = "social/matrix"; + field = "password"; + }; + znc-pass = { + path = "social/irc/znc"; + field = "password"; + }; + }; secrets.files.weechat-sec = { text = ''