weebo-authentik

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: Allow

AuthentikNamespacePolicy 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.

On this page