diff --git a/modules/blocks/authelia.nix b/modules/blocks/authelia.nix index d27db34..1c27dd3 100644 --- a/modules/blocks/authelia.nix +++ b/modules/blocks/authelia.nix @@ -1,7 +1,8 @@ -{ config, pkgs, lib, ... }: +{ config, options, pkgs, lib, ... }: let cfg = config.shb.authelia; + opt = options.shb.authelia; contracts = pkgs.callPackage ../contracts {}; shblib = pkgs.callPackage ../../lib {}; @@ -67,33 +68,45 @@ in description = "Secrets needed by Authelia"; type = lib.types.submodule { options = { - jwtSecretFile = lib.mkOption { - type = lib.types.path; - description = "File containing the JWT secret."; + jwtSecret = contracts.secret.mkOption { + description = "JWT secret."; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${opt.subdomain}.${opt.domain}" ]; }; - ldapAdminPasswordFile = lib.mkOption { - type = lib.types.path; - description = "File containing the LDAP admin user password."; + ldapAdminPassword = contracts.secret.mkOption { + description = "LDAP admin user password."; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${opt.subdomain}.${opt.domain}" ]; }; - sessionSecretFile = lib.mkOption { - type = lib.types.path; - description = "File containing the session secret."; + sessionSecret = contracts.secret.mkOption { + description = "Session secret."; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${opt.subdomain}.${opt.domain}" ]; }; - storageEncryptionKeyFile = lib.mkOption { - type = lib.types.path; - description = "File containing the storage encryption key."; + storageEncryptionKey = contracts.secret.mkOption { + description = "Storage encryption key."; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${opt.subdomain}.${opt.domain}" ]; }; - identityProvidersOIDCHMACSecretFile = lib.mkOption { - type = lib.types.path; - description = "File containing the identity provider OIDC HMAC secret."; + identityProvidersOIDCHMACSecret = contracts.secret.mkOption { + description = "Identity provider OIDC HMAC secret."; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${opt.subdomain}.${opt.domain}" ]; }; - identityProvidersOIDCIssuerPrivateKeyFile = lib.mkOption { - type = lib.types.path; + identityProvidersOIDCIssuerPrivateKey = contracts.secret.mkOption { description = '' - File containing the identity provider OIDC issuer private key. + Identity provider OIDC issuer private key. Generate one with `nix run nixpkgs#openssl -- genrsa -out keypair.pem 2048` ''; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${opt.subdomain}.${opt.domain}" ]; }; }; }; @@ -207,9 +220,11 @@ in type = lib.types.str; description = "Username to connect to the SMTP host."; }; - passwordFile = lib.mkOption { - type = lib.types.str; + password = contracts.secret.mkOption { description = "File containing the password to connect to the SMTP host."; + mode = "0400"; + owner = cfg.autheliaUser; + restartUnits = [ "authelia-${fqdn}" ]; }; }; })) @@ -282,19 +297,20 @@ in user = cfg.autheliaUser; secrets = { - inherit (cfg.secrets) jwtSecretFile storageEncryptionKeyFile; + jwtSecretFile = cfg.secrets.jwtSecret.result.path; + storageEncryptionKeyFile = cfg.secrets.storageEncryptionKey.result.path; }; # See https://www.authelia.com/configuration/methods/secrets/ environmentVariables = { - AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = toString cfg.secrets.ldapAdminPasswordFile; - AUTHELIA_SESSION_SECRET_FILE = toString cfg.secrets.sessionSecretFile; + AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE = toString cfg.secrets.ldapAdminPassword.result.path; + AUTHELIA_SESSION_SECRET_FILE = toString cfg.secrets.sessionSecret.result.path; # Not needed since we use peer auth. # AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE = "/run/secrets/authelia/postgres_password"; - AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE = toString cfg.secrets.storageEncryptionKeyFile; - AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE = toString cfg.secrets.identityProvidersOIDCHMACSecretFile; - AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE = toString cfg.secrets.identityProvidersOIDCIssuerPrivateKeyFile; + AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE = toString cfg.secrets.storageEncryptionKey.result.path; + AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE = toString cfg.secrets.identityProvidersOIDCHMACSecret.result.path; + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE = toString cfg.secrets.identityProvidersOIDCIssuerPrivateKey.result.path; - AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = lib.mkIf (!(builtins.isString cfg.smtp)) (toString cfg.smtp.passwordFile); + AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE = lib.mkIf (!(builtins.isString cfg.smtp)) (toString cfg.smtp.password.result.path); }; settings = { server.address = "tcp://127.0.0.1:9091"; diff --git a/modules/blocks/hardcodedsecret.nix b/modules/blocks/hardcodedsecret.nix index b53136b..6e62cef 100644 --- a/modules/blocks/hardcodedsecret.nix +++ b/modules/blocks/hardcodedsecret.nix @@ -4,7 +4,7 @@ let opt = options.shb.hardcodedsecret; inherit (lib) mapAttrs' mkOption nameValuePair; - inherit (lib.types) attrsOf listOf path str submodule; + inherit (lib.types) attrsOf listOf path nullOr str submodule; inherit (pkgs) writeText; in { @@ -56,12 +56,21 @@ in }; content = mkOption { - type = str; + type = nullOr str; description = '' Content of the secret. This will be stored in the nix store and should only be used for testing or maybe in dev. ''; + default = null; + }; + + source = mkOption { + type = nullOr str; + description = '' + Source of the content of the secret. + ''; + default = null; }; }; })); @@ -70,14 +79,16 @@ in config = { system.activationScripts = mapAttrs' (n: cfg': let - content' = writeText "hardcodedsecret_${n}_content" cfg'.content; + source = if cfg'.source != null + then cfg'.source + else writeText "hardcodedsecret_${n}_content" cfg'.content; in nameValuePair "hardcodedsecret_${n}" '' mkdir -p "$(dirname "${cfg'.path}")" touch "${cfg'.path}" chmod ${cfg'.mode} "${cfg'.path}" chown ${cfg'.owner}:${cfg'.group} "${cfg'.path}" - cp ${content'} "${cfg'.path}" + cp ${source} "${cfg'.path}" '' ) cfg; }; diff --git a/test/blocks/authelia.nix b/test/blocks/authelia.nix index ec6d17f..5c523c5 100644 --- a/test/blocks/authelia.nix +++ b/test/blocks/authelia.nix @@ -13,6 +13,7 @@ in (pkgs'.path + "/nixos/modules/profiles/headless.nix") (pkgs'.path + "/nixos/modules/profiles/qemu-guest.nix") ../../modules/blocks/authelia.nix + ../../modules/blocks/hardcodedsecret.nix ../../modules/blocks/ldap.nix ../../modules/blocks/postgresql.nix ]; @@ -44,14 +45,12 @@ in ldapPort = config.shb.ldap.ldapPort; dcdomain = config.shb.ldap.dcdomain; secrets = { - jwtSecretFile = pkgs.writeText "jwtSecretFile" "jwtSecretFile"; - ldapAdminPasswordFile = pkgs.writeText "ldapAdminPasswordFile" ldapAdminPassword; - sessionSecretFile = pkgs.writeText "sessionSecretFile" "sessionSecretFile"; - storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKeyFile" "storageEncryptionKeyFile"; - identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecretFile" "identityProvidersOIDCHMACSecretFile"; - # This needs to be of the correct shape and at least 2048 bits. Generated with: - # nix run nixpkgs#openssl -- genrsa -out keypair.pem 2048 - identityProvidersOIDCIssuerPrivateKeyFile = pkgs.writeText "identityProvidersOIDCIssuerPrivateKeyFile" (builtins.readFile ./keypair.pem); + jwtSecret.result.path = config.shb.hardcodedsecret.autheliaJwtSecret.path; + ldapAdminPassword.result.path = config.shb.hardcodedsecret.ldapAdminPassword.path; + sessionSecret.result.path = config.shb.hardcodedsecret.sessionSecret.path; + storageEncryptionKey.result.path = config.shb.hardcodedsecret.storageEncryptionKey.path; + identityProvidersOIDCHMACSecret.result.path = config.shb.hardcodedsecret.identityProvidersOIDCHMACSecret.path; + identityProvidersOIDCIssuerPrivateKey.result.path = config.shb.hardcodedsecret.identityProvidersOIDCIssuerPrivateKey.path; }; oidcClients = [ @@ -73,6 +72,28 @@ in } ]; }; + + shb.hardcodedsecret.autheliaJwtSecret = config.shb.authelia.secrets.jwtSecret.request // { + content = "jwtSecret"; + }; + shb.hardcodedsecret.ldapAdminPassword = config.shb.authelia.secrets.ldapAdminPassword.request // { + content = ldapAdminPassword; + }; + shb.hardcodedsecret.sessionSecret = config.shb.authelia.secrets.sessionSecret.request // { + content = "sessionSecret"; + }; + shb.hardcodedsecret.storageEncryptionKey = config.shb.authelia.secrets.storageEncryptionKey.request // { + content = "storageEncryptionKey"; + }; + shb.hardcodedsecret.identityProvidersOIDCHMACSecret = config.shb.authelia.secrets.identityProvidersOIDCHMACSecret.request // { + content = "identityProvidersOIDCHMACSecret"; + }; + shb.hardcodedsecret.identityProvidersOIDCIssuerPrivateKey = config.shb.authelia.secrets.identityProvidersOIDCIssuerPrivateKey.request // { + source = (pkgs.runCommand "gen-private-key" {} '' + mkdir $out + ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 + '') + "/private.pem"; + }; }; testScript = { nodes, ... }: '' diff --git a/test/common.nix b/test/common.nix index 24f6ab8..8e5f2c2 100644 --- a/test/common.nix +++ b/test/common.nix @@ -185,17 +185,36 @@ in dcdomain = config.shb.ldap.dcdomain; secrets = { - jwtSecretFile = pkgs.writeText "jwtSecret" "jwtSecret"; - ldapAdminPasswordFile = pkgs.writeText "ldapUserPassword" "ldapUserPassword"; - sessionSecretFile = pkgs.writeText "sessionSecret" "sessionSecret"; - storageEncryptionKeyFile = pkgs.writeText "storageEncryptionKey" "storageEncryptionKey"; - identityProvidersOIDCHMACSecretFile = pkgs.writeText "identityProvidersOIDCHMACSecret" "identityProvidersOIDCHMACSecret"; - identityProvidersOIDCIssuerPrivateKeyFile = (pkgs.runCommand "gen-private-key" {} '' - mkdir $out - ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 - '') + "/private.pem"; + jwtSecret.result.path = config.shb.hardcodedsecret.autheliaJwtSecret.path; + ldapAdminPassword.result.path = config.shb.hardcodedsecret.ldapAdminPassword.path; + sessionSecret.result.path = config.shb.hardcodedsecret.sessionSecret.path; + storageEncryptionKey.result.path = config.shb.hardcodedsecret.storageEncryptionKey.path; + identityProvidersOIDCHMACSecret.result.path = config.shb.hardcodedsecret.identityProvidersOIDCHMACSecret.path; + identityProvidersOIDCIssuerPrivateKey.result.path = config.shb.hardcodedsecret.identityProvidersOIDCIssuerPrivateKey.path; }; }; + + shb.hardcodedsecret.autheliaJwtSecret = config.shb.authelia.secrets.jwtSecret.request // { + content = "jwtSecret"; + }; + shb.hardcodedsecret.ldapAdminPassword = config.shb.authelia.secrets.ldapAdminPassword.request // { + content = "ldapUserPassword"; + }; + shb.hardcodedsecret.sessionSecret = config.shb.authelia.secrets.sessionSecret.request // { + content = "sessionSecret"; + }; + shb.hardcodedsecret.storageEncryptionKey = config.shb.authelia.secrets.storageEncryptionKey.request // { + content = "storageEncryptionKey"; + }; + shb.hardcodedsecret.identityProvidersOIDCHMACSecret = config.shb.authelia.secrets.identityProvidersOIDCHMACSecret.request // { + content = "identityProvidersOIDCHMACSecret"; + }; + shb.hardcodedsecret.identityProvidersOIDCIssuerPrivateKey = config.shb.authelia.secrets.identityProvidersOIDCIssuerPrivateKey.request // { + source = (pkgs.runCommand "gen-private-key" {} '' + mkdir $out + ${pkgs.openssl}/bin/openssl genrsa -out $out/private.pem 4096 + '') + "/private.pem"; + }; }; }