EXTERNAL API ============ RSpade provides a system-level API key authentication mechanism for external API access. API keys are managed as a system table (_api_keys) with an opinionated interface - developers interact with the Session class rather than API key records directly. ARCHITECTURE ------------ API keys authenticate requests and establish a session context automatically. The system handles: - Key validation and lookup - User context establishment (API key -> user -> session) - Rate limiting (future) - Usage tracking Developers never interact with API key records directly. The Session class provides the interface for checking authentication context regardless of whether authentication came from a browser session or API key. DATABASE SCHEMA --------------- System table: _api_keys (not exposed to developers) id BIGINT PRIMARY KEY user_id BIGINT NOT NULL (FK to users) name VARCHAR(255) - Human-readable key name key_hash VARCHAR(255) - Hashed API key (never store plaintext) key_prefix VARCHAR(16) - First chars for identification (e.g., "rsk_...") user_role_id BIGINT NULL - Optional role override (see ROLE OVERRIDE below) last_used_at DATETIME NULL expires_at DATETIME NULL is_revoked BOOLEAN DEFAULT FALSE created_at DATETIME updated_at DATETIME Keys are tied to users (user_id). A user can have multiple API keys. KEY FORMAT ---------- API keys use the format: rsk_{environment}_{random} rsk_live_a1b2c3d4e5f6... (production) rsk_test_x7y8z9a0b1c2... (development/test) The prefix (rsk_live_, rsk_test_) is stored in key_prefix for identification. Only the hash of the full key is stored. ROLE OVERRIDE ------------- The user_role_id column allows API keys to have reduced permissions compared to the user's actual role. This enables creating restricted-access keys. Rules: - NULL: Key inherits user's actual role - Set value: Key uses specified role IF user has permission to assign it Role assignment follows ACL rules - a user cannot create an API key with higher privileges than their own role allows. Even if a privileged role ID is set on an API key record, the system will not grant access beyond what the user themselves has. Example: A "Member" user cannot create an API key with "Admin" privileges. If such a record exists (e.g., from direct DB manipulation), the system ignores the elevated role and uses the user's actual permissions. This behavior depends on the ACL system implementation (see: acls.txt). AUTHENTICATION FLOW (PLANNED) ----------------------------- 1. Client sends request with API key in header: Authorization: Bearer rsk_live_a1b2c3d4... 2. System extracts key, hashes it, looks up in _api_keys 3. If valid and not revoked/expired: - Load associated user - Establish session context (user_id, site_id, role) - Apply role override if set - Update last_used_at 4. Request proceeds with user context available via Session class 5. Controller code uses Session::user(), Session::check() as normal - no awareness needed of API vs browser authentication USAGE (PLANNED) --------------- For API consumers: curl -H "Authorization: Bearer rsk_live_xxx" https://example.com/api/endpoint For developers checking auth context: // Works identically for browser sessions and API keys if (Session::check()) { $user = Session::user(); // ... handle authenticated request } // Check if current request is API-authenticated if (Session::is_api_request()) { // ... API-specific logic if needed } RATE LIMITING (FUTURE) ---------------------- Planned features: - Per-key rate limits - Configurable limits per role/plan - Usage tracking and analytics - Automatic throttling with appropriate HTTP responses IP WHITELISTING (FUTURE) ------------------------ Planned features: - Optional IP restrictions per key - CIDR notation support - Automatic rejection of requests from non-whitelisted IPs KEY MANAGEMENT UI ----------------- Users manage their API keys via Settings > API Keys: - View existing keys (name, prefix, created, last used) - Generate new keys (name required) - Revoke keys (soft delete via is_revoked flag) - Copy key to clipboard (full key shown only on creation) The full API key is shown only once at creation time. Users must copy it immediately as the system only stores the hash. SEE ALSO -------- acls.txt - Access control and role system session.txt - Session management