Idempotent Authentik provisioning from YAML service registry
  • Python 99.3%
  • Dockerfile 0.7%
Find a file
Rudy ce39e2a32b
All checks were successful
Build authentik-sync image / build (push) Successful in 1m16s
feat: auto-create access-control groups when missing
_sync_group_policy previously errored and skipped RBAC when a group named
in a service's auth.groups didn't exist in Authentik, so adding a new group
to values.yaml silently did nothing until someone created it by hand in the
UI. Add AuthentikClient.ensure_group() and call it instead of find_group():
missing groups are created as non-superuser (a typo can't mint an admin
group) and built-in groups like "authentik Admins" are still matched, never
recreated. Adding a group name to the registry is now sufficient; only
membership must be assigned manually.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 23:21:10 -04:00
.forgejo/workflows fix: docker:27-git doesn't exist, use docker:27 + apk add git 2026-02-26 02:15:03 +00:00
.gitignore feat: manage skip_path_regex on proxy providers 2026-03-21 17:59:12 -04:00
Dockerfile Initial commit: sync-authentik.py + Dockerfile + CI 2026-02-26 01:01:34 +00:00
README.md feat: auto-create access-control groups when missing 2026-07-17 23:21:10 -04:00
sync-authentik.py feat: auto-create access-control groups when missing 2026-07-17 23:21:10 -04:00
test-values.yaml Initial commit: sync-authentik.py + Dockerfile + CI 2026-02-26 01:01:34 +00:00

authentik-sync

Idempotent Authentik provisioning from a YAML service registry. Syncs providers, applications, outpost bindings, group policies, and OIDC client secrets (with Vault integration).

Groups referenced in a service's auth.groups are created automatically (as non-superuser groups) if they don't already exist, then bound via an expression policy. This means adding a new group name to values.yaml is enough — no manual group creation in the Authentik UI. Only membership still has to be assigned. Built-in groups like authentik Admins are matched, never recreated.

Image

Built and pushed to git.bun.cafe/cinnabrad/authentik-sync via Forgejo Actions on every push to main.

Consumed by the service-routes Helm chart in the infra repo as an ArgoCD PostSync hook Job.

Local usage

export AUTHENTIK_URL=https://auth.bun.cafe
export AUTHENTIK_API_TOKEN=<token>
export AUTHENTIK_VERIFY_SSL=false

# Without Vault
python3 sync-authentik.py --values test-values.yaml --dry-run

# With Vault (token auth for local testing)
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_AUTH_METHOD=token
export VAULT_TOKEN=<token>
python3 sync-authentik.py --values test-values.yaml

Flags

Flag Description
--values PATH Path to service registry YAML (default: charts/service-routes/values.yaml)
--dry-run Show what would change without making changes
--diff Show drift between current and desired state (implies --dry-run)
--rotate-secret SERVICE Rotate OIDC client_secret for a specific service

Secret rotation

python3 sync-authentik.py --rotate-secret argocd --values values.yaml

Generates a new client_secret, PATCHes the Authentik provider, and overwrites the Vault KV entry. ESO syncs the new value on its next refresh cycle.

Environment variables

Variable Required Default Description
AUTHENTIK_URL Yes Base URL of Authentik instance
AUTHENTIK_API_TOKEN Yes API token with admin privileges
AUTHENTIK_VERIFY_SSL No true Set to false to disable SSL verification
VAULT_ADDR No http://vault.vault.svc:8200 Vault address
VAULT_AUTH_METHOD No kubernetes kubernetes or token
VAULT_TOKEN No Only used when VAULT_AUTH_METHOD=token

CI test

public

cnp fix