authentik/README.md

4.2 KiB

Authentik deployment

This repository owns the production Authentik Compose deployment and its Komodo Stack declaration. The central komodo-bootstrap repository owns the child Resource Sync and the ordered deployment Procedure.

Layout

.
├── docker-compose.yml
├── docker-compose.override.yml
├── komodo.toml
├── env/
│   └── common.env
├── secrets/
│   └── prod.env.age
├── scripts/
│   ├── compose.sh
│   └── init.sh
└── tests/
    └── compose-secrets.sh

env/common.env contains tracked, non-secret configuration and explicit image versions. secrets/prod.env.age contains only secrets and is encrypted to the sbx0docker01 SSH host key and the personal agenix-phg SSH key.

The authentik-prod Stack follows protected main. Its direct webhook is disabled. A Forgejo webhook calls the central authentik-deploy Procedure, which runs the child Sync before DeployStackIfChanged.

Komodo passes docker-compose.yml first and docker-compose.override.yml second. The base and deployment-specific override remain separate by design.

Secrets

The encrypted production bundle contains:

PG_PASS
AUTHENTIK_SECRET_KEY
AUTHENTIK_EMAIL__PASSWORD
GEOIPUPDATE_LICENSE_KEY

To edit it locally, decrypt to a mode-0600 temporary file, edit it, then encrypt it to both recipients:

tmp=$(mktemp)
chmod 0600 "$tmp"
trap 'rm -f -- "$tmp"' EXIT HUP INT TERM

age --decrypt \
  --identity ~/.ssh/identities/agenix-phg \
  --output "$tmp" \
  secrets/prod.env.age

${EDITOR:-vi} "$tmp"

age --encrypt \
  --armor \
  --recipient 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH4umkUY5CG5aNJBhUjVcU8TWbh453N0pGHZhYDTOGQa' \
  --recipient 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIr4Dji0wWzwSXyqbxdGa8LdWkhP+0T7kDKrLbyCoyos' \
  --output secrets/prod.env.age.new \
  "$tmp"

mv secrets/prod.env.age.new secrets/prod.env.age

Do not add a plaintext secret file to Git. The Stack config tracks the encrypted bundle so a rotation counts as a deployment change, but does not track the temporary .komodo/prod.env file.

The decrypted values are Compose secret sources rather than service environment values. Containers receive only their declared files under /run/secrets; Authentik reads them through file:// configuration values, while PostgreSQL and GeoIP Update use their _FILE variables. Consequently, docker compose config renders secret source names and file paths without persisting the values in Komodo's merged configuration.

Compose wrapper

Komodo wraps config, pull, up, and run with the NixOS-provided with-age-env command. The wrapper:

  • obtains an exclusive per-bundle lock;
  • removes stale plaintext and temporary files;
  • decrypts through the NixOS-provided systemd age-identity credential;
  • creates plaintext with mode 0600; and
  • removes plaintext on success, failure, or a handled signal.

The plaintext target and matching .lock and .tmp.* paths are exclusively owned by the wrapper. A SIGKILL or power loss can leave plaintext behind; the next invocation removes it before decrypting again.

NixOS owns the wrapper, its runtime dependencies, the host-key systemd credential, Periphery's Podman permissions, and the external dokploy-network. Workload containers do not receive the age identity, but commands launched by Periphery can access it. Revisit that trust boundary if deployment authority is ever granted to another operator.

Run bash tests/compose-secrets.sh to verify that sentinel secret values do not appear in the rendered Compose model and that every service receives only its intended secret files.

Optional test environment

Do not create a test Stack or dummy bundle until there is a real long-lived test branch. When it is needed:

  1. add secrets/test.env.age, encrypted to the test host and personal keys;
  2. keep both Stack declarations in komodo.toml on main;
  3. point authentik-test at branch test and its own encrypted/decrypted paths; and
  4. add authentik-test to the Procedure's deployment stage in the central bootstrap repository.

The repository webhook should use the Procedure's __ANY__ endpoint so pushes to either protected environment branch enter the same ordered flow.