Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions doc/authentik.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Authentik

[Authentik](https://goauthentik.io/) is an open-source identity provider offering single sign-on (SSO), user federation and support for OpenID Connect, OAuth 2.0, SAML and more.

> [!NOTE]
>
> This module runs the `migrate`, `worker` and `server` components for local development and testing, not production. Secrets set via `settings`/`secretKey/`environmentFile` end up in the Nix store.

Authentik is not in nixpkgs. You must provide the packages yourself via [`components`](#components) from the [`authentik-nix`](https://github.com/nix-community/authentik-nix) flake input.
It also needs a PostgreSQL and a Redis instance.

{#start}

## Getting Started

```nix
perSystem = {config, inputs', ...}:
let
ak = config.process-compose."authentik".services.authentik.ak;
in
{
process-compose."authentik" = {
# Configure the sidecar postgres and a redis processes.
services.postgres = ak.services.postgres;
services.redis = ak.services.redis;

# Configure authentik.
services.authentik."authentik" = {
enable = true;

compponents = inputs.authentik-nix.packages.${system};
secretKey = "dev-secret";

settings = {
listen.http = "0.0.0.0:9000";

postgresql = {
host = "127.0.0.1";
port = 5433;
user = "authentik";
name = "authentik";
password = "authentik";
};

redis.host = "127.0.0.1";
redis.port = 6378;
};
};
};
```

Authentik becomes available at [http://localhost:9000](http://localhost:9000).
The bootstrap admin user is `akadmin` with the e-mail set by [`initialAdminEmail`](#admin-email) (`admin@example.com` by default) and the password set by [`initialAdminPassword`](#admin-password) (`admin` by default).

{#tips}

## Tips & Tricks

{#blueprints}

### Import Blueprints

[Blueprints](https://docs.goauthentik.io/docs/customize/blueprints/) declare Authentik objects (groups, applications, flows, ...) as YAML. A blueprint listed under `settings.blueprints` with `import = true` (the default) and a `path` set is copied into the blueprints directory on start up and auto-applied by the worker.
The `path` may be relative to the `process-compose` working directory or a Nix store path.

```nix
{
services.authentik."ak" = {
enable = true;

settings.blueprints.my-app = {
path = ./blueprints/my-app.yaml;
};
};
}
```
1 change: 1 addition & 0 deletions doc/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ short-title: Services
# Supported services

- [[apache-kafka]]#
- [[authentik]]#
- [[azurite]]#
- [[cassandra]]#
- [[chromadb]]#
Expand Down
8 changes: 8 additions & 0 deletions nix/services/authentik.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ ...
}:
{
imports = [
./authentik/service.nix
./authentik/options.nix
];
}
178 changes: 178 additions & 0 deletions nix/services/authentik/options.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{ config
, lib
, pkgs
, name
, ...
}:

let
inherit (lib)
mkOption
mkEnableOption
types
;

settingsFormat = pkgs.formats.yaml { };

hostAndPort = name: port: {
host = mkOption {
type = types.str;
default = "0.0.0.0";
description = "Host of the ${name}.";
};
port = mkOption {
type = types.port;
default = port;
description = "Port of the ${name}.";
};
};
in
{
options = {
components = mkOption {
type = types.raw;
example = lib.literalExpression "inputs.authentik-nix.legacyPackages.\${system}.authentikComponents";
description = ''
The Authentik component set, typically
`inputs.authentik-nix.legacyPackages.''${system}.authentikComponents`.
'';
};

secretKey = mkOption {
type = types.nullOr types.str;
example = "insecure-dev-secret";
description = ''
The Authentik secret key, exported as `AUTHENTIK_SECRET_KEY`.

This is written into the process environment and therefore ends up in the
Nix store; only use it for local development. For anything else set
{option}`environmentFile` instead and put `AUTHENTIK_SECRET_KEY` there.
'';
};

initialAdminEmail = mkOption {
type = types.str;
default = "admin@example.com";
description = ''
E-mail for the bootstrap `akadmin` user, exported as
`AUTHENTIK_BOOTSTRAP_EMAIL`.
'';
};

initialAdminPassword = mkOption {
type = types.str;
default = "admin";
description = ''
Initial password for the bootstrap `akadmin` user, exported as
`AUTHENTIK_BOOTSTRAP_PASSWORD`.
'';
};

environmentFile = mkOption {
type = types.nullOr (
types.pathWith {
inStore = false;
absolute = false;
}
);
default = null;
example = "authentik.env";
description = ''
Path to an environment file with additional
`AUTHENTIK_*` variables, e.g. `AUTHENTIK_SECRET_KEY` and
`AUTHENTIK_POSTGRESQL__PASSWORD`.
Values here override {option}`settings`.
'';
};

services = {
postgres = mkOption {
type = types.attrsOf types.raw;
readOnly = true;
description = ''
The config to easily define the needed postgres process.
'';
};
};

logLevel = mkOption {
type = types.str;
default = "info";
example = "debug";
description = "Authentik log level.";
};

server = {
http = hostAndPort "server endpoint" 9000;
https = hostAndPort "server endpoint" 9443;
metrics = hostAndPort "server metrics endpoint." 9300;
};

worker = {
http = hostAndPort "worker endpoint" 9001;
metrics = hostAndPort "worker metrics endpoint." 9302;
};

email = hostAndPort "${name}'s email connection" 25;

postgres = (hostAndPort "${name}'s postgres DB" 5432) // {
name = mkOption {
type = types.str;
default = "authentik";
description = "PostgreSQL database name (`postgresql.name`).";
};

user = mkOption {
type = types.str;
default = "authentik";
description = "PostgreSQL user (`postgresql.user`).";
};

password = mkOption {
type = types.str;
default = "authentik";
description = ''
PostgreSQL password (`postgresql.password`). Written to the config
file in the Nix store; for non-dev use, override it via
{option}`environmentFile` (`AUTHENTIK_POSTGRESQL__PASSWORD`).
'';
};
};

blueprints = {
export = {
enable = mkEnableOption "blueprint export process on manual trigger";
path = mkOption {
description = "The path to the export file.";
type = types.pathWith {
inStore = false;
absolute = false;
};
default = "${config.dataDir}/export/blueprint.yaml";
};
};

imports = mkOption {
description = ''
Blueprints to import on start up.
Enabled blueprints are copied into the blueprints directoryr and
auto-applied by the Authentik worker.
'';
type = types.listOf (
types.pathWith {
inStore = true;
}
);
default = [ ];
};
};

settings = mkOption {
description = "YAML option for authentic which are merged with '<dataDir>/authentic/lib/default.yml'.";
type = types.submodule {
freeformType = settingsFormat.type;
options = { };
};
};
};
}
Loading