Values export ("download values") leaves several secret fields unredacted
Nobody has claimed this yet.
- Dominant language
- Go Template
- Stars
- 2.3k
- Forks
- 186
- Avg merge
- 3d 11h
- Merged PRs (30d)
- 66
Description
### Summary
The values export produced by the console **Download values** feature (#1517) is named `values-redacted-.yaml` and masks most secrets as ``, but several secret-bearing fields pass through in **cleartext**. Because the `-redacted` filename signals the file is safe to share, these leak in practice — they get pasted into tickets, chats, and screen-shares on the assumption that redaction was complete.
Verified against an exported `values-redacted-*.yaml` from an apl-core v4.14.1 instance. No values are reproduced here.
### Fields redacted correctly (for contrast)
`otomi.adminPassword`, `kms.sops.age.privateKey`, `apps.cert-manager.customRootCA{,Key}`, `apps.harbor.*` secrets, `apps.keycloak.idp.clientSecret`, `apps.loki.adminPassword`, `apps.oauth2-proxy.config.cookieSecret`, `apps.gitea.*Password`, `obj.provider.linode.secretAccessKey`, etc. — all ``.
### Fields NOT redacted (the bug)
1. **`users[].initialPassword`** — cleartext for every user, including platform admins. Never masked.
2. **`teamConfig..settings.password`** — **inconsistent**: `teamConfig.admin.settings.password` is ``, but the same field on a non-admin team (e.g. `teamConfig..settings.password`) is cleartext. Strongly suggests the redaction path special-cases the `admin` team (or the first team) rather than matching the field by shape, so every additional team's password slips through.
3. **`obj.provider.linode.accessKeyId`** — cleartext. Its paired `secretAccessKey` *is* redacted, but an access-key ID is half the credential and shouldn't be exposed either.
### Why it matters
- `initialPassword` on `isPlatformAdmin: true` users is a direct path to admin access if those passwords were not rotated after first login.
- The per-team `settings.password` inconsistency means the redaction gives false assurance: an operator who confirms the `admin` password is masked reasonably assumes all of them are.
### Suggested fix
Redact by **field identity across all list/map entries** rather than by fixed top-level paths — apply the same masking to `users[].initialPassword` and `teamConfig.*.settings.password` (all teams, not just `admin`), and treat `obj.provider.linode.accessKeyId` as sensitive alongside its secret key. A denylist keyed on leaf names (`password`, `initialPassword`, `accessKeyId`, `secret*`, `*Key`, …) applied recursively would close all three at once and be robust to new teams/users.
### Repro
1. Configure an instance with ≥1 non-admin team and ≥1 platform-admin user.
2. Console → **Download values**.
3. Grep the resulting `values-redacted-*.yaml` for `initialPassword:`, the non-admin team's `settings.password:`, and `accessKeyId:` — all appear in cleartext.
Environment: apl-core v4.14.1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the console's Download values export and locate the redaction logic by searching for values-redacted-*.yaml and the affected field names. Reproduce with a non-admin team and platform-admin user, then verify the exported YAML masks all listed fields while preserving the redactions already reported as correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- yaml
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100