Skip to content

feat: redact secret key material in credential toString()#90

Merged
OmarAlJarrah merged 2 commits into
mainfrom
feat/redact-credential-tostring
Jun 16, 2026
Merged

feat: redact secret key material in credential toString()#90
OmarAlJarrah merged 2 commits into
mainfrom
feat/redact-credential-tostring

Conversation

@OmarAlJarrah

Copy link
Copy Markdown
Member

Summary

KeyCredential and NamedKeyCredential hold secret key material. They are plain classes (not data classes), so today they inherit Object's identity toString() and don't actually leak the secret — but they also have no explicit, safe string form. This adds redacting toString() overrides so the secret can never surface through logs, exception messages, or a debugger, and stays masked under any future change (e.g. a promotion to data class). This matches the existing redaction on BearerToken.

  • KeyCredentialKeyCredential(apiKey=***, headerName=…, prefix=…)
  • NamedKeyCredentialNamedKeyCredential(name=…, key=***)

Identity-equality semantics are unchanged (no equals/hashCode introduced). New tests assert the secret never appears while the mask and non-secret fields do. The now-declared toString() is reflected in the API snapshot.

Closes #47

KeyCredential and NamedKeyCredential hold secret key material in
plain fields. Any code path that stringified them — a log line, an
exception message, or a debugger view — could surface the raw secret.

Override toString() on both so the key is never rendered:
KeyCredential emits `apiKey=***` while keeping the non-secret
headerName and prefix, and NamedKeyCredential emits `key=***` while
keeping the non-secret name. This matches the existing redaction on
BearerToken.

The override is toString-only: these are reference types with
identity equality, and that behaviour is preserved (covered by tests).
Adding an explicit toString() surfaces it as a declared public member,
so the sdk-core API snapshot is regenerated accordingly.
The default-fields redaction test only asserted the secret was masked. Add an
assertion that the non-secret headerName (Authorization) is still rendered, so
the test pins both halves of the contract like the explicit-fields test does.
@OmarAlJarrah OmarAlJarrah merged commit 6ce5377 into main Jun 16, 2026
1 check passed
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.

Redact secrets in KeyCredential and NamedKeyCredential toString()

1 participant