Skip to content

Improve credential lifecycle and log hygiene - #1054

Open
EhabY wants to merge 8 commits into
mainfrom
fix/credential-log-hygiene
Open

Improve credential lifecycle and log hygiene#1054
EhabY wants to merge 8 commits into
mainfrom
fix/credential-log-hygiene

Conversation

@EhabY

@EhabY EhabY commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Review priority: 7/10. Independent hygiene fixes, one logical change per commit.
Diff: production +364/-162, tests +427/-33

Small, independent hardening changes around credential handling and what ends up in logs.

  • Header command: parse errors reference the offending line by number instead of echoing command output, and command execution no longer logs the command string or its stdout/stderr. Failures log the exit code only.
  • HTTP logging: header redaction is case-insensitive and covers the standard credential-bearing headers (Authorization, Cookie, Set-Cookie, X-Api-Key, Coder-Session-Token, Proxy-Authorization) plus every header applied by the configured header command. Known credential fields (access_token, refresh_token, client_secret, code, code_verifier, id_token, password, token) are redacted from logged bodies on all paths, including JSON and form-encoded strings. Redaction is copy-on-write, and log serialization is bounded in depth and length.
  • Logout: OAuth refresh and access tokens are revoked at the server (best-effort, one request pipeline for both), and logout reports incomplete credential cleanup with a retry hint instead of unconditional success. Revocation is wired to logout only; deployment switch deliberately keeps credentials for switching back.
  • Support bundle: a modal dialog lists the collected data categories before the bundle is created. Previously the CLI's own warning was suppressed with --yes and nothing was shown in its place.
  • Migration cleanup: legacy file-based url/session credentials are deleted after migration into secret storage instead of being left on disk. The migration logic now lives in src/remote/migration.ts.

Each change ships with unit tests. No settings or command surface changes beyond the new dialog.

@EhabY EhabY self-assigned this Jul 30, 2026
Consolidate OAuth revocation into a single revokeTokens() operation
(one discovery fetch and client instead of two) and drop the now-unused
revokeRefreshToken(). Replace the per-store CredentialClearResult with a
boolean since the only consumer checks overall success and the store
lists were fabricated on cancel/error paths; the failing store remains
in the logs. Narrow buildExtraLogs to take headerCommandKeys directly.

Also DRY the new tests: shared loggedOutput() helper for scanning mock
logger output, merged duplicate header-redaction cases, and simpler
rejection/message assertions.
@EhabY
EhabY force-pushed the fix/credential-log-hygiene branch from 3f7e1df to 5710189 Compare July 30, 2026 17:34
Type the sensitive-name sets as ReadonlySet<Lowercase<string>> with a
shared lowercase() helper so wrong-cased entries fail to compile, and
make body redaction copy-on-write: clean bodies (the common case) pass
through without allocation and clean strings are returned as-is after a
single parse.

Flatten revokeTokens into one operation with a token loop, extract the
session-auth migration out of Remote into src/remote/migration.ts so its
test needs no Remote or ServiceContainer stubbing, and tighten the new
user-facing messages.

Tests: MockUserInteraction now records dialog options and backs the
support-bundle disclosure tests, redaction tests assert positives before
one collapsed negative, and the migration test is renamed to match the
extracted module.
@EhabY
EhabY force-pushed the fix/credential-log-hygiene branch from 3e47996 to 2f70bf1 Compare July 30, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant