Implement V3 API security hardening and multi-tenant data isolation
- Enhanced AuthContext with role-aware fields (administrator, manager, super). - Implemented deferred database lookups for user roles in get_v3_auth_context. - Added global account isolation in api_crud_v3.py using check_account_access and apply_forced_account_filter. - Hardened all V3 CRUD endpoints (GET, POST, PATCH, DELETE) and nested routes with ownership verification. - Enforced forced account filtering at the SQL level for Listing and Searching. - Updated documentation with details on the new security and data isolation architecture.
This commit is contained in:
@@ -55,3 +55,21 @@ The following objects have been migrated to the modern V3 configuration and are
|
||||
- `hosted_file`, `post`, `post_comment`
|
||||
- `person`, `user`
|
||||
- `lu_country`, `lu_country_subdivision`, `lu_time_zone`
|
||||
|
||||
## 5. Security and Data Isolation
|
||||
|
||||
Implemented in Jan 2026, the V3 architecture enforces strict data isolation and role-aware authorization.
|
||||
|
||||
### Role-Aware Authorization (`AuthContext`)
|
||||
- **Deferred User Lookup**: When a JWT is provided, the API performs a deferred database lookup via `load_user_obj` to populate `administrator`, `manager`, and `super` flags.
|
||||
- **Role Scoping**: These flags are used to bypass account isolation for support and system maintenance tasks.
|
||||
|
||||
### Multi-Tenant Isolation
|
||||
- **Forced Account Filtering**: For all non-super users, the API automatically injects an `account_id` filter into every list and search query. This is enforced at the SQL level via `apply_forced_account_filter`.
|
||||
- **Post-Retrieval Verification**: Single object retrievals (`GET`), updates (`PATCH`), and deletions (`DELETE`) include a secondary ownership check (`check_account_access`). If a user attempts to access an ID belonging to another account, they receive a `403 Forbidden` response.
|
||||
- **Hierarchical Verification**: Child/Nested endpoints verify the ownership of the parent object before allowing operations on children, preventing cross-tenant "sideways" traversal.
|
||||
- **Creation Guard**: When creating records (`POST`), the user's `account_id` is automatically forced onto the new record, preventing a user from creating data for another account.
|
||||
|
||||
### Bypass and Utility Access
|
||||
- **X-No-Account-ID**: A specialized header used by development utilities and administrative scripts to bypass standard account isolation. This header grants `super` permissions and should only be used in trusted internal environments.
|
||||
- **JWT Query Parameter**: Supported for direct file downloads and sharing links where custom headers cannot be provided.
|
||||
|
||||
Reference in New Issue
Block a user