Generating Secure API Keys: Formats and Best Practices

Keys

API keys are the simplest form of API authentication. Unlike OAuth tokens or JWTs, they don't encode user identity or expiration — they're just random strings that identify a caller. Getting the format and handling right matters for both security and developer experience.

Key Formats Compared

UUID v4

550e8400-e29b-41d4-a716-446655440000
  • 122 bits of randomness
  • Universally understood format
  • Easy to parse (five hyphen-separated groups)
  • Downside: No visual indicator of what the key is for

Hex Token

a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0
  • Arbitrary length (64 hex chars = 256 bits)
  • Simple to generate with any crypto library
  • Downside: Not human-friendly, easy to confuse with hashes

Prefixed API Key

tk_live_a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5
  • Prefix identifies the service (tk_) and environment (live_)
  • Immediately distinguishable from passwords, hashes, and other secrets
  • Log scanning can detect leaked keys by prefix (like GitHub's secret scanning)
  • This is the recommended format

Generate a prefixed API key with the Auth Toolkit API:

curl -X POST https://auth.toolkitapi.io/v1/auth/generate-key \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "api-key", "length": 32, "prefix": "tk_live_"}'
{
  "key": "tk_live_a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5",
  "type": "api-key",
  "entropy_bits": 128.0
}

Entropy: How Much Randomness?

Entropy measures how hard a key is to guess. For API keys:

Entropy Security level Example
64 bits Minimum viable 16 hex chars
128 bits Standard 32 hex chars, UUID v4
256 bits High security 64 hex chars

128 bits of entropy is the practical standard — it would take billions of years to brute-force, even with all the world's computing power.

The Auth Toolkit reports entropy_bits in every response so you can verify your keys meet your security requirements.

Other Key Types

The Generate Key endpoint supports multiple formats:

# UUID v4
curl -X POST .../generate-key -d '{"type": "uuid"}'

# Hex secret
curl -X POST .../generate-key -d '{"type": "hex", "length": 64}'

# URL-safe token
curl -X POST .../generate-key -d '{"type": "url-safe", "length": 32}'

For asymmetric key pairs (RSA/EC), use the Generate Key Pair endpoint:

curl -X POST https://auth.toolkitapi.io/v1/auth/generate-keypair \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"algorithm": "RSA", "key_size": 2048}'

Storage Best Practices

Hash keys before storing

Never store API keys in plaintext in your database. If your database is breached, all keys are compromised. Instead:

  1. When a key is generated, show it to the user once.
  2. Store a SHA-256 hash of the key in your database.
  3. When a request arrives, hash the provided key and compare against stored hashes.

This is the same principle as password hashing, but SHA-256 is sufficient here because API keys have high entropy (unlike passwords).

Display only the prefix

In dashboards, show only the first 8–12 characters: tk_live_a3f8.... This lets users identify which key it is without exposing the full secret.

Scope keys to the minimum

Each key should have the narrowest permissions possible:

  • Read-only vs. read-write
  • Per-environment: Separate keys for development, staging, and production
  • Per-service: Don't share keys between microservices

Rotation and Revocation

Keys should be rotatable without downtime:

  1. Generate a new key and add it to the system.
  2. Update the client to use the new key.
  3. Revoke the old key after confirming the transition.

Support multiple active keys per user/service so the transition is seamless. Set key expiration dates and alert users before keys expire.

Key Generation Checklist

  • [ ] Use at least 128 bits of cryptographic randomness
  • [ ] Add a descriptive prefix (service + environment)
  • [ ] Hash keys (SHA-256) before database storage
  • [ ] Show the full key only once at creation time
  • [ ] Support multiple active keys for rotation
  • [ ] Log key usage with key ID (not the key itself)
  • [ ] Rate-limit API authentication to slow brute-force attempts

Try it out

Browse Tools →

More from the Blog