How do I remove API keys and secrets from code before AI?

Developers paste code into AI assistants to debug, explain, refactor, or write tests. The risky part is not only the source code. Logs, stack traces, .env files, deployment config, headers, database URLs, and screenshots can contain live secrets and internal infrastructure details. Credentials leak more easily than most people expect — GitGuardian detected over 28 million secrets exposed in public code in 2025 alone.

AI tools can be useful for debugging without seeing the actual credential. The model usually needs the error shape, code structure, library version, and expected behavior. It does not need a real token.

Replace secrets with precise placeholders

Use placeholders that preserve the role of each value:

Sensitive valuePlaceholder
sk-... or cloud API key[API_KEY]
Database connection string[DATABASE_URL]
Bearer token or JWT[ACCESS_TOKEN]
Private key block[PRIVATE_KEY]
Internal hostname[INTERNAL_HOST]
Customer identifier[CUSTOMER_ID]
Repository or project codename[PROJECT_NAME]

This keeps the prompt useful. For example, “authorization fails when [ACCESS_TOKEN] is passed to [INTERNAL_API]” is enough for many debugging tasks.

AI Prompt Privacy Checker can automatically scan pasted text for common secrets, emails, IDs, and tokens before you send the prompt, then lets you review, restore, or manually label anything missed. For the wider list of what to keep out of prompts, see what not to paste into AI prompts.

Developer log and API-key checklist

Use this checklist before pasting code, logs, stack traces, config, or screenshots into an AI assistant. It is designed for the practical task people search for: remove API key before asking AI and sanitize logs before AI debugging.

Source Look for Safe replacement Keep for debugging
Application logs Bearer tokens, API keys, session IDs, cookies, request bodies, account IDs, customer emails, IP addresses, internal URLs, and full payloads. [ACCESS_TOKEN], [API_KEY], [SESSION_ID], [CUSTOMER_ID], [INTERNAL_URL]. Error code, sanitized endpoint path, timestamp range, framework version, retry count, and the smallest relevant stack frame.
Stack traces Usernames in file paths, project codenames, repository names, internal package names, tenant IDs, request IDs, and private hostnames. [USER_PATH], [PROJECT], [PACKAGE], [TENANT_ID], [INTERNAL_HOST]. Exception type, sanitized file names if needed, line numbers, function names, and the call sequence around the failure.
.env and config files Database URLs, private keys, OAuth client secrets, cloud credentials, webhook secrets, signing keys, SMTP passwords, and service account JSON. [DATABASE_URL], [PRIVATE_KEY], [OAUTH_SECRET], [WEBHOOK_SECRET], [SERVICE_ACCOUNT]. Variable names, expected format, environment type, and non-secret flags that affect the bug.
HTTP examples Authorization headers, cookies, CSRF tokens, customer IDs, query strings, internal domains, signed URLs, and real request bodies. Authorization: Bearer [ACCESS_TOKEN], Cookie: [SESSION_COOKIE], https://[INTERNAL_HOST]/.... HTTP method, sanitized path, status code, response shape, and safe sample payload fields.
Code snippets Inline tokens, hardcoded passwords, private repo URLs, comments naming customers, internal feature flags, and real test fixtures. [API_KEY], [PASSWORD], [PRIVATE_REPO], [CLIENT], [FEATURE_FLAG]. The failing function, types, validation rules, library versions, and sanitized sample input.
Screenshots Terminal prompts, usernames, shell history, browser tabs, dashboard URLs, visible tokens, customer records, and account names. Blackout boxes over visible secrets with Screenshot Redactor. The visible error message, UI state, chart shape, or command output that explains the issue.

Before and after: sanitized debug log

Here is a realistic example of a log that should not be pasted into AI as-is:

2026-06-29T10:18:42Z ERROR checkout failed
tenant=acme-prod [email protected] account_id=ACC-99821
POST https://billing.internal.acme.local/v1/charges
Authorization: Bearer sk_live_51Nx-example-secret
Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6...
DATABASE_URL=postgres://billing_app:p@[email protected]:5432/billing
error=PaymentProviderTimeout request_id=req_8f1a9c stack=src/payments/stripe.ts:184

The AI does not need the real account, token, cookie, database password, hostname, or customer email. It needs the error shape and the sanitized context:

2026-06-29T10:18:42Z ERROR checkout failed
tenant=[TENANT] customer_email=[EMAIL] account_id=[ACCOUNT_ID]
POST https://[INTERNAL_HOST]/v1/charges
Authorization: Bearer [API_KEY]
Cookie: session=[SESSION_COOKIE]
DATABASE_URL=[DATABASE_URL]
error=PaymentProviderTimeout request_id=[REQUEST_ID] stack=src/payments/[PAYMENT_PROVIDER].ts:184

Now the prompt can ask a useful question without exposing working credentials:

This checkout request times out after 30 seconds. The sanitized log is below.
Runtime: Node 22. Payment SDK: v14. The retry count is 3.
What failure paths should I check, and how can I improve timeout handling?

Keep the minimum debugging context

A safe debugging prompt usually needs:

  • The smallest relevant code snippet.
  • The sanitized error message.
  • Library, runtime, and framework versions.
  • The expected behavior.
  • What you already tried.
  • A fake but structurally similar input example.

Avoid pasting full repositories, full logs, production .env files, customer payloads, or screenshots of admin dashboards unless they are truly required and cleaned first.

Screenshots and logs need separate review

Terminal screenshots can reveal usernames, paths, hostnames, repository names, tokens, branch names, and internal URLs. Logs can include headers, cookies, request bodies, and account IDs.

If the sensitive detail is visible in pixels, use Screenshot Redactor. If the detail is in text, sanitize it before pasting. If you are attaching a file, inspect it first with Metadata Inspector.

Rotate if a secret was already shared

If a working credential was pasted into an AI assistant, do not rely on deletion. Revoke or rotate it. Then search the codebase, CI variables, logs, and docs for copies of the same secret.

The long-term habit is to create a sanitized reproduction before asking AI. That makes the prompt clearer and keeps access-bearing values out of systems that do not need them.