Describe the bug
packages/apps/opensearch/templates/users.yaml renders a Secret named {{ $.Release.Name }}-user-{{ $username }} with the map key taken raw, and values.schema.json puts no propertyNames pattern on users, so the tail of that name is tenant-chosen and unconstrained. Application x with a user named http-server therefore writes opensearch-x-user-http-server, which is exactly the name application x-user writes for its HTTP server leaf. Both are Secrets in the same tenant namespace and both are Helm-owned, so the realistic outcome is the second release wedging rather than one release reading the other's key, but one of the two names carries a server private key.
The wedge is permanent rather than a race. users.yaml renders type: kubernetes.io/basic-auth and cert-manager writes kubernetes.io/tls, and a Secret's type is immutable on update, so whichever release arrives second can never bring the object to its own type. That is the difference from the older members of this family, -credentials and -admin-credentials, which collide as two Secrets of the same type and resolve as first writer wins. It is also the argument for constraining the users key rather than treating this as name hygiene.
The chart's own no-collision argument does not reach this. It holds between the chart's fixed suffixes, and the dot that separates the CA Secret from release names rests on application names being DNS-1035 labels. A users key is not a DNS label, so it can carry a dot of its own and neither defence applies.
Environment
- Cozystack main, 2026-09-10
- Any tenant that can create two OpenSearch applications whose names differ by a suffix that a users key can reproduce
To Reproduce
- Create an OpenSearch application named
x with users: {http-server: {...}}
- Create an OpenSearch application named
x-user with external: true, so cert-manager issues its HTTP server leaf
- Both releases target the Secret
opensearch-x-user-http-server in the same namespace
Expected behaviour
A users key cannot construct a Secret name the chart already owns for something else.
Actual behaviour
The name is reachable from tenant input, and the second release to reconcile fails on Secret ownership.
Additional context
Raised in review on #2682, where the call was to track it separately rather than grow that branch. The mechanism is documented in that branch at packages/apps/opensearch/templates/certmanager.yaml. The fix belongs on the users key rather than on the certificate suffixes: a propertyNames.pattern on users in values.schema.json plus the matching validation on the API map, with a render test pinning the rejection. Moving a certificate suffix instead only relocates the reachable name.
Checklist
Describe the bug
packages/apps/opensearch/templates/users.yamlrenders a Secret named{{ $.Release.Name }}-user-{{ $username }}with the map key taken raw, andvalues.schema.jsonputs nopropertyNamespattern onusers, so the tail of that name is tenant-chosen and unconstrained. Applicationxwith a user namedhttp-servertherefore writesopensearch-x-user-http-server, which is exactly the name applicationx-userwrites for its HTTP server leaf. Both are Secrets in the same tenant namespace and both are Helm-owned, so the realistic outcome is the second release wedging rather than one release reading the other's key, but one of the two names carries a server private key.The wedge is permanent rather than a race.
users.yamlrenderstype: kubernetes.io/basic-authand cert-manager writeskubernetes.io/tls, and a Secret's type is immutable on update, so whichever release arrives second can never bring the object to its own type. That is the difference from the older members of this family,-credentialsand-admin-credentials, which collide as two Secrets of the same type and resolve as first writer wins. It is also the argument for constraining theuserskey rather than treating this as name hygiene.The chart's own no-collision argument does not reach this. It holds between the chart's fixed suffixes, and the dot that separates the CA Secret from release names rests on application names being DNS-1035 labels. A users key is not a DNS label, so it can carry a dot of its own and neither defence applies.
Environment
To Reproduce
xwithusers: {http-server: {...}}x-userwithexternal: true, so cert-manager issues its HTTP server leafopensearch-x-user-http-serverin the same namespaceExpected behaviour
A users key cannot construct a Secret name the chart already owns for something else.
Actual behaviour
The name is reachable from tenant input, and the second release to reconcile fails on Secret ownership.
Additional context
Raised in review on #2682, where the call was to track it separately rather than grow that branch. The mechanism is documented in that branch at
packages/apps/opensearch/templates/certmanager.yaml. The fix belongs on the users key rather than on the certificate suffixes: apropertyNames.patternonusersinvalues.schema.jsonplus the matching validation on the API map, with a render test pinning the rejection. Moving a certificate suffix instead only relocates the reachable name.Checklist