The policy previously only fired on UPDATE and only when oldObject already
carried namespace.cozystack.io/host, which left two paths unguarded:
- CREATE of a namespace with the label pre-set.
- UPDATE that adds the label for the first time (oldObject has no label,
so the matchCondition was false and the VAP was skipped).
Both paths required namespace create/update on labels, which is normally
cluster-admin-only, but the VAP is meant to be the source of truth for
this label's integrity. Close the gap:
- operations: [CREATE, UPDATE]
- matchCondition now fires when either object or oldObject carries the
label (renamed had-host-label -> touches-host-label).
- oldHost is computed with a null-safe ternary so CREATE (where
oldObject is null) evaluates cleanly.
The existing validation (newHost == oldHost || trustedCaller) then
naturally denies first-time label writes from non-trusted callers while
still allowing cozy-system / cozy-cert-manager / flux-system / kube-system
SAs to stamp the label during the tenant chart apply.
Update packages/extra/gateway/README.md layer 5 description to match and
add an e2e test that asserts a namespace CREATE with the label from an
untrusted SA is rejected.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
|
||
|---|---|---|
| .. | ||
| apps | ||
| core | ||
| extra | ||
| library | ||
| system | ||
| tests/cozy-lib-tests | ||