Skip to content

fix(sdk): redact standalone keys and structured credentials - #322

Open
mldangelo-oai wants to merge 5 commits into
mainfrom
mdangelo/codex/harden-sdk-error-redaction-20260808
Open

fix(sdk): redact standalone keys and structured credentials#322
mldangelo-oai wants to merge 5 commits into
mainfrom
mdangelo/codex/harden-sdk-error-redaction-20260808

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • redact standalone and truncated PEM private keys without requiring a preceding assignment
  • redact all parameters in structured Authorization/Digest headers without discarding neighboring diagnostics
  • recognize URL-encoded API-key separators and plural credential/api-key fields
  • add focused regression tests for every newly covered credential shape

Verification

  • bun test --timeout 30000 tests-ts/errors.test.ts tests-ts/cli.test.ts tests-ts/multiscan.test.ts (167 passing; 2,025 assertions)
  • pnpm run types
  • prettier --check src/errors.ts tests-ts/errors.test.ts

Companion monorepo backport: https://github.com/openai/openai/pull/1262861

@github-actions github-actions Bot added the bug Something isn't working label Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dd61f0df2c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sdk/typescript/src/errors.ts Outdated
);
return redactQuotedCredentialValues(withoutPrivateKeys)
.replaceAll(
/(\b(?:authorization|auth)\b(?:\\?["'])?\s*[:=]\s*)([A-Za-z][A-Za-z0-9._~-]{0,63})((?:\s|%20|\+)+)(?=[A-Za-z_][A-Za-z0-9_-]{0,64}\s*=)[^\r\n]+/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Recognize username* before redacting Digest headers

When a valid Digest header starts with the extended username* parameter, this lookahead rejects the *, so the structured-header replacement is skipped. The following generic replacement then redacts only the first token; for example, Authorization: Digest username*=UTF-8''user, response="RSECRET" retains response="RSECRET" in the emitted error. Accept the full auth-param token syntax so the entire structured credential is redacted.

Useful? React with 👍 / 👎.

Comment thread sdk/typescript/src/errors.ts Outdated
);
return redactQuotedCredentialValues(withoutPrivateKeys)
.replaceAll(
/(\b(?:authorization|auth)\b(?:\\?["'])?\s*[:=]\s*)([A-Za-z][A-Za-z0-9._~-]{0,63})((?:\s|%20|\+)+)(?=[A-Za-z_][A-Za-z0-9_-]{0,64}\s*=)[^\r\n]+/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact structured values in suffixed authorization fields

This new structured-credential matcher only accepts the exact field names authorization and auth, although the subsequent credential matchers deliberately support names such as client_authorization_value and auth_token. When those fields contain parameterized credentials, the fallback redacts only the scheme or first value; for example, client_authorization_value=Digest username="example", response="LEAK_SECRET" leaves response="LEAK_SECRET" visible. Apply the structured-header handling to the same credential-field name forms supported by the other matchers.

Useful? React with 👍 / 👎.

Comment thread sdk/typescript/src/errors.ts Outdated
)
.replaceAll(
/(\b[A-Za-z0-9_-]{0,64}(?:api[_-]?key|access[_-]?key(?:[_-]?id)?|private[_-]?key|authorization|auth|token|secret|credential|signature|sig|password|passwd)(?:[_-][A-Za-z0-9_-]{1,64}|(?:value|data|token|secret|credential|password|header|field|id|key)[A-Za-z0-9_-]{0,48})?\b(?:\\?["'])?\s*[:=]\s*(?:\\?["'])?)(?!\[redacted\]|[A-Za-z][A-Za-z0-9._~-]{0,63}(?:\s|%20|\+)+\[redacted\])[^\s"',;}&\\\]]+/giu,
/(\b[A-Za-z0-9_-]{0,64}(?:api[_-]?keys?|access[_-]?key(?:[_-]?id)?|private[_-]?key|authorization|auth|token|secret|credentials?|signature|sig|password|passwd)(?:[_-][A-Za-z0-9_-]{1,64}|(?:value|data|token|secret|credential|password|header|field|id|key)[A-Za-z0-9_-]{0,48})?\b(?:\\?["'])?\s*[:=]\s*(?:\\?["'])?)(?!\[redacted\]|[A-Za-z][A-Za-z0-9._~-]{0,63}(?:\s|%20|\+)+\[redacted\])[^\s"',;}&\\\]]+/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact entire plural credential collections

Plural fields commonly hold arrays or objects, but the unquoted replacement stops at quotes, commas, and closing brackets. Consequently, inputs such as credentials=[alice:SECRET_ONE,bob:SECRET_TWO] become credentials=[redacted],bob:SECRET_TWO], and JSON such as {"credentials":["SECRET_ONE","SECRET_TWO"]} retains both secrets. The newly recognized plural fields need collection-aware or conservatively bounded redaction rather than redacting only the first fragment.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 552c382ae4

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 552c382ae4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sdk/typescript/src/errors.ts Outdated
);
return redactQuotedCredentialValues(withoutPrivateKeys)
.replaceAll(
/(\b(?:authorization|auth)\b(?:\\?["'])?\s*[:=]\s*)([A-Za-z][A-Za-z0-9._~-]{0,63})((?:\s|%20|\+)+)[A-Za-z_][A-Za-z0-9_-]{0,64}\s*=\s*(?:"[^"]*"|'[^']*'|[^\s,;]+)(?:\s*,\s*[A-Za-z_][A-Za-z0-9_-]{0,64}\s*=\s*(?:"[^"]*"|'[^']*'|[^\s,;]+))*/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle escaped quotes before ending authorization values

When a valid quoted authorization parameter contains an escaped delimiter, such as Authorization: Digest username="a\"b", response="SECRET", the "[^"]*" branch treats the escaped quote as the end of the value. Redaction therefore stops early and returns the remainder—including the following Digest response or signature—verbatim. Continue through quoted-pairs to the actual unescaped closing delimiter before replacing the complete parameter list.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8b9589bc3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sdk/typescript/src/errors.ts Outdated

function redactCredentialCollections(message: string): string {
const assignment =
/(\b[A-Za-z0-9_-]{0,64}(?:credentials|api[_-]?keys)\b(?:\\*["'])?\s*[:=]\s*)([\[{])/giu;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact collections under suffixed credential fields

The new collection helper still matches only names ending exactly in credentials or apiKeys, while the subsequent credential matchers explicitly recognize suffixed forms such as credentials_value and api_keys_data. For an input like credentials_value=["SECRET_ONE","SECRET_TWO"], the fallback replaces only [ and emits both secrets as credentials_value=[redacted]"SECRET_ONE","SECRET_TWO"]; extend this matcher to the same suffix forms before parsing the collection.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: e8b9589bc3

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf34227cb2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sdk/typescript/src/errors.ts Outdated
redactCredentialCollections(withoutPrivateKeys),
)
.replaceAll(
/(\b[A-Za-z0-9_-]{0,64}(?:authorization|auth)(?:[_-][A-Za-z0-9_-]{1,64}|(?:value|data|token|secret|credential|password|header|field|id|key)[A-Za-z0-9_-]{0,48})?\b(?:\\?["'])?\s*[:=]\s*)([A-Za-z][A-Za-z0-9.+~-]{0,63})((?:\s|%20|\+)+)[A-Za-z_*][A-Za-z0-9_.*-]{0,64}\s*=\s*(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+)(?:\s*,\s*[A-Za-z_*][A-Za-z0-9_.*-]{0,64}\s*=\s*(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+))*/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept full token syntax for authorization parameters

The updated matcher now handles username*, but it still requires the first auth-param name to match [A-Za-z_*][A-Za-z0-9_.*-]* rather than the full HTTP token syntax. When an extension scheme uses a valid parameter beginning with a digit or another permitted punctuation character, Authorization: Custom 0nonce=visible, response=SYNTHETIC_SECRET falls through and becomes Authorization: Custom [redacted], response=SYNTHETIC_SECRET, exposing the later credential. Match the complete token syntax for parameter names (and auth schemes) before applying the fallback.

Useful? React with 👍 / 👎.

Comment thread sdk/typescript/src/errors.ts Outdated
"$1[redacted]",
)
.replaceAll(
/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z0-9 ]*PRIVATE KEY-----|$)/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Redact OpenPGP private-key armor

When an error contains a standalone ASCII-armored OpenPGP private key, its standard -----BEGIN PGP PRIVATE KEY BLOCK----- label does not match because this expression requires the label to end immediately after PRIVATE KEY. The entire block, including its secret payload, is therefore returned unchanged by redactedErrorMessage; include the PRIVATE KEY BLOCK armor form in the standalone-key redaction.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: bf34227cb2

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2d786be76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

redactCredentialCollections(withoutPrivateKeys),
)
.replaceAll(
/(\b[A-Za-z0-9_-]{0,64}(?:authorization|auth)(?:[_-][A-Za-z0-9_-]{1,64}|(?:value|data|token|secret|credential|password|header|field|id|key)[A-Za-z0-9_-]{0,48})?\b(?:\\?["'])?\s*[:=]\s*)([A-Za-z0-9][A-Za-z0-9.+~-]{0,63})((?:\s|%20|\+)+)[!#$%&'*+.^_`|~0-9A-Za-z-]{1,65}\s*=\s*(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+)(?:\s*,\s*[!#$%&'*+.^_`|~0-9A-Za-z-]{1,65}\s*=\s*(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|[^\s,;]+))*/giu,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the auth-param name length ceiling

The updated matcher now accepts additional token punctuation, but the new {1,65} ceiling still rejects valid HTTP auth-param names longer than 65 characters. In that case the generic fallback redacts only the first fragment; for example, Authorization: Digest <66-character-name>=foo, response=SECRET becomes Authorization: Digest [redacted], response=SECRET. Remove the arbitrary token-length limit so later structured credential parameters cannot leak.

Useful? React with 👍 / 👎.

Comment on lines +59 to +63
if (quote !== undefined) {
if (character === "\\") position += 1;
else if (character === quote) quote = undefined;
} else if (character === '"' || character === "'") {
quote = character;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve JSON-stringified collection suffixes

When an error contains a JSON-stringified object with a credential collection, the quotes inside the encoded collection are backslash-escaped, but this scanner treats the first escaped quote as an opening structural quote. It therefore never recognizes the closing bracket and discards the remainder of the message; for example, {\"credentials\":[\"SECRET\"],\"safe\":\"visible\"} is reduced to {\"credentials\":"[redacted]", losing both valid JSON structure and the safe diagnostic fields. Account for escaped delimiters outside quote mode, including nested JSON-stringification levels.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: c2d786be76

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review August 8, 2026 07:17

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2d786be76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

function redactQuotedCredentialValues(message: string): string {
const assignment =
/(\b[A-Za-z0-9_-]{0,64}(?:api[_-]?key|access[_-]?key(?:[_-]?id)?|private[_-]?key|authorization|auth|token|secret|credential|signature|sig|password|passwd)(?:[_-][A-Za-z0-9_-]{1,64}|(?:value|data|token|secret|credential|password|header|field|id|key)[A-Za-z0-9_-]{0,48})?\b(?:\\*["'])?\s*[:=]\s*)(\\*)(["'])/giu;
/(\b[A-Za-z0-9_-]{0,64}(?:api[_-]?keys?|access[_-]?key(?:[_-]?id)?|private[_-]?key|authorization|auth|token|secret|credentials?|signature|sig|password|passwd)(?:[_-][A-Za-z0-9_-]{1,64}|(?:value|data|token|secret|credential|password|header|field|id|key)[A-Za-z0-9_-]{0,48})?\b(?:\\*["'])?\s*[:=]\s*)(\\*)(["'])/giu;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle even backslashes before plural-value quotes

When a newly supported quoted plural field ends in a literal backslash, its valid JSON representation has two backslashes before the closing quote, but the delimiter scanner only accepts a closing quote preceded by exactly openingSlashes backslashes. Thus {"credentials":"SYNTHETIC_SECRET\\\\","safe":"visible"} becomes the invalid {"credentials":"[redacted]"safe":"visible"}, while the equivalent plain-text assignment can discard the entire safe suffix. Determine whether the quote is escaped from the backslash parity rather than requiring an exact count.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: c2d786be76

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ianw-oai ianw-oai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should just remove this feature

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants