canonical / canonical/authentik-server-operator
Mint dedicated least-privilege Authentik automation tokens instead of sharing the bootstrap admin token
- Dominant language
- Python
- Stars
- 1
- Forks
- 1
- Avg merge
- 1h 37m
- Merged PRs (30d)
- 16
Description
## Context
While collapsing the `authentik-server-info` contract to a single canonical `api-token` key, we implemented and then **deliberately reverted (deferred)** the minting of dedicated, least-privilege Authentik automation identities. Today the server publishes its **bootstrap admin token** under the `api-token` key, and consumers (the LDAP outpost) use it for every Authentik API call.
Repos:
- Provider: `canonical/authentik-server-operator` (publishes `api-token` over `authentik-server-info`)
- Consumer: `canonical/authentik-ldap-outpost-operator` (consumes `api-token`)
## Problem / risk
- A compromise of a consumer (e.g. the LDAP outpost) yields a **full-privilege Authentik admin token** rather than a scoped one.
- The bootstrap admin token is long-lived and shared across all server-info relations.
## Desired outcome
- The server mints dedicated, non-expiring, least-privilege API tokens (distinct server-OAuth and per-consumer LDAP identities + roles) and publishes those over `api-token`, keeping the bootstrap token **server-local** (startup, recovery, and automation-credential repair only).
- Implement the typed API primitives needed for this (service-account, role, global-permission, API-token creation, key view) in `src/authentik_api.py`. An earlier iteration added these but they were **removed from the shipped PR to avoid unused code**; reintroduce them (with tests) as part of this work.
## Caveats to address when implementing (from code review)
1. Make API-token reconciliation apply changes: an idempotent-by-identifier `ensure_api_token` that returns early when the token exists will **not** apply a later change to `description`/`expiring`/`intent` or a needed key rotation. Handle reconcile/rotation.
2. Re-verify the permission codename lists against the target Authentik version (they were pinned to 2026.5.3); an invalid codename fails permission assignment.
3. Coordinate the provider/consumer upgrade (LIBPATCH) — consumers read `api-token` regardless of whether it carries a dedicated or the bootstrap token. The consumer already tolerates a legacy `bootstrap-token` key during rollout.
## References
- Contract shipped in canonical/authentik-server-operator#63 and canonical/authentik-ldap-outpost-operator#47.
- OpenSpec archived change `provide-authentik-automation-credentials` (api-token contract shipped; dedicated minting deferred).
Contributor guide
Research direction
Start in src/authentik_api.py and inspect the existing tests and the provider/consumer api-token contract. Trace how the server publishes api-token and how the LDAP outpost consumes it; done means dedicated scoped identities are published, the bootstrap token remains server-local, reconciliation handles updates and rotation, and the provider/consumer rollout is coordinated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- authentication, authorization, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100