Commit fbfcd3e
Amin
fix: allow tenant owners to create namespaces with create-if-missing clients
A tenant owner running `helm install --create-namespace` fails every time
with a 403 on a namespace-scoped resource, and the namespace is never
created (projectcapsule/capsule#1895).
Two distinct problems are at play.
First, Kubernetes authorizes namespace-scoped requests via RoleBindings
that live inside the target namespace, so a namespace that does not exist
yet can never have one. A tenant owner probing a resource there therefore
always gets 403 Forbidden, never the 404 Not Found a cluster-wide
privileged caller receives for the same request. Clients using the
idiomatic "GET, and create it if 404" pattern -- Helm's
`--create-namespace` among them -- treat that 403 as fatal and abort
before they ever attempt to create the namespace.
Second, once creation does proceed, Capsule provisions the owner's
RoleBindings asynchronously, after the Namespace object has already been
persisted and returned. A client acting immediately inside the namespace
it was just handed can still race that provisioning.
Both are addressed in the reverse proxy's ModifyResponse hook:
- maskForbiddenForMissingNamespace rewrites 403 to 404 when a
namespace-scoped GET-by-name failed only because the namespace does
not exist. It is deliberately narrow so it cannot become a
cross-tenant existence oracle: it applies only when the namespace
name falls within the naming space of a tenant the caller actually
owns, and only when the namespace is confirmed absent. A caller can
thus only learn that a namespace they are entitled to create does not
exist yet -- something they can already determine. Every other 403 is
passed through untouched.
- waitForOwnerCreationResponse holds a successful namespace-create
response until the owner's RoleBinding lands, covering both the
collection POST and the server-side-apply PATCH that Helm 4 uses by
default. Dry-run creates are skipped, since they persist nothing to
wait for. The wait is bounded end-to-end by a context deadline and
fails open: the namespace is already created by that point, so a
timeout releases the response rather than misreporting success as an
error.
No new RBAC is required; capsule-proxy already has the necessary read
access.
Refs: projectcapsule/capsule#18951 parent a4d7ee2 commit fbfcd3e
1 file changed
Lines changed: 365 additions & 2 deletions
0 commit comments