SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%
3.4 KB · 47 lines markdown
Rendered Raw Blame History
1---2name: implementing-authorization3description: Implements permission decisions in backend services — RBAC/ABAC models, resource-ownership checks, IDOR prevention, multi-tenant isolation, and centralized policy enforcement. Use when the user asks to add roles, permissions, access control, admin-only routes, ownership checks, tenant isolation, or asks why a user can see another user's data. Do not use for identity verification and login flows (implementing-authentication) or OS and file-system permissions.4---56<!--7Author: Simon-Pierre Boucher8Contact: contact@spboucher.ai9-->1011# Implementing Authorization1213## When to use / when NOT to use14- **Use for:** deciding what an authenticated caller may do — roles, permissions, ownership checks, tenant isolation, policy middleware, privileged-action auditing.15- **Do NOT use for:** logging users in (implementing-authentication), database GRANTs (db-skills/securing-databases), or OS/file permissions.1617## Core rules18191. **Authorize on every request, server-side.** Client-side hiding of buttons is UX, not security.202. **Deny by default.** Routes without an explicit policy are rejected, not allowed.21   -`@require(perm="reports:read")` on each route; unannotated routes 403 in middleware22   - ❌ "Only add checks to the sensitive endpoints"233. **RBAC is the default model** (user → roles → permissions). Reach for ABAC (attribute rules) only when decisions depend on resource attributes (owner, status, amount thresholds).244. **Authentication is not authorization — check ownership.** Fetching by ID must scope to the caller.25   -`SELECT ... WHERE id = :id AND owner_id = :caller`26   -`SELECT ... WHERE id = :id` after login — classic IDOR275. **Multi-tenant: scope every query by `tenant_id`,** derived from the session/token — never from the request body or URL. Use Postgres row-level security as a backstop where available.286. **Centralize policy in one module/middleware.** Scattered `if user.role == "admin"` checks drift and rot; route handlers call `authorize(caller, action, resource)` and nothing else.297. **Audit privileged actions** (role grants, data exports, deletions): who, what, when, from where — to an append-only log.3031## Workflow32331. Enumerate actions and resources; write the permission matrix (roles × actions) before code.342. Implement the central `authorize()` + deny-by-default middleware (rule 2, 6).353. Add ownership/tenant scoping at the data layer (rules 4–5) so a missed route check cannot leak cross-tenant data.364. Wire the audit log for privileged actions (rule 7).375. **Validate:** as user A, request user B's resource by ID (expect 403/404); as a role without the permission, call each privileged route (expect 403); confirm an unannotated test route is rejected by default. All three must pass before shipping.3839## Edge cases & failure modes40- **403 vs 404:** return 404 for resources the caller must not know exist (cross-tenant); 403 within a tenant where existence is not secret. Pick per resource and stay consistent.41- **Role changes mid-session** → re-read roles per request (or short cache ≤60 s); revoke sessions on demotion.42- **Background jobs and internal services** → they get their own scoped identities, never a shared "system = superuser" that skips `authorize()`.43- **Batch endpoints** → authorize each item, not just the endpoint; report per-item denials.4445## References46Copy-paste patterns and gotchas: see [references/patterns.md](references/patterns.md).47