Skip to content

fix(redact): detect modern OpenAI keys (sk-proj-/sk-svcacct-/sk-admin- with -/_ body)#1867

Open
jbetala7 wants to merge 1 commit into
garrytan:mainfrom
jbetala7:fix/openai-key-separators
Open

fix(redact): detect modern OpenAI keys (sk-proj-/sk-svcacct-/sk-admin- with -/_ body)#1867
jbetala7 wants to merge 1 commit into
garrytan:mainfrom
jbetala7:fix/openai-key-separators

Conversation

@jbetala7
Copy link
Copy Markdown
Contributor

@jbetala7 jbetala7 commented Jun 4, 2026

Problem

lib/redact-patterns.ts openai.key is HIGH tier (block), but it only matches a contiguous alphanumeric body:

regex: /\b(sk-(?:proj-)?[A-Za-z0-9]{32,})\b/,

Modern OpenAI keys aren't pure-alphanumeric. Project / service-account / admin keys (sk-proj-, sk-svcacct-, sk-admin-) use a base64url-style body containing - and _ — the same charset gitleaks / trufflehog / GitHub secret scanning use for OpenAI. [A-Za-z0-9]{32,} stops at the first separator, never reaches 32 chars, and the scan returns no finding at all: a genuinely-secret HIGH credential fails open through the redaction gate behind /spec, /ship, /cso, and /document-*.

The sibling anthropic.key in the same file already permits separators (sk-ant-[A-Za-z0-9_\-]{20,}); openai.key is the inconsistent one.

Repro on main (c43c850)

lib/redact-engine scan() of realistic prefixed keys:

MISSED   sk-proj-Ab12_Cd34-Ef56Gh78Ij90Kl12Mn34Op56Qr78St90Uv   -> findings: NONE
MISSED   sk-svcacct-abc_def-ghijklmnopqrstuvwxyz0123456789ABCDEF -> findings: NONE
DETECTED sk-proj-aaaa…(40 contiguous — the only shape the suite covered)

test/redact-engine.test.ts only exercised "sk-proj-" + "a".repeat(40), so the gap was untested.

Root cause

The body character class excludes -/_, which real modern keys contain.

Fix

Widen the body charset to [A-Za-z0-9_\-] only on the prefixed form, and keep the bare sk- legacy path narrow (alnum) so it doesn't start matching kebab/snake identifiers that begin with sk-:

regex: /\b(sk-(?:proj|svcacct|admin)-[A-Za-z0-9_\-]{32,}|sk-[A-Za-z0-9]{32,})\b/,

Single bounded quantifier per alternative — linear-time, passes redact-pattern-lint. No tier/visibility/engine changes.

Testing

  • New regression test asserts the three prefixed separator forms now flag openai.key, the legacy bare sk- form still flags, and a short sk- kebab identifier does not (FP guard).
  • bun test test/redact-engine.test.ts test/redact-pattern-lint.test.ts test/redact-engine-autoredact.test.ts → 101 pass, 0 fail.
  • bun test test/redact-doc-resolver.test.ts test/redact-prepush-hook.test.ts test/gstack-redact-cli.test.ts → 30 pass, 0 fail (description change is doc-safe).

Fixes #1868

🤖 Generated with Claude Code

The HIGH-tier `openai.key` pattern required a contiguous [A-Za-z0-9]
run right after the prefix, so real `sk-proj-`/`sk-svcacct-`/`sk-admin-`
keys (base64url body with `-` and `_`) produced no finding at all — a
genuinely-secret credential failing OPEN past the redaction gate used by
/spec, /ship, /cso, and /document-*. The sibling `anthropic.key` pattern
already allows separators.

Widen the body charset to [A-Za-z0-9_-] only on the prefixed form; the
bare `sk-` legacy path keeps its narrow alnum match so it does not start
matching kebab/snake identifiers that begin with `sk-`. Linear-time,
passes redact-pattern-lint. +regression test for the separator forms.

Fixes garrytan#1866

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@trunk-io
Copy link
Copy Markdown

trunk-io Bot commented Jun 4, 2026

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

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.

gstack-redact: openai.key misses modern sk-proj-/sk-svcacct-/sk-admin- keys (separators in body) — HIGH credential fails open

1 participant