API Keys

API Keys

The Problem They Solve

You need a simple way to identify which application is calling your API, enforce per-client rate limits, and revoke access if a client misbehaves. You don’t need to know which user is making the request — just which application.

How They Work

An API key is an opaque random string (typically 32–64 characters) issued to each client. The client includes it in every request, usually in a header.

sequenceDiagram
    participant Dev as Developer
    participant Portal as API Portal
    participant Client as Client App
    participant API as Your API

    Dev->>Portal: Register application
    Portal-->>Dev: API key: example_key_

    Client->>API: GET /api/weather?city=london
X-API-Key: example_key_ Note over API: 1. Hash the received key
2. Look up hash in DB
3. Check: active? rate limit ok?
4. Identify the client application API-->>Client: 200 OK {temperature: 18, ...}

Why Hash the Key?

API keys are credentials — they grant access to your API. If your database is breached and keys are stored in plaintext, every client is instantly compromised. Hashing with SHA-256 means the attacker gets hashes they can’t reverse.

Stored in DB:       key_hash = SHA256("example_key_...")
Attacker steals DB: sees "a1b2c3d4e5..." (useless without the original key)
Client sends key:   server computes SHA256(received_key), compares with stored hash

Treat API keys exactly like passwords: hash before storing, transmit only over HTTPS, allow rotation, support revocation.

Limitations of API Keys Alone

ProblemWhy API keys can’t solve it
No tamper protectionAn attacker who intercepts the key can replay any request, modify parameters, or forge new requests
No request integrityThe server can’t verify that the request body wasn’t modified in transit (beyond TLS)
No user identityAPI keys identify the application, not the user — can’t do per-user authorization
Shared secret riskThe key is sent with every request — if any request is logged with headers, the key is exposed

For public APIs with simple needs (weather data, maps), API keys are sufficient. For APIs handling sensitive data or money, you need something stronger.

Test Your Understanding

A partner integration uses API keys sent in a query parameter: GET /api/data?key=abc123. Why is this insecure even over HTTPS?

Query parameters are logged everywhere. HTTPS encrypts the URL in transit, but: (1) Server access logs record the full URL including the key. (2) Browser history stores it. (3) Intermediary proxies (CDN, API gateway) may log URLs. (4) Referrer headers leak the URL to external links.

Fix: Send API keys in a header: Authorization: Bearer abc123 or X-API-Key: abc123. Headers are not logged by default in most HTTP servers and never appear in browser history or referrer headers.

Your API-key table is stored in plaintext so support can email a partner their key if they lose it. Why is that ‘convenience’ a serious liability?

A single database leak instantly compromises every client. Plaintext keys are credentials in the clear — an attacker who reads the table can impersonate every partner at once. The ability to email a key back is a symptom of the same flaw: if you can recover it, so can anyone who steals the store.

Fix: treat keys like passwords — store only a hash (e.g., SHA-256), compare the hash of the presented key on each request, and if a partner loses a key, rotate (issue new, revoke old) rather than recover it.