===================== Security Cheatsheet ===================== Quick, practical defaults for secure apps. Properties and Hooks -------------------- - Return `None` from a property hook to hide/deny: - GET → hide property in UI and API - PUT/POST → make property read-only/immutable - Store sensitive data in Attributes (buckets), not regular properties. Access Control -------------- - Prefer built-in trust types: `viewer`, `friend`, `partner`, `admin`, `mcp_client`. - Add custom trust types only when necessary; use pattern-based permissions. - Precedence: Explicit deny > explicit allow > trust type allow > default deny. - **Permission merging**: Individual overrides UNION with base patterns (fail-safe). - To restrict access, use `excluded_patterns`; base `patterns` cannot be narrowed. - Use `merge_base=False` only when explicit full override is needed. OAuth2 ------ - Always validate provider config; use the provider-agnostic factory. - Google: refresh tokens available; GitHub: no refresh tokens. - GitHub: only verified primary emails are accepted for actor linking. Unverified primary emails are skipped to prevent account-linking attacks via the GitHub ``/user/emails`` API. - Expect 401 at protected endpoints with a proper `WWW-Authenticate` header. - When multiple providers are configured, 401 redirects go to the factory login page (not directly to a provider) to let the user choose. Custom Routes ------------- - For custom routes, use `auth.check_and_verify_auth()` instead of ad-hoc authentication. - Always validate the `actor_id` parameter matches the authenticated user. - Handle OAuth2 redirects properly (302 responses with Location header). Web UI ------ - Enable UI only when needed; it enforces OAuth2 when configured. - Never use relative links in templates; use `actor_root` and `actor_www`. Data Backend ------------ - Local dev: use DynamoDB Local with `AWS_DB_HOST` set. - Production: use IAM with least privilege and do not set `AWS_DB_HOST`.