Skip to content

security: widen and de-duplicate the secret-name redaction heuristic #384

Description

@codeforester

Problem

The secret-name heuristic that provides base-cli's defense-in-depth redaction matches only five
stems — token, password, secret, api[-_]?key, authorization — and that same list is
duplicated in three places that must be kept in sync by hand:

  • SECRET_KEY_RE (lib/python/base_cli/redaction.py:9), used by is_secret_key() for argv
    parameter names and inline key=value text;
  • _is_sensitive_key() (lib/python/base_cli/json_contracts.py:155-156), an inline
    re.search over the same alternation, used to redact JSON mapping keys;
  • _SENSITIVE_ASSIGNMENT (lib/python/base_cli/json_contracts.py:31-34), a third copy used to
    redact key: value text inside envelope strings.

Common credential names that operations and infrastructure CLIs actually use are not covered.

Verified evidence

Reviewed 2026-09-30 at a58ec109349fa3f3d03eae5b0de078b39ea361a2. is_secret_key() results:

Name Matched
token, password, secret, api_key, apikey, authorization yes
secret_access_key yes (contains secret)
passwd no
pwd no
credential, credentials no
private_key no
access_key no
bearer no
passphrase no
signature no
session_id no
cookie no
otp no

--access-key missing is notable: AWS-shaped CLIs pair --access-key-id with
--secret-access-key, and only the second is protected. --passwd/--pwd are conventional short
forms, and --private-key/--passphrase are standard for SSH and TLS material.

This is defense in depth, not the primary mechanism — sensitive=True, hide_input, and
sensitive_parameters are explicit and work correctly — and docs/json-contracts.md does state
the five stems. But the guarantee an adopter infers from "secret-looking parameter names are
protected automatically" is materially wider than what is implemented.

Proposal

  1. Extract one shared, commented pattern into a single module (redaction.py) and have both
    json_contracts.py call sites consume it. Three hand-synchronized copies of a security-relevant
    pattern is the underlying defect.
  2. Widen the stem list: add passwd, pwd, passphrase, credential, private[-_]?key,
    access[-_]?key, bearer, session, cookie, signature, otp, salt, client[-_]?secret
    (already covered by secret), auth[-_]?token (covered), sas, pem.
  3. Weigh false positives deliberately and record the reasoning: key alone is too broad
    (--key-file, --sort-key, --partition-key), auth alone is borderline. Redacting a
    non-secret in a diagnostic log is a much cheaper error than leaking a credential, but the
    decision should be written down, not implicit.
  4. Update docs/json-contracts.md and docs/security-threat-model.md with the final list and
    restate that the heuristic is a backstop, not a substitute for explicit marking.

Acceptance criteria

  • One pattern definition; no module contains a second copy of the stem alternation.
  • A property or table test asserts the full documented stem list matches in all three positions
    (argv parameter name, inline text, JSON key) and that named non-secrets such as --key-file,
    --sort-key, and --public-key do not match.
  • Docs list the exact stems and the false-positive policy.

Non-goals

  • Do not attempt value-shaped secret detection (entropy, provider prefixes) here.
  • Do not weaken or replace explicit sensitive=True marking.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

securitySecurity hardening or vulnerability work

Type

No type

Projects

  • Status
    In Progress

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions