Sealed-secret / existing secret support
For my clusters, I use gitops and sealed secrets to consistently represent the secrets in my cluster without exposing them or randomly generating them.
I am running v1.13.0 of the operator and a v16 postgresql db, on kubernetes 1.31.0. Notably I also have the configKubernetes.enable_owner_references=true option enabled for ArgoCD to be able to see the resources which contributes in part but wholly necessary.
My problem summary is that I cannot find a clean way to use an existing secret with a user definition for a given postgresql database:
- There appears to not be a way to reference an existing secret in v1.13.0 for a user's name and password.
- Alternatively, if I autogenerate a user then force replacement with an existing secret its list of owner references is emptied, and it now only references the postgresql CRD, along with requiring some manual intervention breaking automation. I would have expected that the owner reference would have been extended rather than replaced.
Are there any current ways to reference an existing secret for a database user's password in particular? I do not mind the lack of secret rotation.
I think its important to have this, and very surprising that it does not. Difficult to have repeatable IAC with race conditions introduced by autogen'd secrets you cant control the timing of.
Sounds like you just need a bit more imagination — and to think it through a little better 😉.
You need to create the sealed secret using the exact same format expected by the operator. That includes the keys username and password, and the labels cluster-name, application, and team.
If you set the right labels and secret keys, it'll work just fine.
Bear in mind that you need to match the secret name with your secret_name_template
secret_name_template a template for the name of the database user secrets generated by the operator. {namespace} is replaced with name of the namespace if enable_cross_namespace_secret is set, otherwise the secret is in cluster's namespace. {username} is replaced with name of the secret, {cluster} with the name of the cluster, {tprkind} with the kind of CRD (formerly known as TPR) and {tprgroup} with the group of the CRD. No other placeholders are allowed. The default is {namespace}.{username}.{cluster}.credentials.{tprkind}.{tprgroup}.
So, by default, if you didn't enable the cross_namespace_secret , the name your need is <username>.<cluster>.credentials.postgresql.acid.zalan.do . For example, if your user is "paco" and your cluster is "pastrami" i'll need to create the secret paco.pastrami.credentials.postgresql.acid.zalan.do
Inside the secret, you'll need:
username: paco
password: <your-password>
And don’t forget the required labels:
team: <your-team-id> # must match the team ID from your PostgreSQL manifest
cluster-name: pastrami # your actual cluster name
application: spilo
Even though i tried that it does not seem to work. I use external secret operator to create the secrets. External secrets add owner references to the k8 secrets created by them.
But it seems postgres operator does not like it even though enable_owner_references: false is set for postgres operator.
time="2025-06-18T17:23:53Z" level=debug msg="syncing secrets" cluster-name=studio12/postgres-cluster pkg=cluster time="2025-06-18T17:23:53Z" level=info msg="secret studio12/postgres.postgres-cred owner references do not match the current ones" cluster-name=studio12/postgres-cluster pkg=cluster time="2025-06-18T17:23:53Z" level=info msg="secret studio12/standby.postgres-cred owner references do not match the current ones" cluster-name=studio12/postgres-cluster pkg=cluster
I can create a normal k8 secret and avoid above error but then i will have to create it outside external secrets operator. A fix will be great if postgres operator does not delete the existing secret if they follow the secret template and labels.
Also, i think there should be an option to use existing secret for any new postgres user instead postgres operator creates them for us.