Web Authorization
Purpose
Plan who may do what once authenticated: the role/permission model, where the server enforces it (every API call, server action, and data query), and how the client mirrors those decisions for UX (guarded routes, hidden controls) without ever being the gate.
When to Use
- When the app has more than one access level (customer vs admin, tiers, tenants).
- Before building any dashboard surface (feeds
dashboard-permissions).
- Not for identity/login itself (
web-authentication).
Inputs
- The access model from requirements: roles, permissions, tenancy, ownership rules.
- Route tree (
web-routing) and API surface (web-api-integration).
- Dashboard placement (
dashboard-architecture) — separate apps simplify some boundaries.
Discovery Questions
- Roles, granular permissions, or both — and who administers them?
- Is data tenant-scoped or owner-scoped (every query filters by it)?
- Which UI surfaces differ per role (nav, actions, whole route groups)?
- How does the client learn the user's permissions (session claims, profile endpoint) and how stale may that be?
Responsibilities
- Define the model: roles → permissions mapping (prefer permission checks in code over role string checks; roles group permissions).
- Map server enforcement points: every API route/server action checks permission; every query scopes by tenant/owner — deny by default.
- Plan client mirroring: route guards, hidden/disabled controls, role-aware nav — explicitly labeled convenience, backed by server checks.
- Plan permission delivery to the client (claims in session, permissions endpoint) and its refresh on role change.
- Route admin-surface depth (granularity, audit, impersonation) to
dashboard-permissions.
Required Workflow
- Extract the access model from requirements; enumerate roles/permissions/tenancy.
- Map each API operation and route to its required permission (deny by default).
- Plan client mirroring for routes/controls per role.
- Define permission delivery + staleness handling.
- Record the matrix; hand admin specifics to
dashboard-permissions and review to ../../security-review.
Decision Rules
- Deny by default: an operation without a declared permission requirement is a finding, not a pass.
- Check permissions, not roles, at call sites — roles change shape; permissions compose.
- Tenant/ownership scoping lives in the data layer (query-level), not in UI filtering.
- If customer and admin audiences share the app, prefer coarse boundaries (route group + server checks) over sprinkling conditionals (
dashboard-architecture).
Rules
- Hidden UI is not access control; every privileged action re-verifies server-side.
- Authorization failures return consistent, non-leaking responses (404 vs 403 policy decided once).
- Changes to roles/permissions take effect without requiring client redeploys where feasible.
Anti-Patterns
if (user.role === 'admin') scattered through components as the only check.
- APIs trusting a role claim sent from the client body/header.
- Queries returning all rows with the client filtering "their" data.
- Divergence between what UI shows and what the API allows, discovered by users.
Validation Checklist
Definition of Done
A recorded authorization plan — model, server enforcement matrix, query-level scoping, and client mirroring — where removing every client-side check would inconvenience users but expose nothing.
Related Skills
web-authentication, dashboard-permissions, web-routing, web-api-integration, dashboard-architecture, ../../security-review.
Related Knowledge
../../../knowledge/ (access model, tenancy design).
Related References
../../../references/web/dashboard/ (permission matrices — when populated).
Context Loading Guidance
- Requires: access model, route tree, API surface.
- Does not require: UI styling detail, unrelated features.
- May load:
dashboard-permissions for admin depth; ../../security-review for verification.
- Stop when: the enforcement matrix is recorded.
Token Efficiency Guidance
Express the model as a permission matrix (operation × permission), not per-screen prose. State the deny-by-default rule once.
1---2name: web-authorization3description: Use to plan web authorization — the role/permission model, server-side enforcement on every request and action, route guards and UI hiding as UX conveniences, and tenant scoping. UI hiding is never access control; the server verifies everything.4---56# Web Authorization78## Purpose910Plan who may do what once authenticated: the role/permission model, where the server enforces it (every API call, server action, and data query), and how the client mirrors those decisions for UX (guarded routes, hidden controls) without ever being the gate.1112## When to Use1314- When the app has more than one access level (customer vs admin, tiers, tenants).15- Before building any dashboard surface (feeds `dashboard-permissions`).16- **Not** for identity/login itself (`web-authentication`).1718## Inputs1920- The access model from requirements: roles, permissions, tenancy, ownership rules.21- Route tree (`web-routing`) and API surface (`web-api-integration`).22- Dashboard placement (`dashboard-architecture`) — separate apps simplify some boundaries.2324## Discovery Questions2526- Roles, granular permissions, or both — and who administers them?27- Is data tenant-scoped or owner-scoped (every query filters by it)?28- Which UI surfaces differ per role (nav, actions, whole route groups)?29- How does the client learn the user's permissions (session claims, profile endpoint) and how stale may that be?3031## Responsibilities3233- Define the **model**: roles → permissions mapping (prefer permission checks in code over role string checks; roles group permissions).34- Map **server enforcement points**: every API route/server action checks permission; every query scopes by tenant/owner — deny by default.35- Plan **client mirroring**: route guards, hidden/disabled controls, role-aware nav — explicitly labeled convenience, backed by server checks.36- Plan **permission delivery** to the client (claims in session, permissions endpoint) and its refresh on role change.37- Route admin-surface depth (granularity, audit, impersonation) to `dashboard-permissions`.3839## Required Workflow40411. Extract the access model from requirements; enumerate roles/permissions/tenancy.422. Map each API operation and route to its required permission (deny by default).433. Plan client mirroring for routes/controls per role.444. Define permission delivery + staleness handling.455. Record the matrix; hand admin specifics to `dashboard-permissions` and review to `../../security-review`.4647## Decision Rules4849- **Deny by default**: an operation without a declared permission requirement is a finding, not a pass.50- Check permissions, not roles, at call sites — roles change shape; permissions compose.51- Tenant/ownership scoping lives in the data layer (query-level), not in UI filtering.52- If customer and admin audiences share the app, prefer coarse boundaries (route group + server checks) over sprinkling conditionals (`dashboard-architecture`).5354## Rules5556- Hidden UI is not access control; every privileged action re-verifies server-side.57- Authorization failures return consistent, non-leaking responses (404 vs 403 policy decided once).58- Changes to roles/permissions take effect without requiring client redeploys where feasible.5960## Anti-Patterns6162- `if (user.role === 'admin')` scattered through components as the only check.63- APIs trusting a role claim sent from the client body/header.64- Queries returning all rows with the client filtering "their" data.65- Divergence between what UI shows and what the API allows, discovered by users.6667## Validation Checklist6869- [ ] Role/permission model defined; permissions (not roles) checked at call sites.70- [ ] Every API operation mapped to a required permission; deny-by-default confirmed.71- [ ] Tenant/ownership scoping planned at the query level.72- [ ] Client mirroring planned and labeled as convenience.73- [ ] Permission delivery + staleness handling defined.7475## Definition of Done7677A recorded authorization plan — model, server enforcement matrix, query-level scoping, and client mirroring — where removing every client-side check would inconvenience users but expose nothing.7879## Related Skills8081`web-authentication`, `dashboard-permissions`, `web-routing`, `web-api-integration`, `dashboard-architecture`, `../../security-review`.8283## Related Knowledge8485`../../../knowledge/` (access model, tenancy design).8687## Related References8889`../../../references/web/dashboard/` (permission matrices — when populated).9091## Context Loading Guidance9293- **Requires:** access model, route tree, API surface.94- **Does not require:** UI styling detail, unrelated features.95- **May load:** `dashboard-permissions` for admin depth; `../../security-review` for verification.96- **Stop when:** the enforcement matrix is recorded.9798## Token Efficiency Guidance99100Express the model as a permission matrix (operation × permission), not per-screen prose. State the deny-by-default rule once.