Serious notes about security updates.

This commit is contained in:
Scott Idem
2026-02-13 19:22:33 -05:00
parent aca15aab91
commit 577d784fb8
2 changed files with 22 additions and 11 deletions

View File

@@ -65,7 +65,10 @@ Implemented in Jan 2026, the V3 architecture enforces strict data isolation and
- **Role Scoping**: These flags are used to bypass account isolation for support and system maintenance tasks.
### Multi-Tenant Isolation
- **Fail-Closed Strategy (Feb 2026)**: The API enforces a strict "Fail-Closed" mindset. If an authentication context or account ID is missing, the system defaults to a blocking filter (e.g., `account_id IS NULL`). It no longer allows "Fail-Open" behavior where missing context returns all records.
- **IDAA Privacy Baseline**: Based on the International Drunk Doctors Anonymous requirement, the system defaults to **Maximum Isolation**. No object (Events, Files, Posts, Meetings) is public by default. Every object requires an `x-account-id` context, with the sole exception of `site_domain` used for bootstrapping.
- **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`.
- **Detailed 403 Feedback**: Security failures now return descriptive error messages (e.g., "API Key expired", "Account context required") to assist developers in debugging header/context issues while maintaining strict isolation.
- **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.