Back to blog
api key securitydeveloper securityapi best practicessecrets managementdevsecops

API Key Security: The Mistakes That Get Developers Breached

API key security best practices for developers who ship fast: real mistakes, real fixes, and a checklist to stop leaking secrets into production.

2026-08-096 min read

Every year, thousands of API keys show up in public GitHub repos, client-side JavaScript bundles, and Slack messages. Most of these leaks aren't caused by sophisticated attacks — they're caused by developers doing the fast, easy thing instead of the safe thing under deadline pressure. This post covers the specific mistakes that lead to leaked keys, and the concrete fixes that actually prevent them.

Why API Keys Get Compromised in the First Place

Before the fixes, it helps to understand the actual attack surface. API keys usually leak through one of these paths:

  • Hardcoded directly into source code that gets pushed to a public or semi-public repo
  • Exposed in client-side code (browser JS, mobile app bundles) where anyone can inspect network requests
  • Logged accidentally in error messages, request logs, or monitoring tools
  • Shared over Slack, email, or shared docs and never rotated afterward
  • Left in CI/CD config files or Docker images that get pushed to a registry

None of these require a sophisticated attacker. A scraper bot scanning public GitHub commits for regex patterns like sk_live_ or AKIA will find your key within minutes of it being pushed.

Rule 1: Never Hardcode Keys in Source Code

This sounds obvious, but it's still the #1 cause of leaks. The fix is environment variables, full stop.

How to do it properly

  1. Store keys in a .env file locally, never committed to git
  2. Add .env to .gitignore on day one of the project — not after your first leak
  3. Use a library like dotenv (Node), python-dotenv, or built-in env support to load values at runtime
  4. In production, set env vars directly in your hosting platform (Vercel, Railway, AWS Secrets Manager, etc.) rather than shipping a .env file

If you're integrating a third-party service like PxShot for generating screenshots or PDFs, the API key should live in process.env.PXSHOT_API_KEY on your server — never inline in a request URL that gets logged or committed.

Rule 2: Never Call Third-Party APIs Directly from the Browser

This is the mistake that turns a minor slip into a full compromise. If your frontend JavaScript makes a fetch call directly to an API using your secret key, that key is visible to anyone who opens DevTools.

The fix: a server-side proxy

  • Your frontend calls your own backend endpoint (e.g. /api/screenshot)
  • Your backend attaches the real API key and forwards the request to the third-party service
  • The client never sees the actual credential

For example, if you're using PxShot to generate OG images or link previews on the fly, don't call the PxShot endpoint from client-side code with the key attached. Route it through a small server function instead — a single Express route or serverless function is enough.

Rule 3: Scope Keys to the Minimum Permission Needed

Not every part of your system needs full access. If your API provider supports scoped or restricted keys, use them.

  • Create separate keys for development, staging, and production
  • Use read-only keys wherever write access isn't needed
  • Restrict keys by IP address or domain when the provider supports it
  • Set usage limits or rate caps on keys used in less-trusted environments (e.g. internal tools, demos)

This limits blast radius. If a staging key leaks, you don't want it to also have production database write access.

Rule 4: Rotate Keys on a Schedule, Not Just After Incidents

Most teams only rotate keys reactively — after a leak is discovered. By then, the damage may already be done.

A practical rotation workflow

  1. Set a calendar reminder every 90 days to rotate all active API keys
  2. Generate the new key while keeping the old one active temporarily
  3. Update all services/environments to use the new key
  4. Confirm nothing is broken, then revoke the old key
  5. Log the rotation date somewhere your team can see it

Anytime someone leaves the team, or a contractor's project ends, treat that as a mandatory rotation trigger — not optional.

Rule 5: Catch Leaks Before They Ship

Prevention beats cleanup. A few tools that catch secrets before they hit a public repo:

  • git-secrets — blocks commits matching known credential patterns
  • gitleaks — scans repo history and CI pipelines for exposed secrets
  • GitHub secret scanning — enabled by default on public repos, and available on private repos with GitHub Advanced Security
  • Pre-commit hooks that run a regex check before allowing a commit to go through

Set these up once, at the repo level, and they run silently in the background — you don't have to remember to check manually.

Rule 6: Treat Logs as a Leak Vector Too

Keys don't only leak through code. They leak through logs when developers log full request objects for debugging and forget the header containing the API key.

Safer logging practices

  • Explicitly redact or mask authorization headers before logging requests
  • Never log full URLs if the key is passed as a query parameter — use headers instead when the API supports it
  • Review what your error-tracking tool (Sentry, LogRocket, etc.) captures by default — many capture full request/response payloads

A Quick Pre-Launch Checklist

Before shipping anything that touches a third-party API key, run through this:

  • ☐ Key is stored in an environment variable, not hardcoded
  • .env is in .gitignore
  • ☐ Frontend never sees the raw key — all calls go through a backend proxy
  • ☐ Key is scoped to the minimum permission needed for the task
  • ☐ Separate keys exist for dev/staging/production
  • ☐ Secret scanning is enabled on the repo
  • ☐ Logging doesn't capture auth headers or full request URLs
  • ☐ A rotation schedule is documented somewhere the team can see it

Applying This to Screenshot and PDF APIs

If you're building automated OG image generation, visual monitoring, or PDF exports using a service like PxShot, the same rules apply directly:

  • Keep your PxShot API key server-side and proxy requests through your own backend or serverless function
  • Use a separate key for local development versus production so a local mistake never touches production usage limits
  • If you're generating public-facing preview images on demand, cache the results rather than exposing an endpoint that lets anyone trigger unlimited API calls under your key

Try PxShot's free tier at pxshot.dev to test screenshot and PDF generation with a scoped API key from day one — no credit card, no shared credentials, just a clean setup you can build security into from the start.