The Uber API Key Leak That Cost Millions
API key management became a major security concern in 2016 when Uber discovered that engineers had committed AWS access keys to a private GitHub repository. Attackers found the keys, accessed an S3 bucket, and downloaded personal data of 57 million riders and drivers.. Uber paid $148 million in settlement. The root cause was not malicious intent - a developer simply hardcoded an API key in source code, a mistake that happens at companies every single day.
GitHub reports scanning over 100 million commits per year and finding millions of leaked secrets. API key management is not a nice-to-have - it is the difference between a secure system and a data breach.
API Keys vs Tokens vs OAuth
Authentication Mechanisms Compared:
Mechanism Identifies Lifetime Use Case Example
---------- ---------- --------- ------------------- ------------------
API Key Application Long-lived Server-to-server Stripe sk_live_...
JWT Token User Short-lived Client-to-server Auth0, Firebase
OAuth Token User+App Medium Delegated access 'Sign in with Google'
Session ID User Session Traditional web app JSESSIONID cookie
API Key: 'I am the Payment Service, here is my key'
JWT: 'I am Alice (user 42), here is proof'
OAuth: 'Alice gave PhotoApp permission to read her Google Photos'
Key insight: API keys authenticate APPLICATIONS.
JWTs and OAuth authenticate USERS.While API keys are straightforward and popular, OAuth 2.0 represents a more secure alternative when it comes to authentication via user credentials. Find out more in our OAuth2 Flows: Delegated Authorization Made Practical guide. For those who are curious about token-based authentication in today’s world, we have an article called JWT Token and Refresh Rotation: Stateless Authentication That Works.
API Key Architecture
Key Generation and Storage:
Developer Portal Your Backend
[Generate Key] ----request-----> 1. Generate 32 bytes of crypto-random data
2. Encode as Base64: sk_live_a3Bx9kL2mN...
3. Hash with SHA-256: e4d909c290d0fb...
4. Store ONLY the hash in database
5. Return THE ACTUAL KEY to developer (once!)
<----response---- sk_live_a3Bx9kL2mN...
Incoming API Request:
Authorization: Bearer sk_live_a3Bx9kL2mN...
1. Extract key from header
2. SHA-256 hash the key
3. Look up hash in database
4. Found? Check scopes + rate limits
5. Not found? Return 401
Key Anatomy (Stripe pattern):
sk_live_a3Bx9kL2mN...
^^ ^^^^ ^^^^^^^^^^^^^^
| | |__ Random secret (32+ bytes)
| |__ Environment (live / test)
|__ Type (sk=secret / pk=publishable)Key Rotation Without Downtime
Rotation Flow (Zero-Downtime):
Day 0: Developer requests rotation
+---------------------------------+
| Active Keys: |
| Key A (current) -> ACTIVE |
| Key B (new) -> ACTIVE |
+---------------------------------+
Both keys work simultaneously.
Developer updates their code to use Key B.
Day 0 + 24 hours:
+---------------------------------+
| Active Keys: |
| Key A (old) -> REVOKED |
| Key B (current) -> ACTIVE |
+---------------------------------+
Key A stops working.
Grace period prevents breaking changes.
Scoping Matrix:
Permission sk_read sk_write sk_admin
--------------- -------- --------- --------
Read resources Yes Yes Yes
Create/Update No Yes Yes
Delete No No Yes
Manage API keys No No YesSecurity Best Practices
Never embed keys in frontend code - anyone can view source. Use a backend proxy instead.
Store keys hashed (SHA-256) in your database - if the DB leaks, the hashes are useless without the original key.
Support key rotation with overlap periods - let old and new keys work simultaneously during transition.
Implement key scoping - read-only vs read-write, specific endpoints only (principle of least privilege).
Set expiration dates - keys that never expire are time bombs. Default to 90-day expiry.
Log usage per key - detect anomalies like 100x normal volume, requests from unexpected IPs.
Use environment-specific keys - test keys cannot access production data, ever.
Scan repositories for leaked keys - use tools like GitLeaks, truffleHog, or GitHub secret scanning.
Interview Tip
When discussing API authentication in interviews, distinguish between API keys (identify applications, long-lived, server-to-server) and tokens (identify users, short-lived). Emphasize that keys must be hashed in storage like passwords - if your keys table leaks, attackers should get nothing useful. Mention the Stripe key prefix pattern (sk_live_, pk_test_) as elegant UX design. If asked about key rotation, describe the zero-downtime overlap approach where both old and new keys are valid during a grace period.
Key Takeaway
API keys are simple but powerful when managed correctly. Hash them in storage, support rotation with grace periods, scope them to minimum permissions, expire them, and NEVER expose them in client-side code. They identify applications, not users.
