Files
rspade_system/app/RSpade/man/external_api.txt
root 84ca3dfe42 Fix code quality violations and rename select input components
Move small tasks from wishlist to todo, update npm packages
Replace #[Auth] attributes with manual auth checks and code quality rule
Remove on_jqhtml_ready lifecycle method from framework
Complete ACL system with 100-based role indexing and /dev/acl tester
WIP: ACL system implementation with debug instrumentation
Convert rsx:check JS linting to RPC socket server
Clean up docs and fix $id→$sid in man pages, remove SSR/FPC feature
Reorganize wishlists: priority order, mark sublayouts complete, add email
Update model_fetch docs: mark MVP complete, fix enum docs, reorganize
Comprehensive documentation overhaul: clarity, compression, and critical rules
Convert Contacts/Projects CRUD to Model.fetch() and add fetch_or_null()
Add JS ORM relationship lazy-loading and fetch array handling
Add JS ORM relationship fetching and CRUD documentation
Fix ORM hydration and add IDE resolution for Base_* model stubs
Rename Json_Tree_Component to JS_Tree_Debug_Component and move to framework
Enhance JS ORM infrastructure and add Json_Tree class name badges

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 21:39:43 +00:00

149 lines
4.5 KiB
Plaintext
Executable File

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