Authentication
Authentication verifies the identity of a client attempting to access a service. Common patterns are: * **API Keys**: Simple strings sent in request headers. * ...
Definition
Authentication verifies the identity of a client attempting to access a service. Common patterns are:
- API Keys: Simple strings sent in request headers.
- JWT (JSON Web Token): Cryptographically signed tokens that securely transmit claims between parties.
- OAuth 2.0: An authorization framework that delegates resource access control without sharing passwords.
Why It Exists
AI resources are expensive to run. Unauthenticated access can lead to token abuse, large infrastructure bills, and Denial of Service (DoS) attacks. Secure authentication ensures you can track API usage, enforce rate limits, and charge customers correctly.
How It Works
JWT AUTHENTICATION FLOW
┌────────┐ ───[ POST /login ]───► ┌────────┐
│ Client │ │ Server │
│ │ ◄───[ Token (Header.Payload.Signature) ]─── │ │
└────────┘ └────────┘
│
└─[ POST /generate + Authorization: Bearer Token ]──► Validates Signature
* **API Key Header**: The client includes the key in a request header: `Authorization: Bearer <API_KEY>`. The server checks this key against its database.
* **JWT Signature**: A JWT consists of three parts separated by dots: Header, Payload, and Signature. The signature is created by hashing the header, payload, and a private key known only to the server. The server can verify the token's validity by checking its signature, without needing to query a database on every request.Real-World Example
When using Claude, you initialize the client by passing an API key. Every request made by the SDK attaches this key to the HTTP header, allowing Anthropic to verify your account credentials and deduct tokens from your balance.
Python Example
Here is a simulation of JWT creation and validation using signature verification:
import hmac
import hashlib
import base64
import json
from typing import Optional
class MockJWT:
"""Simulates generation and verification of a cryptographically signed JWT."""
def __init__(self, secret_key: str):
self.secret = secret_key.encode()
def create_token(self, payload: dict) -> str:
# Step 1: Base64 encode header and payload
header = {"alg": "HS256", "typ": "JWT"}
header_b64 = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().strip("=")
payload_b64 = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().strip("=")
# Step 2: Sign the token
signature_input = f"{header_b64}.{payload_b64}".encode()
signature = hmac.new(self.secret, signature_input, hashlib.sha256).digest()
sig_b64 = base64.urlsafe_b64encode(signature).decode().strip("=")
return f"{header_b64}.{payload_b64}.{sig_b64}"
def verify_token(self, token: str) -> Optional[dict]:
try:
parts = token.split(".")
if len(parts) != 3:
return None
header_b64, payload_b64, sig_b64 = parts
# Recreate signature
signature_input = f"{header_b64}.{payload_b64}".encode()
expected_sig = hmac.new(self.secret, signature_input, hashlib.sha256).digest()
expected_sig_b64 = base64.urlsafe_b64encode(expected_sig).decode().strip("=")
# Use constant-time comparison to prevent timing attacks
if hmac.compare_digest(sig_b64.encode(), expected_sig_b64.encode()):
# Decode payload
padding = "=" * (4 - len(payload_b64) % 4)
decoded_payload = base64.urlsafe_b64decode(payload_b64 + padding).decode()
return json.loads(decoded_payload)
return None
except Exception:
return None
if __name__ == "__main__":
jwt = MockJWT("super_secret_key")
token = jwt.create_token({"user_id": "usr_77", "role": "admin"})
print("Generated JWT:", token)
# Valid validation
print("Verified Payload:", jwt.verify_token(token))
# Corrupted check
print("Corrupted verification:", jwt.verify_token(token + "corrupt"))Interview Questions
- Beginner: How is an API Key typically transmitted in an HTTP request?
- Intermediate: What are the three parts of a JSON Web Token (JWT)?
- Advanced: Why does JWT authentication reduce database load compared to traditional session-based token authentication?
Interview Answers
- Beginner: An API Key is typically sent in the HTTP request headers, commonly using the key
Authorizationwith the value formatBearer <API_KEY>. - Intermediate: A JWT consists of a Header (defines token type and signature algorithm), a Payload (contains session data claims like user id or roles), and a Signature (verifies the integrity of the token).
- Advanced: Traditional session authentication requires the server to query its database on every request to verify the token. In contrast, a JWT is self-contained. The server can verify the token's validity by checking its cryptographic signature, without needing to query a database on every request.
Common Mistakes
- Leaking keys in git repository: Hardcoding API keys directly inside code files. If you push the code to a public repository, scanners will steal the keys instantly. Always load API keys from environment variables using a
.envfile and add the file to.gitignore.
Assignment
Write a Python script that loads an API key from an environment variable and makes an authenticated request to a public endpoint, printing a confirmation message once successful.