Repository navigation
Dato Agent: redact credentials from copied failure diagnostics - #161
roger-datocms merged 7 commits into
Conversation
Provider API keys, OAuth access/refresh tokens, PKCE verifiers and similar fields are replaced with [Redacted] (empty values are kept), and sk-* keys or Bearer tokens embedded in strings are scrubbed. Diagnostics are commonly pasted into issues and chats, so they must not carry live credentials. Co-authored-by: Cursor <cursoragent@cursor.com>
|
(Claude here [Opus 5.5]) TriageThe fix is still needed. On master ( Status
Review findings
Key matching ( RecommendationFix finding 1 before merge, because it is the leak that matters most in practice. Findings 2-4 are cheap and can go in the same commit. After that, merge, then close #159. |
…ey formats Copied diagnostics still leaked credentials through several paths: - Error message and stack went out raw. - Map entries skipped the key-based rule. - Query-string secrets (?access_token=, ?code=, ?key=) and api_key=… text were not matched. - Gemini (AIza…), Vercel AI Gateway (vck_…) and DatoCMS CMA tokens were not matched. Redact all of these, treat credentials/jwt/session/privateKey keys as sensitive, and use the plugin's existing "[redacted]" marker and 12-char sk- minimum. Harmless text such as "status code=401" is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
(I'm working on this one, adding a few more secrets to redact before we merge) |
Replace the secret-shape regexes with two structural guarantees: - Allowlist: diagnostics list the non-secret configuration fields explicitly (diagnosticConfiguration) and report API keys only as hasOpenAiApiKey/hasAnthropicApiKey. OAuth state is reduced to version, client registration and token metadata (diagnosticOAuthCredentials); the access token is never included. New secret fields can't leak by default. - Known-value masking: serializeDiagnostics takes the frame's live secrets (both provider keys and the OAuth access token) and replaces every exact occurrence anywhere in the payload, including error messages, stacks, URLs and map values, whatever their format. The credential-key list stays as a structural backstop for nested objects such as headers.authorization. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g values Known secrets are already masked. For anything else that looks like a credential, such as a key pasted into chat, "Copy diagnostics" now lists the candidates (last 4 characters, length and payload path, never the value) and lets the user choose which to redact. All start selected. Detection is generic, with no provider patterns: tokens of 20+ characters that mix letters and digits and have high entropy. DatoCMS IDs (isValidId from @datocms/cma-client-browser), canonical UUIDs, URL escapes and values under id/…Id/…Ids keys are skipped. With no candidates, copying works as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
registerTerminalFailure is a per-render closure, so its oauthCredentials could predate a token rotation while the turn used the newer token from oauthCredentialsRef. An error message echoing that token reached the clipboard unmasked. Also mask the live ref and the turn's mcpAccessToken/repairOauthAccessToken, with a regression test. Bump DIAGNOSTICS_SCHEMA_VERSION to 2: configuration and OAuth state now have an allowlisted shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The live review flagged the project name (claude-…-2026-11-03) and a host context fingerprint. Flag a token only if one of its -/_ segments mixes letters and digits, as keys do (sk-ant-api03-…) and slugs don't; treat fingerprint/hash/checksum/digest keys as identifiers. Keep each preview on one line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each candidate now has a visible "Redact" label, and a hint under the heading says ticked values are replaced with [redacted] in the copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I pushed a few followup fixes to this:
I didn't want to absorb a full security sweeper like Gitleaks into this plugin, so hopefully this is good enough for now. pr-161-walkthrough.mp4 |
Fixes #159.
What
serializeDiagnosticsnow redacts credentials and keeps the rest of the payload intact:[Redacted]. Matching ignores case and punctuation: suffixapikey,accesstoken,refreshtoken,secretorpassword; exacttoken,idtoken,codeverifier,authorization,bearerorcookie. Empty strings are kept, so a missing key is still visible. Numeric fields such asanthropicModelMaxOutputTokensare untouched.sk-…API keys andBearer …tokens embedded in any string are replaced.This covers
configuration.*ApiKey,activeApiKeyandoauthCredentials.token.accessTokenin the AgentFrame failure payload.Tests
diagnostics.test.ts: the deterministic-output test now expects redaction. New test covers provider keys, OAuth token/refresh/PKCE fields,mcpAccessTokenand embeddedBearer/sk-strings.AgentFrame.test.tsx: the copied diagnostics no longer contain the API key or OAuth token.npm run typecheck,npm run lint,npm test(952 passed).