Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions docs/tenant-abstraction.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,19 @@ and annotations; they cannot force orphaning by removing that finalizer.
The existing platform-owned `flux-system/wedding-app` pilot is an exact
exception, not a wildcard namespace exemption.

KRO 0.9.2 identifies children through ApplySet and `kro.run/instance-*` labels,
not WebApp owner references. Child admission therefore checks their complete
placement/identity and refuses updates that would adopt an unlabelled or
KRO 0.9.4 identifies children through ApplySet and `kro.run/instance-*` labels,
not WebApp owner references, and its apply path adopts an existing unlabelled
object. Child admission therefore checks their complete placement/identity and
refuses updates that would adopt an unlabelled or
foreign-owned Deployment, Service or HTTPRoute. Non-controller writers must
preserve reserved ownership labels. Controller updates may change provenance
such as `kro.run/kro-version`, while instance/node/ApplySet identity remains fixed.
Existing hostname, secret-store and
network admission remain in force; KRO has no hostname bypass.

KRO's pinned deletion path does not itself verify child ownership. Deletion
KRO's pinned deletion path does not itself verify child ownership: it deletes every
object carrying the parent's ApplySet membership label, with a UID precondition that
only guards against a recreate between listing and deleting. Deletion
admission additionally requires complete old child ownership, a read of the
labelled parent's matching UID, and that parent's deletion timestamp. This
prevents failed collision/rollback from deleting an unowned workload or another
Expand Down Expand Up @@ -168,7 +171,7 @@ rejects duplicate members before jq can keep a last value; the maintained YAML
decoder also checks the original source before conversion. Complete inputs are
bounded to 1 MiB, with at most 1024 raw YAML documents. This is the platform's committed
source gate, not proof of a future tenant publisher's input validation. The actual
KRO 0.9.2 compiler/generated API tests admission, defaults, literal arguments and
KRO 0.9.4 compiler/generated API tests admission, defaults, literal arguments and
resolved children. Resolved deployments are separately scanned with Trivy 0.74.0;
the writable-root and low-ID compatibility findings remain explicit rather than
disappearing behind expressions. Both resolved states pass the actual container
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# KRO 0.9.2 deletes graph targets by name without an ownership precondition.
# A failed collision followed by parent deletion must not delete another app.
# KRO 0.9.4 deletes a WebApp's children by ApplySet membership: it lists every object
# that carries the parent's applyset.kubernetes.io/part-of label in the recorded scope
# and deletes each with a UID precondition taken from that same list
# (pkg/controller/instance/deletion.go, applyset/applyset.go). The precondition only
# guards against a recreate between list and delete; a label is not proof of ownership.
# A failed collision followed by parent deletion must not delete another app, so KRO may
# delete only a child whose labels bind it to the parent being deleted. Kept as defence
# in depth: restrict-webapp-child-ownership already refuses adoption and hand edits of
# the reserved labels, the two ways a foreign object could gain that membership.
apiVersion: policies.kyverno.io/v1
kind: ValidatingPolicy
metadata:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# KRO 0.9.2 uses ApplySet labels, not a WebApp ownerReference. Its apply path can
# adopt an existing unlabelled object. Check admission oldObject, not a prior GET,
# to refuse that collision and preserve ownership even across a stale read.
# KRO tracks WebApp children with ApplySet labels, not a WebApp ownerReference. Its
# apply path in 0.9.4 refuses only an object already labelled for another ApplySet; an
# existing unlabelled object is force-applied and gains the membership label, which
# adopts it (pkg/controller/instance/applyset/applyset.go). Check admission oldObject,
# not a prior GET, to refuse that collision and preserve ownership even across a stale
# read. Only KRO may set or change the reserved labels on these kinds, so no other
# writer can add or remove an object's membership.
apiVersion: policies.kyverno.io/v1
kind: ValidatingPolicy
metadata:
Expand Down
Loading