The allow-list (AuthentikNamespacePolicy)
How a namespace gets permission to create Applications/AccessPolicies, and what happens when it doesn't.
AuthentikNamespacePolicy is the operator's central security
mechanism: default-deny. A namespace can create
AuthentikApplication/AuthentikAccessPolicy resources only if some
rule, across every AuthentikNamespacePolicy in the cluster,
explicitly allows it.
Granting a namespace access
apiVersion: authentik.weebo.io/v1alpha1
kind: AuthentikNamespacePolicy
metadata:
name: team-a-access
spec:
rules:
- namespaces: ["team-a"]
allowedKinds: ["AuthentikApplication", "AuthentikAccessPolicy"]
effect: AllowAuthentikNamespacePolicy is cluster-scoped — only a cluster admin can
create or edit it. rules is a list; each rule names the namespaces it
applies to, the resource kinds it covers, and whether it Allows or
Denys. A namespace entry is an exact name, * (every namespace), or a
prefix glob: team-* matches team-a, team-b… A Deny rule always wins over a matching Allow, regardless
of which one is listed first or which AuthentikNamespacePolicy object
it came from — there's no ordering to reason about, a narrower deny is
always the last word.
What happens if a namespace isn't allowed
An admission webhook validates every CREATE/UPDATE of an
AuthentikApplication or AuthentikAccessPolicy (never DELETE — see
below) against the current rules. A denied request is rejected at
kubectl apply time with a message like:
Error from server: admission webhook "..." denied the request:
no AuthentikNamespacePolicy rule allows AuthentikApplication in namespace "team-b"(or a Deny rule matches namespace "team-b" for AuthentikApplication
when a Deny rule is what refused it).
The webhook's failurePolicy is Fail: if the webhook pod itself is
unreachable, writes are blocked cluster-wide rather than silently
allowed through. This is why the
Helm chart runs it multi-replica by default.
Existing resources after a policy change
The operator re-checks the same rules on every reconcile of an
AuthentikApplication or AuthentikAccessPolicy, and re-triggers all of
them whenever an AuthentikNamespacePolicy changes. An object created
before a rule was narrowed (or before the first policy existed) turns
Ready: False with reason NamespaceNotAllowed and an Event; the
operator stops updating it in Authentik but deletes nothing — the object
stays as it was until the rule allows it again (it then resumes) or the
CR is deleted (its cleanup always runs).
Why DELETE is never validated
Revoking a namespace's access (removing or narrowing its
AuthentikNamespacePolicy rule) must never block cleanup of resources
it already created — a finalizer that can't run because the webhook
now denies its own object's deletion would strand that object
permanently. The webhook only ever validates CREATE/UPDATE.