How to Check for Exposed API Keys

How-To Guide

How to Check for Exposed API Keys

Find leaked secrets before attackers do

TL;DR

TL;DR: Search your codebase with grep for common key patterns. Check git history for past commits. Inspect your browser bundle and network requests. Use automated tools like GitHub secret scanning or CheckYourVibe for continuous monitoring.

Common Key Patterns to Search For

Most API keys follow a recognizable prefix. If you see these strings in source files, DevTools, or network logs, you're looking at a real credential:

ServicePatternExample
Stripe Secretsk_live_ or sk_test_sk_test_51H...
OpenAIsk-sk-proj-abc123...
Supabase ServiceeyJ (JWT)eyJhbGciOiJIUz...
AWSAKIAAKIAIOSFODNN7...
GitHub Tokenghp_ or github_pat_ghp_xxxx...
SendGridSG.SG.xxxx...
TwilioSK (32 chars)SKxxxx...

Method 1: Search Your Source Code

Use grep to search for hardcoded keys in your project:

# Search for common key patterns
grep -rn "sk_live\|sk_test\|sk-\|AKIA\|ghp_\|SG\." \
  --include="*.ts" --include="*.js" --include="*.tsx" --include="*.jsx" .

# Search for generic patterns
grep -rn "api_key\|apiKey\|API_KEY\|secret\|password" \
  --include="*.ts" --include="*.js" --include="*.json" .

# Exclude node_modules and other irrelevant directories
grep -rn "sk_live" --include="*.ts" --exclude-dir=node_modules .

Pro tip: Look for long random strings (32+ characters) that aren't obviously UUIDs or hashes.

Method 2: Check Git History

A key you deleted from a file last week might've been committed to git before the deletion. It's still in every clone of that repo.

# Search entire git history for key patterns
git log -p --all | grep -E "sk_live|sk_test|api_key|AKIA"

# Search for specific file changes
git log -p -- .env

# Check if .env files were ever tracked
git log --all --full-history -- "*.env*"

# See all .env related commits
git log --oneline --all -- ".env*"

Finding a key in git history means it's compromised. Rotate it before anything else, even if the repo is private. Private repos get forked, cloned, and occasionally made public by accident. Clean the history after you're safe, not before.

Method 3: Inspect Your Browser Bundle

If a secret key ends up in your client-side JavaScript, every visitor to your site can read it. Check your production build:

# Build your app
npm run build

# Search the build output
grep -rn "sk_live\|sk_test\|sk-\|STRIPE_SECRET" .next/ dist/ build/

# For Next.js specifically
grep -rn "sk_" .next/static/

Check in the Browser

  1. Open your deployed site
  2. Open DevTools (F12) → Sources tab
  3. Press Ctrl+Shift+F (or Cmd+Shift+F on Mac) to search all sources
  4. Search for sk_, api_key, or other patterns

Method 4: Monitor Network Requests

Your browser shouldn't be calling third-party APIs directly with secret keys. Open DevTools, go to the Network tab, and use your app normally: log in, submit forms, trigger the key workflows.

Click on each request and check the Headers and Payload tabs. If you see Authorization: Bearer sk_live_... or a raw API key in a request body going to an external service, the key is visible to every user on your network.

Secret keys in browser requests are readable by anyone who can run DevTools or intercept traffic on the same network. This isn't a theoretical risk.

Method 5: Use Automated Tools

GitHub Secret Scanning

Enable in repo Settings → Security → Secret scanning. GitHub will alert you when it detects exposed secrets.

Pre-commit Hooks

Install tools that scan before each commit:

# Install detect-secrets
pip install detect-secrets

# Create baseline
detect-secrets scan > .secrets.baseline

# Add pre-commit hook
# In .pre-commit-config.yaml:
repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']

CI/CD Scanning

Add secret scanning to your deployment pipeline:

# GitHub Actions example
- name: Scan for secrets
  uses: trufflesecurity/trufflehog@main
  with:
    path: ./
    base: main
    head: HEAD

What to Do If You Find Exposed Keys

Rotate first. Everything else is secondary.

  1. Rotate immediately: generate a new key in the service dashboard
  2. Deploy it: update the environment variable and redeploy
  3. Revoke the old key: delete it; don't leave it active "just in case"
  4. Check for abuse: review the service's usage logs for the window the key was exposed
  5. Fix the root cause: move to server-side environment variables, add .env to .gitignore, add a pre-commit hook

Are Supabase anon keys safe to have in client code?

Yes, when Row Level Security is enabled. The anon key is designed to be in your client code. It only permits what your RLS policies allow. The service_role key is a different story. That one bypasses RLS entirely and must never appear in client JavaScript.

What about Firebase config objects?

Firebase's apiKey is intentionally public. It just tells the SDK which project to connect to. What protects your data is Firebase Security Rules. Hiding the config doesn't help; writing good rules does.

How often should I check for exposed keys?

Set up automated scanning so every commit gets checked. Beyond that, do a manual pass before major releases and when new people join the team. That's when new credentials tend to appear.

Related guides:How to Hide API Keys · How to Rotate API Keys · How to Enable Secret Scanning

How-To Guides

How to Check for Exposed API Keys