feat: API key authentication dependency

Implements create_api_key_dependency() FastAPI dependency that validates
Bearer tokens against a configured list of ApiKey objects (401 on missing,
malformed, or unknown tokens). Includes 5 TDD tests covering all cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
tlg
2026-04-04 07:31:30 +02:00
parent c4eaf5088b
commit 969bcb3292
2 changed files with 74 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
import pytest
from fastapi import FastAPI, Depends
from fastapi.testclient import TestClient
from llmux.auth import create_api_key_dependency
from llmux.config import ApiKey
@pytest.fixture
def app_with_auth():
keys = [
ApiKey(key="sk-test-valid-key", name="Test"),
ApiKey(key="sk-test-another-key", name="Another"),
]
require_api_key = create_api_key_dependency(keys)
app = FastAPI()
@app.get("/protected")
def protected(api_key: str = Depends(require_api_key)):
return {"key_name": api_key}
return app
@pytest.fixture
def client(app_with_auth):
return TestClient(app_with_auth)
def test_valid_key_returns_200(client):
resp = client.get("/protected", headers={"Authorization": "Bearer sk-test-valid-key"})
assert resp.status_code == 200
assert resp.json()["key_name"] == "Test"
def test_another_valid_key(client):
resp = client.get("/protected", headers={"Authorization": "Bearer sk-test-another-key"})
assert resp.status_code == 200
assert resp.json()["key_name"] == "Another"
def test_missing_auth_header_returns_401(client):
resp = client.get("/protected")
assert resp.status_code == 401
def test_invalid_key_returns_401(client):
resp = client.get("/protected", headers={"Authorization": "Bearer sk-wrong"})
assert resp.status_code == 401
def test_malformed_header_returns_401(client):
resp = client.get("/protected", headers={"Authorization": "sk-test-valid-key"})
assert resp.status_code == 401