Summary
The values export produced by the console Download values feature (#1517) is named values-redacted-<timestamp>.yaml and masks most secrets as <redacted>, 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 <redacted>.
Fields NOT redacted (the bug)
-
users[].initialPassword — cleartext for every user, including platform admins. Never masked.
-
teamConfig.<team>.settings.password — inconsistent: teamConfig.admin.settings.password is <redacted>, but the same field on a non-admin team (e.g. teamConfig.<otherTeam>.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.
-
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
- Configure an instance with ≥1 non-admin team and ≥1 platform-admin user.
- Console → Download values.
- 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
Summary
The values export produced by the console Download values feature (#1517) is named
values-redacted-<timestamp>.yamland masks most secrets as<redacted>, but several secret-bearing fields pass through in cleartext. Because the-redactedfilename 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-*.yamlfrom 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<redacted>.Fields NOT redacted (the bug)
users[].initialPassword— cleartext for every user, including platform admins. Never masked.teamConfig.<team>.settings.password— inconsistent:teamConfig.admin.settings.passwordis<redacted>, but the same field on a non-admin team (e.g.teamConfig.<otherTeam>.settings.password) is cleartext. Strongly suggests the redaction path special-cases theadminteam (or the first team) rather than matching the field by shape, so every additional team's password slips through.obj.provider.linode.accessKeyId— cleartext. Its pairedsecretAccessKeyis redacted, but an access-key ID is half the credential and shouldn't be exposed either.Why it matters
initialPasswordonisPlatformAdmin: trueusers is a direct path to admin access if those passwords were not rotated after first login.settings.passwordinconsistency means the redaction gives false assurance: an operator who confirms theadminpassword 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[].initialPasswordandteamConfig.*.settings.password(all teams, not justadmin), and treatobj.provider.linode.accessKeyIdas 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
values-redacted-*.yamlforinitialPassword:, the non-admin team'ssettings.password:, andaccessKeyId:— all appear in cleartext.Environment: apl-core v4.14.1