Генератор паролів

Опубліковано: 2026-06-08

API Key Management: Best Practices for 2026

Stop leaking API keys. Learn entropy math, rotation, scoping, and secret storage that actually holds up — plus a free client-side key generator.

api key security architecture — vault, rotation, and scoped tokens

A leaked API key is a password that wrote itself onto the internet. The difference is that nobody types an API key, so nobody notices when it ends up in a public GitHub repo, a Slack message, or a frontend bundle. By the time the crypto-mining bill arrives, the key has been scraped, traded, and weaponized.

The fix is boring and effective: generate keys with real entropy, scope them tightly, store only their hashes, and rotate on a schedule. Get those four right and a leaked key becomes an annoyance instead of an incident. This guide covers the math and the mechanics behind each one.

What actually makes an API key secure

An API key is just a bearer token — whoever holds it is trusted. There's no second factor, no password prompt, no "are you sure?" The entire security model collapses to one question: can an attacker guess, derive, or steal the key?

Guessing is a math problem. The entropy of a generated key is:

H = L × log₂(R)

Where H = entropy in bits, L = key length in characters, and R = the size of the character pool. A 32-character hex key (R = 16) gives you 32 × 4 = 128 bits. A 22-character Base64url key (R = 64) gives you 22 × 6 = 132 bits. Both are well past the point where brute force stops being a threat.

How far past? Here's what an attacker with an RTX 4090 faces when a key is stored as a SHA-256 hash:

Key formatLengthEntropyCombinationsOffline crack (SHA-256, ~23B/s)
Hex16 chars64 bits1.8 × 10¹⁹~25 years
Hex32 chars128 bits3.4 × 10³⁸~10²¹ × age of universe
Base64url22 chars132 bits5.4 × 10³⁹effectively infinite
Base64url43 chars256 bits1.2 × 10⁷⁷heat death of the universe

128 bits is the floor. Below 64 bits, a determined attacker with enough GPUs can grind through it. At 128+ bits, brute force is off the table and the only attack left is theft — which is what the rest of this guide defends against.

Generate keys from a real entropy source

Here's the part that trips up smart developers: the algorithm doesn't matter if the randomness is fake.

Avoid tools and code that use Math.random(). It's a deterministic PRNG seeded from a small state — predictable enough that researchers have reconstructed its output from a handful of samples. A key built on Math.random() might look like 128 bits of entropy while actually having a few dozen bits of real unpredictability. Our Secret Key Generator — runs 100% in your browser, zero data sent to any server — uses the Web Crypto API (crypto.getRandomValues()), so your entropy source is the same OS-level CSPRNG that hardware security modules rely on.

Zero-Knowledge — the Secret Key Generator processes everything in your browser's volatile memory. Nothing is ever transmitted to a server.

In Node, the equivalent is crypto.randomBytes(32).toString('base64url'). In Python, secrets.token_urlsafe(32). Both pull from the kernel CSPRNG. The rule never changes: bold the boundarycrypto.getRandomValues() good, Math.random() catastrophic.

Never store the raw key

Treat your API keys exactly like passwords: the server should never be able to print a key back to you.

When you generate a key, show it to the user once, then store only its hash. Because keys already carry 128+ bits of entropy, you don't need a slow password-style KDF (bcrypt, Argon2) — those exist to protect low-entropy human passwords against brute force. A single fast SHA-256 is enough, since there's nothing to brute-force in the first place.

 ISSUE                         STORE                          VERIFY
 ─────                         ─────                          ──────
 key = csprng(32 bytes)        db.save({                      incoming request
   │                             prefix: "sk_live_a8Fk",        │  Authorization: sk_live_a8Fk…9Qx
   │  "sk_live_a8Fk…9Qx"         hash:   sha256(key)            ▼
   ▼                            })                            sha256(incoming) ──┐
 show ONCE to user        ─────────►  raw key discarded                         ▼
 (never stored raw)                   only hash + prefix kept   == stored.hash ? ──► allow / deny

The raw key exists in plaintext for exactly one moment — when you hand it to the user. After that the server holds only an irreversible SHA-256 digest plus a short lookup prefix. Verification re-hashes whatever arrives and compares digests; the original is never reconstructed.

Storing a short non-secret prefix (the first 6–8 chars) alongside the hash lets you show users sk_live_a8Fk… in a dashboard and search logs without ever holding the secret. You can generate and verify those SHA-256 digests with the Hash Generator while building the flow. If your database leaks, attackers get a column of irreversible hashes. Game over for them, not you.

Scope every key to the minimum it needs

A key that can do everything is a key worth stealing. Scoping shrinks the blast radius of a leak.

  • Permission scopes — read-only vs read-write, per-resource grants. A key for a static-site analytics widget should not be able to delete users.
  • Environment separation — distinct sk_test_ and sk_live_ prefixes. Test keys hit sandbox data; a leaked test key costs nothing.
  • IP allowlisting — bind server-to-server keys to known egress IPs. A scraped key fired from a residential botnet gets rejected at the edge.
  • Rate limits per key — cap requests so a stolen key can't drain your quota or your wallet before monitoring catches it.

The principle is the same one you'd apply to IAM roles: least privilege, always. Issue many narrow keys instead of one master key, and a single leak compromises one capability instead of your whole account.

Rotate on a schedule, revoke on suspicion

Keys age badly. The longer one lives, the more logs, backups, and laptops it has leaked into. Rotation caps that exposure window.

Key typeLifetimeRotation policy
Short-lived access token< 1 hourAuto-expires; no manual rotation
Service-to-service key90 daysScheduled rotation, overlap window
CI/CD deploy key90 daysRotate + rotate on team offboarding
Long-lived integration key90 days maxScheduled + immediate on suspected leak

The trick that makes rotation painless is an overlap window: issue the new key, accept both old and new for 24–48 hours, then revoke the old one. No downtime, no scramble. Build the new key, deploy it, confirm traffic moved, kill the old key.

And when a key leaks — push to a public repo, paste in a ticket, show up in a breach dump — revoke immediately. Don't rotate "soon." A leaked bearer token is being used by someone else right now.

🛡️ Security Checkpoint — Complete This Step

A single weak or reused secret undoes every other control on this list. Lock down your key hygiene before you ship the next deploy.

Keep keys out of the places they leak

Most key compromises aren't clever attacks — they're keys sitting in the wrong file. The usual suspects:

  1. Committed to git.env files, hardcoded constants, config dumps. Add .env to .gitignore before the first commit, and run a secret scanner (gitleaks, trufflehog) in CI.
  2. Shipped to the frontend — any key in client-side JS is public. If the browser can read it, so can everyone. Frontend code should call your backend, which holds the real key server-side.
  3. Logged in plaintext — request loggers and error trackers love to capture headers. Redact Authorization and X-API-Key at the logging layer.
  4. Pasted into chat/tickets — treat any key that touches Slack or Jira as already compromised. Rotate it.

For production, graduate from .env files to a real secret manager — HashiCorp Vault, AWS Secrets Manager, or Doppler — which gives you encryption at rest, access auditing, and rotation hooks. Your app fetches secrets at runtime instead of baking them into an image.

Frequently Asked Questions

How long should an API key be? Aim for at least 128 bits of entropy — roughly 32 hex characters or a 22-character Base64url string. That puts brute force out of reach even for an offline attacker grinding SHA-256 at ~23 billion guesses/sec. Going to 256 bits costs you nothing and future-proofs the key.

Should I hash API keys before storing them? Yes. Store only a SHA-256 hash of the key, never the raw value, exactly as you'd treat a password. The difference: keys are already high-entropy, so you don't need a slow KDF like bcrypt or Argon2 — those defend low-entropy human passwords. A fast SHA-256 is correct here. Keep a short non-secret prefix alongside the hash so dashboards and logs can identify a key without exposing it.

How often should I rotate API keys? Rotate long-lived keys every 90 days, and immediately after any suspected exposure or team offboarding. Use an overlap window — accept old and new keys for 24–48 hours — so rotation causes no downtime. Short-lived tokens that expire in under an hour sidestep manual rotation entirely.

Is it safe to generate API keys in a browser? Yes, if the tool uses the Web Crypto API. The Secret Key Generator builds every key with crypto.getRandomValues() entirely client-side — nothing is transmitted, so the key exists only in your browser's memory until you copy it. Avoid any generator that relies on Math.random().

What's the difference between an API key and a token? An API key is typically a long-lived static credential you manage manually. A token (like a JWT or OAuth access token) is usually short-lived, scoped, and issued by an auth flow. Tokens reduce rotation burden because they expire fast; keys trade convenience for a larger exposure window.

Спробуйте наш безкоштовний генератор паролів

Генеруйте надійні, безпечні паролі миттєво. 100% приватно, на стороні клієнта.

Відкрити генератор паролів