-- API keys for the public read-only API. Keys grant higher rate limits and let -- usage be attributed to a caller; the API itself stays free and read-only. -- Only the SHA-256 hash of a key is stored; the plaintext is shown once at -- creation time. Keys are issued/revoked from the admin console. The public -- server only ever SELECTs from this table (request counting lives in Redis), -- preserving its read-only contract against PostgreSQL. CREATE TABLE IF NOT EXISTS api_key ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, key_prefix VARCHAR(20) NOT NULL, -- shown for identification, e.g. og_live_AbC1 key_hash TEXT NOT NULL UNIQUE, -- hex SHA-256 of the full key owner_email TEXT, tier VARCHAR(16) NOT NULL DEFAULT 'free', rate_limit_per_min INT NOT NULL DEFAULT 120, revoked_at TIMESTAMPTZ, created_by TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), CONSTRAINT api_key_tier_chk CHECK (tier IN ('free', 'partner', 'internal')), CONSTRAINT api_key_rate_chk CHECK (rate_limit_per_min > 0) ); -- Fast lookup of active keys by their hash on every authenticated request. CREATE INDEX IF NOT EXISTS idx_api_key_active_hash ON api_key (key_hash) WHERE revoked_at IS NULL;