Repository navigation
bug(mongodb): dashboard shows no usable MongoDB credentials on fresh install #2678
Description
Describe the bug
After creating a MongoDB.apps.cozystack.io resource and opening the instance in the Cozystack dashboard, the Secrets tab does not present a usable password to the user. Two distinct defects combine to produce this:
- The
databaseAdminsystem credentials Secret (<release>-credentials) is rendered with emptypasswordandurion first install. - Per-user credentials Secrets (
<release>-user-<username>) generated for entries in.Values.usersare not exposed to the dashboard at all — the dashboardRoledoes not grantget/list/watchon them.
So if a user defines users.testuser: {}, the dashboard shows them either:
- a
databaseAdminentry with an empty password (defect 1), and - no
testusercredentials at all (defect 2).
Defect 1 self-heals after a subsequent helm upgrade (flux reconcile helmrelease --force is enough). Defect 2 persists until the chart is changed — the dashboard cannot see the Secret regardless of its contents.
Defect 1 — <release>-credentials rendered with empty password/uri on first install
The chart template packages/apps/mongodb/templates/credentials.yaml reads the admin password via helm lookup of the operator-managed Secret internal-<release>-users:
{{- $operatorSecret := lookup "v1" "Secret" .Release.Namespace (printf "internal-%s-users" .Release.Name) }}
{{- $password := "" }}
{{- if and $operatorSecret (hasKey $operatorSecret.data "MONGODB_DATABASE_ADMIN_PASSWORD") }}
{{- $password = index $operatorSecret.data "MONGODB_DATABASE_ADMIN_PASSWORD" | b64dec }}
{{- end }}
On first install the lookup target does not yet exist — Percona Server MongoDB operator creates it asynchronously — so the lookup returns nil and the dashboard Secret is rendered with empty fields. There is an in-tree comment acknowledging this:
# Note: On first install, password/uri will be empty until operator creates the secret.
# Run 'helm upgrade' after MongoDB is ready to populate credentials.
This is the same class of problem tracked in #1942 (Helm lookup is unreliable for cross-controller secret resolution); this issue is the concrete MongoDB symptom.
Defect 2 — per-user Secrets are invisible to the dashboard
packages/apps/mongodb/templates/user-secrets.yaml generates one Secret per user listed under .Values.users:
{{- range $username, $user := .Values.users }}
apiVersion: v1
kind: Secret
metadata:
name: {{ $.Release.Name }}-user-{{ $username }}
type: Opaque
stringData:
password: ...
{{- end }}
These Secrets are then referenced by the Percona PerconaServerMongoDB CR through passwordSecretRef, which requires one Secret per user. The per-user Secret design is therefore necessary for the operator.
However, packages/apps/mongodb/templates/dashboard-resourcemap.yaml only grants the dashboard read access to a single Secret name:
- apiGroups: [""]
resources: [secrets]
resourceNames:
- {{ .Release.Name }}-credentials
verbs: ["get", "list", "watch"]No -user-<username> Secrets are listed, so the dashboard cannot show those passwords to the tenant. Verified empirically:
$ kubectl auth can-i --as=system:serviceaccount:tenant-root:tenant-root \
--namespace tenant-root get secret/mongodb-bug-demo-credentials
yes
$ kubectl auth can-i --as=system:serviceaccount:tenant-root:tenant-root \
--namespace tenant-root get secret/mongodb-bug-demo-user-testuser
no
For comparison, the Postgres chart sidesteps this by writing all per-user passwords as separate keys of the single <release>-credentials Secret (see packages/apps/postgres/templates/init-script.yaml); the dashboard Role covers them with the existing single resourceNames entry. MongoDB cannot fold per-user passwords into one Secret because Percona's CR requires passwordSecretRef.name per user — so the fix has to be on the RBAC / dashboard mapping side, not by changing the Secret layout.
Environment
- Cozystack version: built from
main(HelmChart[email protected]+e988b8517e6d) - Provider: on-prem test cluster
To Reproduce
-
Create a
MongoDB.apps.cozystack.ioresource in a tenant namespace:apiVersion: apps.cozystack.io/v1alpha1 kind: MongoDB metadata: name: bug-demo namespace: tenant-root spec: replicas: 1 resourcesPreset: t1.nano size: 1Gi users: testuser: {} databases: testdb: roles: admin: [testuser]
-
Wait until the HelmRelease reports
InstallSucceeded(~15-30 seconds). -
Inspect the dashboard credentials Secret and the per-user Secret:
kubectl --namespace tenant-root get secret mongodb-bug-demo-credentials \ --output json | jq '.data | map_values(@base64d)' kubectl --namespace tenant-root get secret mongodb-bug-demo-user-testuser \ --output json | jq '.data | map_values(@base64d)' -
Open the MongoDB instance in the dashboard and check the Secrets tab.
Expected behaviour
mongodb-<release>-credentialsshould contain a non-emptypasswordand a fully-formedurifrom the moment the install completes.- Per-user Secrets created for entries in
.Values.usersshould be visible in the dashboard so tenants can retrieve the passwords for the users they declared.
Actual behaviour
Right after install:
// mongodb-bug-demo-credentials (visible to dashboard, empty)
{
"host": "mongodb-bug-demo-rs0.tenant-root.svc.cozy.local",
"password": "",
"port": "27017",
"uri": "",
"username": "databaseAdmin"
}
// mongodb-bug-demo-user-testuser (NOT visible to dashboard, populated)
{
"password": "tbQAoctxmnbn6Usn"
}The operator-managed internal-mongodb-bug-demo-users Secret already contains a valid MONGODB_DATABASE_ADMIN_PASSWORD at this point — the chart simply rendered before that Secret was created.
A forced HelmRelease reconcile repopulates the dashboard Secret (defect 1 only):
flux --namespace tenant-root reconcile helmrelease mongodb-bug-demo --force
After that:
{
"host": "mongodb-bug-demo-rs0.tenant-root.svc.cozy.local",
"password": "<actual>",
"port": "27017",
"uri": "mongodb://databaseAdmin:<actual>@mongodb-bug-demo-rs0.tenant-root.svc.cozy.local:27017/admin?replicaSet=rs0",
"username": "databaseAdmin"
}The default spec.interval: 5m0s on the HelmRelease means natural reconciliation may eventually run helm upgrade and fix defect 1, but it leaves the dashboard broken for at least one reconcile cycle. Defect 2 is unaffected by reconciles.
Logs
helmrelease.helm.toolkit.fluxcd.io/mongodb-bug-demo 60s True Helm install succeeded for release tenant-root/mongodb-bug-demo.v1 with chart [email protected]+e988b8517e6d
Screenshots
Dashboard Secrets tab renders password and uri cells empty for databaseAdmin, and testuser is missing from the list entirely while it is defined in the instance's users: values.
Additional context
- Affected files:
packages/apps/mongodb/templates/credentials.yaml,packages/apps/mongodb/templates/dashboard-resourcemap.yaml,packages/apps/mongodb/templates/user-secrets.yaml - Defect 1 root cause is the same as feat: Replace Helm lookup with OpenBao + ESO + Operator architecture #1942 (Helm
lookuprace vs operator-created Secrets). - Other DB charts (mysql, postgres, mariadb, redis, …) that use the same
lookup-on-operator-secret pattern may share defect 1 — worth a sweep. - Defect 2 (per-user Secrets invisible to dashboard) likely affects any chart that creates Secrets outside
<release>-credentialsbut still wants the dashboard to display them. A quick grep acrosspackages/apps/*/templates/dashboard-resourcemap.yamlshows every chart hard-codes a single Secret name inresourceNames— worth checking which of them have per-user or per-resource Secrets that are similarly hidden. - Possible local fixes (not selected here, deferred to maintainer discussion):
- Defect 1: drop
<release>-credentialsand map dashboard fields directly frominternal-<release>-userswith key remapping; or add a post-install Job that waits for the operator Secret and patches the dashboard Secret; or move toExternalSecretonce feat: Replace Helm lookup with OpenBao + ESO + Operator architecture #1942 lands. - Defect 2: extend the dashboard
Roleto include<release>-user-<username>Secret names for each declared user; or label per-user Secrets and grant the dashboard a separate list+watch with a labelSelector-based filter on the client side; or change the architecture to store user passwords as keys of<release>-credentials(incompatible with Percona'spasswordSecretRefrequirement, would need an extra controller to fan them back out).
- Defect 1: drop
Checklist
- I have checked the documentation
- I have searched for similar issues
- I have included all required information
- I have provided clear steps to reproduce
- I have included relevant logs
Activity
dosubot commentedon May 19, 2026
Good bug report — both defects are confirmed and well-characterized. Here's some additional context from the codebase that may help the discussion:
On Defect 1 (empty credentials on first install):
Interestingly, the Redis and MariaDB charts already avoid this exact race by generating a random fallback password when the operator secret doesn't exist yet, rather than leaving it empty [1] [2]. MongoDB could adopt the same pattern: generate a random password on first install, then on subsequent reconciles pick up the operator-managed one from
internal-<release>-users. This would give immediate usability without breaking the operator flow.The broader architectural fix (replacing all
lookup-based patterns with OpenBao + External Secrets Operator) is tracked in #1942 [3], but that issue was marked stale on 2026-05-02 with no concrete implementation timeline yet — so a local fix incredentials.yamlis likely the pragmatic path for now.On Defect 2 (per-user secrets invisible to dashboard):
The dashboard resource map hard-codes a single
resourceNamesentry across all DB charts [4]. PostgreSQL avoids this by consolidating all user passwords as keys within the single<release>-credentialssecret [5], but as you noted, that's incompatible with Percona'spasswordSecretRefrequirement.The simplest fix would be to dynamically extend the
resourceNameslist indashboard-resourcemap.yamlby ranging over.Values.users:This keeps the explicit-allow RBAC model while making per-user secrets visible without any architectural changes.
Sweep across other charts:
A quick look confirms every chart in
packages/apps/*/templates/dashboard-resourcemap.yamlhard-codes a single secret name [6]. Currently MongoDB is the only one generating per-user secrets as separate Secret objects, so Defect 2 appears MongoDB-specific for now.To reply, just mention @dosu.
Share context across your team and agents. Try Dosu.