linode / linode/apl-core

Values export ("download values") leaves several secret fields unredacted

Open
#3,456 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

community on hold
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.