# 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 ```text . ├── 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: ```text 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: ```bash 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 \ --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.