Created
January 5, 2024 10:12
-
-
Save anpin/ecbdb6625400908856ef9482eca3380c to your computer and use it in GitHub Desktop.
Authentik NixOS module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{config, pkgs, lib, ... }: | |
let | |
cfg = config.services.authentik; | |
databaseActuallyCreateLocally = cfg.database.createLocally && cfg.database.host == "/run/postgresql"; | |
inherit (pkgs) | |
authentik | |
; | |
inherit (lib) | |
mkIf | |
mkEnableOption | |
mkOption | |
types | |
mdDoc | |
literalExpression | |
optional | |
optionalString | |
concatStringsSep | |
attrsets | |
; | |
inherit (attrsets) | |
optionalAttrs; | |
inherit (types) | |
str | |
bool | |
port | |
submodule | |
package | |
nullOr | |
path | |
enum | |
; | |
hostWithPort = h: p : "${h}:${toString p}"; | |
authentikBaseService = { | |
after = [ "network.target" ] | |
++ optional databaseActuallyCreateLocally "postgresql.service"; | |
wantedBy = [ "multi-user.target" ]; | |
path = [ | |
authentik | |
]; | |
environment = | |
let listenAddress = hostWithPort cfg.listen.address; | |
in { | |
AUTHENTIK_REDIS__HOST = cfg.redis.host; | |
AUTHENTIK_REDIS__PORT = toString cfg.redis.port; | |
AUTHENTIK_POSTGRESQL__HOST = cfg.database.host; | |
AUTHENTIK_POSTGRESQL__PORT = toString cfg.database.port; | |
AUTHENTIK_POSTGRESQL__USER = cfg.database.user; | |
AUTHENTIK_POSTGRESQL__NAME = cfg.database.name; | |
AUTHENTIK_LISTEN__HTTP = listenAddress cfg.listen.http; | |
AUTHENTIK_LISTEN__HTTPS = listenAddress cfg.listen.https; | |
# initial password for admin user | |
AUTHENTIK_BOOTSTRAP_PASSWORD = cfg.defaultPassword; | |
# disable outbound connections | |
AUTHENTIK_DISABLE_UPDATE_CHECK="true"; | |
AUTHENTIK_ERROR_REPORTING__ENABLED="false"; | |
AUTHENTIK_DISABLE_STARTUP_ANALYTICS="true"; | |
AUTHENTIK_AVATARS="initials"; | |
AUTHENTIK_LOG_LEVEL=cfg.logLevel; | |
}; | |
serviceConfig = { | |
User = cfg.user; | |
Group = cfg.group; | |
EnvironmentFile = cfg.environmentFile; | |
WorkingDirectory = cfg.package; | |
DynamicUser = true; | |
RuntimeDirectory = "authentik"; | |
NoNewPrivileges = true; | |
PrivateTmp = true; | |
ProtectHome = true; | |
ProtectSystem = "strict"; | |
ProtectKernelTunables = true; | |
ProtectKernelModules = true; | |
ProtectControlGroups = true; | |
SystemCallFilter= "~@cpu-emulation @keyring @module @obsolete @raw-io @reboot @swap @sync"; | |
ConfigurationDirectory = "authentik"; | |
StateDirectoryMode = "0750"; | |
}; | |
}; | |
in { | |
options.services.authentik = { | |
enable = mkEnableOption "Enables Authentik service"; | |
package = mkOption { | |
type = package; | |
default = pkgs.authentik; | |
defaultText = literalExpression "pkgs.authentik"; | |
description = mdDoc "Authentik package to use."; | |
}; | |
user = mkOption { | |
description = mdDoc '' | |
User under which authentik runs. | |
''; | |
type = str; | |
default = "authentik"; | |
}; | |
group = mkOption { | |
description = mdDoc '' | |
Group under which authentik runs. | |
''; | |
type = str; | |
default = "authentik"; | |
}; | |
defaultPassword = mkOption { | |
description = mdDoc "Default admin password. Only read on first startup."; | |
type = str; | |
default = "change-me"; | |
}; | |
logLevel = mkOption { | |
description = mdDoc "Log level for the server and worker containers. Setting the log level to trace will include sensitive details in logs, so it shouldn't be used in most cases."; | |
type = enum [ "trace" "debug" "info" "warning" "error" ]; | |
default = "info"; | |
}; | |
listen = mkOption { | |
description = mdDoc "Listen ports"; | |
default = {}; | |
type = submodule { | |
options = { | |
http = mkOption { | |
description = mdDoc "HTTP port."; | |
type = port; | |
default = 9000; | |
}; | |
https = mkOption { | |
description = mdDoc "HTTPS port."; | |
type = port; | |
default = 9443; | |
}; | |
address = mkOption { | |
description = mdDoc "Address to listen on."; | |
type = str; | |
default = "0.0.0.0"; | |
}; | |
}; | |
}; | |
}; | |
redis = { | |
createLocally = mkOption { | |
description = mdDoc "Configure local Redis server for Authentik."; | |
type = bool; | |
default = true; | |
}; | |
host = mkOption { | |
description = mdDoc "Redis host."; | |
type = str; | |
default = "127.0.0.1"; | |
}; | |
port = mkOption { | |
description = mdDoc "Redis port."; | |
type = port; | |
default = 31637; | |
}; | |
}; | |
ssl = { | |
cert = mkOption { | |
type = nullOr path; | |
default = null; | |
}; | |
key = mkOption { | |
type = nullOr path; | |
default = null; | |
}; | |
name = mkOption { | |
type = str; | |
default = "SSL from NIXOS"; | |
}; | |
}; | |
secretKeyFile = mkOption { | |
type = nullOr path; | |
default = null; | |
example = "/var/lib/authentik/secrets/db-password"; | |
description = mdDoc '' | |
Secret key used for cookie signing and unique user IDs, don't change this after the first install. | |
''; | |
}; | |
environmentFile = mkOption { | |
type = nullOr path; | |
default = null; | |
example = "/var/lib/authentik/secrets/db-password"; | |
description = mdDoc '' | |
Environment variables including : | |
- Secret key used for cookie signing and unique user IDs, don't change this after the first install. | |
''; | |
}; | |
database = { | |
createLocally = mkOption { | |
description = mdDoc "Configure local PostgreSQL database server for authentik."; | |
type = bool; | |
default = true; | |
}; | |
host = mkOption { | |
type = str; | |
default = "/run/postgresql"; | |
example = "192.168.23.42"; | |
description = mdDoc "Database host address or unix socket."; | |
}; | |
port = mkOption { | |
type = nullOr port; | |
default = if cfg.database.createLocally then null else 5432; | |
defaultText = literalExpression '' | |
if config.database.createLocally | |
then null | |
else 5432 | |
''; | |
description = mdDoc "Database host port."; | |
}; | |
name = mkOption { | |
type = str; | |
default = "authentik"; | |
description = mdDoc "Database name."; | |
}; | |
user = mkOption { | |
type = str; | |
default = "authentik"; | |
description = mdDoc "Database user."; | |
}; | |
}; | |
outposts = mkOption { | |
type = submodule { | |
options = { | |
ldap = mkOption { | |
type = submodule { | |
options = { | |
enable = mkEnableOption (lib.mdDoc "the authentik ldap outpost"); | |
package = mkOption { | |
type = path; | |
default = pkgs.authentik-outposts.ldap; | |
}; | |
host = mkOption { | |
type = str; | |
default = "https://127.0.0.1:9443"; | |
}; | |
insecure = mkOption { | |
type = bool; | |
default = false; | |
}; | |
environmentFile = mkOption { | |
type = nullOr path; | |
default = null; | |
example = "/var/lib/authentik-ldap/secrets/env"; | |
description = mdDoc '' | |
Environment variables including : | |
- API TOKEN | |
''; | |
}; | |
listen = mkOption { | |
description = mdDoc "Listen ports"; | |
default = {}; | |
type = submodule { | |
options = { | |
ldap = mkOption { | |
description = mdDoc "LDAP port."; | |
type = port; | |
default = 3389; | |
}; | |
ldaps = mkOption { | |
description = mdDoc "LDAPS port."; | |
type = port; | |
default = 6636; | |
}; | |
address = mkOption { | |
description = mdDoc "Address to listen on."; | |
type = str; | |
default = "0.0.0.0"; | |
}; | |
}; | |
}; | |
}; | |
}; | |
}; | |
}; | |
}; | |
}; | |
default = { ldap = { enable = false; };}; | |
}; | |
}; | |
config = mkIf cfg.enable { | |
users.users = | |
(mkIf (cfg.user == "authentik") { | |
authentik = { | |
isSystemUser = true; | |
home = cfg.package; | |
inherit (cfg) group; | |
}; | |
}); | |
users.groups.${cfg.group} = {}; | |
services.postgresql = mkIf databaseActuallyCreateLocally { | |
enable = true; | |
ensureUsers = [ | |
{ | |
name = cfg.database.name; | |
ensureDBOwnership = true; | |
} | |
]; | |
ensureDatabases = [ cfg.database.name ]; | |
}; | |
services.redis.servers.authentik = mkIf (cfg.redis.createLocally && cfg.redis.host == "127.0.0.1") { | |
enable = true; | |
port = cfg.redis.port; | |
bind = "127.0.0.1"; | |
}; | |
systemd.services.authentik-server = authentikBaseService // { | |
serviceConfig = authentikBaseService.serviceConfig // { | |
ExecStart = "${cfg.package}/bin/ak server"; | |
}; | |
}; | |
systemd.services.authentik-worker = authentikBaseService // { | |
serviceConfig = authentikBaseService.serviceConfig // { | |
ExecStart = "${cfg.package}/bin/ak worker"; | |
}; | |
}; | |
systemd.services.authentik-ssl-import = authentikBaseService // { | |
before = [ "authentik-server.service" ]; | |
serviceConfig = authentikBaseService.serviceConfig // { | |
Type = "oneshot"; | |
RemainAfterExit = true; | |
ExecStart = "${cfg.package}/bin/ak import_certificate --name \"${cfg.ssl.name}\" --certificate \"${cfg.ssl.cert}\" --private-key \"${cfg.ssl.key}\""; | |
}; | |
}; | |
systemd.services.authentik-ldap-outpost = | |
let ldapCfg = cfg.outposts.ldap; in | |
mkIf ldapCfg.enable (authentikBaseService // { | |
description = "authentik ldap outpost"; | |
environment = | |
let listenAddress = hostWithPort ldapCfg.listen.address; | |
in { | |
AUTHENTIK_HOST = ldapCfg.host; | |
AUTHENTIK_LISTEN__LDAP = listenAddress ldapCfg.listen.ldap; | |
AUTHENTIK_LISTEN__LDAPS = listenAddress ldapCfg.listen.ldaps; | |
} // optionalAttrs ldapCfg.insecure { AUTHENTIK_INSECURE = "true"; }; | |
serviceConfig = authentikBaseService.serviceConfig // { | |
ExecStart = "${cfg.outposts.ldap.package}/bin/ldap"; | |
EnvironmentFile = ldapCfg.environmentFile; | |
}; | |
}); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Make sure authentik is in your nixpkgs (see this PR NixOS/nixpkgs#271885), import the module and use it your config as such: