tenantToSecret (pkg/registry/core/tenantsecret/rest.go:117-119) copies every label from the request into the Secret it writes, with no filtering:
for k, v := range ts.Labels {
out.Labels[k] = v
}
The registry implements Create, Update and Delete (:219, :334, :382), so the write path is real. What keeps this inert today is that tenant roles grant only get/list/watch on tenantsecrets.
That read-only posture lives in a different package (packages/system/cozystack-basics clusterroles), and the labels in question now decide visibility. internal.cozystack.io/tenantresource is what the aggregated API surfaces on, and internal.cozystack.io/tenant-ca is what the per-app ResourceDefinitions select on. Postgres already ships that selector on main, and #2814 converges more engines onto the same label, so the number of definitions keying off a caller-suppliable label is growing.
The moment any principal gains create on this API, a caller can stamp both labels on a Secret of their choosing.
A deny-list on internal.cozystack.io/* keys in tenantToSecret is the cheap fix, and it is worth having in place before more engines depend on the label. Found while converting qdrant (#3341).
tenantToSecret(pkg/registry/core/tenantsecret/rest.go:117-119) copies every label from the request into the Secret it writes, with no filtering:The registry implements
Create,UpdateandDelete(:219,:334,:382), so the write path is real. What keeps this inert today is that tenant roles grant onlyget/list/watchontenantsecrets.That read-only posture lives in a different package (
packages/system/cozystack-basicsclusterroles), and the labels in question now decide visibility.internal.cozystack.io/tenantresourceis what the aggregated API surfaces on, andinternal.cozystack.io/tenant-cais what the per-app ResourceDefinitions select on. Postgres already ships that selector onmain, and #2814 converges more engines onto the same label, so the number of definitions keying off a caller-suppliable label is growing.The moment any principal gains
createon this API, a caller can stamp both labels on a Secret of their choosing.A deny-list on
internal.cozystack.io/*keys intenantToSecretis the cheap fix, and it is worth having in place before more engines depend on the label. Found while converting qdrant (#3341).