EqualifyEverything / equalify-reflow

feat(auth): labelled API keys for per-key usage attribution
API-key requests were unattributable. The middleware stored request.state.api_key but the request logger only read request.state.identity (the session user), so every API-key call logged as anonymous. The key value is never logged (correct), but nothing derived from it was either — two keys were indistinguishable in every log line, so "how much is this key being used" had no answer. API_KEYS now accepts an optional label per entry: API_KEYS="zach:<key>,daisy:<key>" # labelled API_KEYS="<key>,<key>" # bare — still works Each entry is either a bare key or a 'label:key' pair, split on the first colon — the same encoding AUTH_BASIC_USERS uses for 'username:hash'. A bare key gets a derived 'key-<fingerprint>' label (first 8 hex of sha256) so even unlabelled keys stay distinct in logs without exposing the key. A key that itself contains a colon must be given an explicit label. Changes: - api_key_auth: _load_api_keys returns a {key: label} dict instead of a set; _is_valid_key becomes _match_key returning the matched label (or None). On a valid request, request.state.api_key_label is set. - logging_middleware: _identity_fields now also surfaces api_key_label, and accumulates fields from both auth paths instead of returning early — a request can carry a session identity, an API key label, or neither. - config: API_KEYS field description documents the label syntax. Backward compatible: an existing flat comma-separated API_KEYS with no colons keeps working unchanged; each key just gets a fingerprint label. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Blake Bertuccelli-Booth Blake Bertuccelli-Booth committed on May 18, 2026, 07:49 PM
Showing 6 changed files +238 additions -47 deletions
Browse files at this commit →