nixos/authelia: Make secrets available to the service even if not readable by the authelia user

This commit is contained in:
Nicolas Mémeint
2026-04-27 18:08:53 +02:00
parent 160883c7c1
commit 1df2a4c729
3 changed files with 27 additions and 21 deletions

View File

@@ -142,6 +142,8 @@
- The `newuidmap` and `newgidmap` security wrappers are now installed with `cap_setuid`/`cap_setgid` file capabilities instead of the setuid-root bit, matching shadow's `--with-fcaps` install mode and other major distributions. Rootless containers (podman, docker-rootless, unprivileged user namespaces) are unaffected. The only behavioural change is that mapping host uid 0 via `/etc/subuid` (which NixOS never configures by default) additionally requires `cap_setfcap`; users who explicitly grant uid 0 in a subuid range can restore the previous behaviour with `security.wrappers.newuidmap.capabilities = lib.mkForce "cap_setuid,cap_setfcap+ep";`.
- The `authelia` module now uses systemd's `LoadCredential` to load all files defined in `secrets`. As such, these files no longer need to be readable by the authelia user and group: they can for example be set to be only readable by the root user.
- `zoneminder` has been updated to 1.38.x release. See [upstream release note](https://github.com/ZoneMinder/zoneminder/releases/tag/1.38.0). While database migration should happen automatically, it's recommended that you make a backup of the database before upgrading your system.
- The latest available version of Nextcloud is v34 (available as `pkgs.nextcloud34`). The installation logic is as follows:

View File

@@ -268,15 +268,6 @@ let
};
};
writeOidcJwksConfigFile =
oidcIssuerPrivateKeyFile:
pkgs.writeText "oidc-jwks.yaml" ''
identity_providers:
oidc:
jwks:
- key: {{ secret "${oidcIssuerPrivateKeyFile}" | mindent 10 "|" | msquote }}
'';
# Remove an attribute in a nested set
# https://discourse.nixos.org/t/modify-an-attrset-in-nix/29919/5
removeAttrByPath =
@@ -362,7 +353,12 @@ in
execCommand = "${instance.package}/bin/authelia";
configFile = format.generate "config.yml" cleanedSettings;
oidcJwksConfigFile = lib.optional (instance.secrets.oidcIssuerPrivateKeyFile != null) (
writeOidcJwksConfigFile instance.secrets.oidcIssuerPrivateKeyFile
pkgs.writeText "oidc-jwks.yaml" ''
identity_providers:
oidc:
jwks:
- key: {{ mustEnv "CREDENTIALS_DIRECTORY" | printf "%s/oidcIssuerPrivateKeyFile" | secret | mindent 10 "|" | msquote }}
''
);
configArg = "--config ${
builtins.concatStringsSep "," (
@@ -373,21 +369,25 @@ in
]
)
}";
# Mapping between the Authelia env variables and the secret keys defined in the module
envSecretsMap = {
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE = "jwtSecretFile";
AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE = "storageEncryptionKeyFile";
AUTHELIA_SESSION_SECRET_FILE = "sessionSecretFile";
AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE = "oidcHmacSecretFile";
};
nonNullEnvSecretsMap = lib.filterAttrs (_: v: instance.secrets.${v} != null) envSecretsMap;
in
{
description = "Authelia authentication and authorization server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ]; # Checks SMTP notifier creds during startup
wants = [ "network-online.target" ];
environment =
(lib.filterAttrs (_: v: v != null) {
X_AUTHELIA_CONFIG_FILTERS = lib.mkIf (oidcJwksConfigFile != [ ]) "template";
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE = instance.secrets.jwtSecretFile;
AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE = instance.secrets.storageEncryptionKeyFile;
AUTHELIA_SESSION_SECRET_FILE = instance.secrets.sessionSecretFile;
AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE = instance.secrets.oidcHmacSecretFile;
})
// instance.environmentVariables;
environment = {
X_AUTHELIA_CONFIG_FILTERS = lib.mkIf (oidcJwksConfigFile != [ ]) "template";
}
// lib.mapAttrs (_: v: "%d/${v}") nonNullEnvSecretsMap
// instance.environmentVariables;
preStart = "${execCommand} ${configArg} validate-config";
serviceConfig = {
@@ -399,6 +399,12 @@ in
StateDirectory = autheliaName instance.name;
StateDirectoryMode = "0700";
LoadCredential =
lib.optional (
instance.secrets.oidcIssuerPrivateKeyFile != null
) "oidcIssuerPrivateKeyFile:${instance.secrets.oidcIssuerPrivateKeyFile}"
++ lib.mapAttrsToList (_: v: "${v}:${instance.secrets.${v}}") nonNullEnvSecretsMap;
# Security options:
AmbientCapabilities = "";
CapabilityBoundingSet = "";

View File

@@ -28,12 +28,10 @@
# This is purely for testing purposes!
environment.etc."authelia/storageEncryptionKeyFile" = {
mode = "0400";
user = "authelia-testing";
text = "you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this";
};
environment.etc."authelia/jwtSecretFile" = {
mode = "0400";
user = "authelia-testing";
text = "a_very_important_secret";
};
environment.etc."authelia/users_database.yml" = {