Part of the audit remediation umbrella #67. Milestone 2. Severity: MEDIUM (security). Requirements: AUTH-8, AUTH-28, XCUT-16.
Current SDK behavior
Passwords in plain fields. BasicCredential and DigestCredential
(packages/core/src/auth/auth-step.ts:36-41,48-58) are structural interfaces with a public
password: string. ApiKeyCredential, NameKeyCredential and BearerToken in
credential.ts keep the secret in a #private field and override toString and
nodejs.util.inspect.custom. util.inspect(credentials) on an AuthCredentialSet prints
password: 'hunter2' beside ApiKeyCredential{key=***}. JSON.stringify serializes both
passwords. docs/sdk-documentation/auth.md:40-46 shows the raw-password shape directly above
the claim that a credential cannot leak into a log line by accident.
Replay guard checks two header names. After a 401, the auth step calls
guardReplayScheme (auth-step.ts:549-567) on the replacement request. The guard tests only
Authorization and Proxy-Authorization (:554-556). ApiKeyCredentialConfig.headerName
(:81) lets the step stamp any header. A challengeHook that returns a replacement on
http:// with X-Api-Key: SECRET is dispatched in clear text. No PlaintextCredentialError
is thrown.
Expected behavior
The SDK redacts every credential type in every string or diagnostic representation. The
Basic and Digest credentials do not expose the password as a plain property. The SDK refuses
to send a replay over plain HTTP when the replacement request carries any header the step
treats as a credential carrier.
Notes and leads
- Passwords: add
BasicCredential / DigestCredential classes (or createBasicCredential()
factories) with #password, toString, and the inspect override, matching credential.ts.
Accept them in AuthCredentialSet. Update auth.md. This is a public-shape change; it is
free before the first version bump (docs/first-release.md). Minor changeset for
@dexpace/core.
- Replay guard: simplest correct rule is "if the original request was guarded, run
requireHttps on the replacement, regardless of headers". Alternative: build the set of
credential-carrying names from the step's configuration and check each.
- AUTH-8 names bearer, API-key and name-key types only. Record the wider reading in the Phase
5c ledger section.
- Tests:
util.inspect and JSON.stringify on a full AuthCredentialSet contain no
password; a replay with an API-key header on http:// throws PlaintextCredentialError.
Add both to packages/core/src/auth/ and the API-key case to
tests/conformance/xcut/security-by-default.conformance.test.ts.
Part of the audit remediation umbrella #67. Milestone 2. Severity: MEDIUM (security). Requirements: AUTH-8, AUTH-28, XCUT-16.
Current SDK behavior
Passwords in plain fields.
BasicCredentialandDigestCredential(
packages/core/src/auth/auth-step.ts:36-41,48-58) are structural interfaces with a publicpassword: string.ApiKeyCredential,NameKeyCredentialandBearerTokenincredential.tskeep the secret in a#privatefield and overridetoStringandnodejs.util.inspect.custom.util.inspect(credentials)on anAuthCredentialSetprintspassword: 'hunter2'besideApiKeyCredential{key=***}.JSON.stringifyserializes bothpasswords.
docs/sdk-documentation/auth.md:40-46shows the raw-password shape directly abovethe claim that a credential cannot leak into a log line by accident.
Replay guard checks two header names. After a 401, the auth step calls
guardReplayScheme(auth-step.ts:549-567) on the replacement request. The guard tests onlyAuthorizationandProxy-Authorization(:554-556).ApiKeyCredentialConfig.headerName(
:81) lets the step stamp any header. AchallengeHookthat returns a replacement onhttp://withX-Api-Key: SECRETis dispatched in clear text. NoPlaintextCredentialErroris thrown.
Expected behavior
The SDK redacts every credential type in every string or diagnostic representation. The
Basic and Digest credentials do not expose the password as a plain property. The SDK refuses
to send a replay over plain HTTP when the replacement request carries any header the step
treats as a credential carrier.
Notes and leads
BasicCredential/DigestCredentialclasses (orcreateBasicCredential()factories) with
#password,toString, and the inspect override, matchingcredential.ts.Accept them in
AuthCredentialSet. Updateauth.md. This is a public-shape change; it isfree before the first version bump (
docs/first-release.md). Minor changeset for@dexpace/core.requireHttpson the replacement, regardless of headers". Alternative: build the set ofcredential-carrying names from the step's configuration and check each.
5c ledger section.
util.inspectandJSON.stringifyon a fullAuthCredentialSetcontain nopassword; a replay with an API-key header on
http://throwsPlaintextCredentialError.Add both to
packages/core/src/auth/and the API-key case totests/conformance/xcut/security-by-default.conformance.test.ts.