Skip to content

Keep your API keys out of the code Claude writes

When you build with Claude, the key goes into the app's settings, never into a file in the app. Ask Claude to read it from a named setting (say STRIPE_API_KEY), paste the real value into the host's settings once, and the code only ever contains the name. Secret scanning, which Haechy runs on every change, is the backstop for the times a key slips into a file anyway. If a key does leak, the first ten minutes go: replace the key at the provider, put the new one in your app's settings, then read the provider's usage log for calls you didn't make. Deleting the key from the code, or making the repository private, fixes nothing on its own.

Why this goes wrong so often

Claude writes what you ask for, and what you ask for is often "make it send the email" with a key pasted in the same message. The fastest way for code to work is to put the key in the code. It works, you move on, and the key sits in a file that gets saved, copied, committed or shared.

This is common enough to have numbers. GitGuardian, which sells leak detection, counted 28.65 million new hard-coded credentials in public GitHub commits in 2025, up 34% on the year before, and 1,275,105 leaked credentials tied to AI services, up 81% (The State of Secrets Sprawl 2026). The same report retested credentials it had confirmed as valid in 2022 and found more than 64% still valid in January 2026. Leaked keys tend to stay usable until a person revokes them.

Where the key goes instead

The pattern is the same on any host: the key lives in a setting outside the code, and the code reads it by name when it runs.

On Haechy you tell Claude the name and the value once. Claude stores it as an app setting, the app picks it up within seconds, and the value is never shown again: Haechy lists the names only. Settings are encrypted at rest. To change one, ask Claude to set it again, and to remove one, ask Claude to delete it.

A prompt that works:

Use the Resend API key from a setting called RESEND_API_KEY. Don't write the key into any file. I'll give you the value separately.

Then give the value in its own message. If you did paste a key into a chat with Claude, treat that key as one you may want to replace once the app is working, and start the replacement from the table below.

What secret scanning is, and what Haechy's version checks

Secret scanning means automatically searching code, and the history of its changes, for credentials such as API keys, passwords and tokens, so they can be revoked before someone misuses them. GitHub does this on every branch, free for public repositories. Its push protection can also stop a key from being pushed at all, and for individual users that is on by default for public repositories on GitHub.com. Private repositories need GitHub's paid Secret Protection (about secret scanning, about push protection).

Haechy runs its own check each time Claude is about to put a change online. It stops the change if the code contains a hard-coded key or a .env file, and it shows the file, the line and the fix, which is to move the value into a setting. It also checks packages and risky code, covered below the list. Here is exactly what it looks for in keys:

  • Key formats for AWS, Stripe live keys, Anthropic, OpenAI-style keys, GitHub, Slack tokens and webhooks, Google API keys, Twilio, SendGrid and Resend
  • PEM private keys
  • Database addresses with a password written into them
  • A general rule: a variable with a key-like name that is given a long, random-looking value
  • Any .env file

Example files such as .env.example are skipped for keys. It is a pattern check, so a key in a format that isn't on that list, or one hidden in a form it doesn't recognize, can get through. Beyond keys, the same check reads your lockfile and compares the packages with the OSV database of known vulnerabilities and malware, and looks for risky code such as request input run as a command or as SQL. It doesn't find every bug, and it isn't a code review or an audit. Treat it as a net under your habits. The habit is still to keep keys in settings.

Once the change is online, Haechy opens the home page and up to ten pages you name and reports what each answered. When the app's log shows a missing setting, it says so, which is how a forgotten RESEND_API_KEY can get caught before a colleague finds it. That second step tests whether pages load. It says nothing about security.

If a key leaks: the first ten minutes

Say you find the key in a public repository, a screenshot or a chat. Work in this order.

  1. Replace the key at the provider. The table below has the steps. Treat a key that has been public, even briefly, as one someone else may already have. If you can switch the app in a few minutes, create the new key, do step 2, then revoke the old key straight away. If the switch will take longer, or you already see calls you didn't make, revoke the old key first and accept a short outage. Anthropic and Resend both say to revoke a leaked key immediately.
  2. Put the new key in the app's settings. Ask Claude to set the setting again with the new value. Don't paste it into the code to "just test".
  3. Read the usage log for the old key. Look for calls you didn't make, and for spending that doesn't add up. Keep the old key's logs open until you've checked.
  4. Then tidy up. Remove the key from the code and rewrite what Claude generated to read it from a setting. Do it after steps 1 to 3, because the old key is still in the history of every copy.

Nobody will revoke the key for you in every case. GitHub revokes its own tokens (personal access tokens, OAuth tokens and GitHub App tokens) when they are pushed to a public repository or gist. Other providers take part in GitHub's partner program, and each decides for itself whether to revoke. Anthropic does: when GitHub finds a Claude API key in a public repository, Anthropic deactivates it and emails the owner. That covers public repositories only. Revoke it yourself either way.

Provider by provider

As of November 8, 2026. Each row links the provider's own page, because menus move.

Provider Where to revoke or rotate What to know Afterward
OpenAIAPI keys page. Create a replacement, update your app, then revoke the old key once the new one worksOpenAI suggests a project service account for the app rather than a personal key, and an expiry date on project keysUsage page shows calls per key. Keys made before December 20, 2023 show older usage as "Untracked" (OpenAI)
Anthropic (Claude API)Console, API keys, the three-dot menu on the key, "Delete API key"Anthropic says to revoke immediately if a key may be compromised. It also suggests replacing keys on a schedule, for example every 90 daysLogs and Usage pages. Spend limits help if your organization has custom rate limits. Auto-reload can allow high unexpected usage (Anthropic)
StripeAPI keys page, the menu on the key, "Rotate key", then pick when the old one expiresIn the Dashboard, old and new keys can both work for up to 7 days, which suits a planned rotation. For a leaked key, pick "Now". Stripe says to when a key is being abused, and a key that has been public may be. sk_ and rk_ keys must stay out of code. pk_ publishable keys are meant for the front end"View request logs" on the key shows its calls. Stripe suggests expiring an old key once its requests have been zero for hours or days; with a leaked key, don't wait that long. Stripe recommends restricted keys (Stripe)
Google CloudCredentials page. Rotating makes a new key with the same restrictions. Update every app, then delete the old keyA deleted key can be undeleted within 30 days. Google recommends API and application restrictions on every keyNo separate leak procedure on Google's page, so check your usage and billing yourself (Google)
GitHub personal access tokenProfile photo, Settings, Developer settings, Personal access tokens, then DeleteNo regenerate in place: make a new token, then delete the old one. GitHub removes tokens left unused for a yearGitHub revokes tokens pushed to public repositories on its own (GitHub)
TwilioConsole, Settings, Account settings, API keys and auth tokens, the key, "Delete this key"Keys are independent, so you can create a second one, switch the app, then delete the first. Auth tokens work differently and aren't covered hereDeleting a key revokes its permissions (Twilio)
ResendAPI keys pageResend keys never expire on their own. For a leaked one, Resend says delete it nowThe Logs page, filtered by API key, shows whether the new key is in use (Resend)
AWS access keysIAM console, Users, the user, Security credentials, Access keysMake a second key, update the app, check the old key's "Last used", deactivate it (reversible), confirm the app works, then delete it. A lost key can't be shown againThe Users list has an "Access key age" column to find your oldest keys (AWS)

Your provider isn't here? The order is the same almost everywhere: make a new key, switch the app to it, remove the old key, then read the log.

Habits that keep this from happening again

Give each app its own key, so one leak means one replacement. Prefer restricted or limited keys where the provider offers them (Stripe and Google both recommend this). Set an expiry when the provider lets you. Review the list of settings your app has now and then; Haechy shows the names, so you can spot one you no longer use and ask Claude to delete it.

If this is part of a wider question about building safely with Claude, the security page lists what Haechy does and doesn't do, and building for Haechy covers app settings and what the deploy check blocks. IT teams can read the page written for them. If you're deciding where to share a Claude-built app at all, see the safest way to share one with your team.

Haechy is an independent product of DT Global Ventures Ltd. It is not made, sponsored or endorsed by Anthropic. Claude is a trademark of Anthropic, PBC.