admin-authorization
The most common critical bug in vibe-coded apps:
is "protected" because the link is hidden, and the API behind it answers anyone. This skill checks the server, where authorization actually lives.
Activate when
- Any admin/staff/operator route or API exists (, , , role fields, "isAdmin" checks), or roles/permissions exist.
- / routes here.
- Not to design admin features (that is , which calls this skill for access control). If the only "admin" is the database console, say so.
Inspect
- Enumerate privileged surfaces from routes, API handlers, server actions, database policies, and UI conditionals: user management, content moderation, refunds, exports, impersonation, feature flags, settings, data deletion, "run job" endpoints, internal tools.
- For each, find the check: authentication (who are you?) and authorization (may you do this on this object?) executed on the server at the handler, middleware, or database policy. Client-side route guards, hidden links, in React, and obscure URLs are not authorization.
- Roles and grants: where roles come from (database column, JWT claim, provider metadata); can a user modify their own role via any endpoint (mass assignment: accepting )? First-user-becomes-admin logic; default/seed admins with default passwords; invite/reset flows for staff.
- Object-level access: an admin's or user's request for another resource ID (); listing endpoints returning all users' data to non-admins; database row-level security present for tables holding admin-only or per-user data.
- Test on local/staging (never against production or other people's accounts): request each privileged route/API (a) with no session, (b) with a normal test user, (c) with an admin test user. Expect (a) and (b) denied (401/403, not a 200 with empty data and not a redirect that still leaks data), (c) allowed. Also try direct API calls that bypass the UI, and ID substitution.
- Discoverability: admin routes not in the sitemap or as a hint (); consistent ; login page protections: rate limiting, no user enumeration, MFA where the product warrants.
- Sensitive destructive actions: confirmation, and an audit trail ().
Evidence that counts
Label each claim OBSERVED, SOURCE-INDICATED, DECLARED, INFERRED, UNKNOWN, or REVIEW REQUIRED. UNKNOWN is never a pass and never a failure.
- Denied/allowed behavior seen in requests as specific test users: OBSERVED. A check present in source: SOURCE-INDICATED (it may not run on every path).
- A protected route with an unprotected sibling API is still a hole; report both.
- Third-party admin tools (provider dashboards) are outside the codebase: UNKNOWN.
May change
Add server-side authentication and authorization checks to privileged handlers following the project's pattern (middleware, guards, RLS policies); remove role fields from writable user endpoints; remove default credentials from seeds; return proper 401/403; add a "no admin surface" note when true. Do not build a new admin interface, invent a role model, or change production users.
Must not claim
"Secure admin area", "role-based access implemented", or "authorized" from UI conditionals. Report which endpoints you tested as which principals.
Verify
Repeat the anonymous / normal-user / admin request matrix on every changed handler and the sibling API routes; confirm the UI still works for admins; confirm no data returns to non-admins in error bodies.
Escalate
Any privileged route reachable by unauthorized principals: HIGH, fix or block before launch and tell the owner. Systems handling money, health, or others' personal data: recommend an independent security review. Real user data exposure: stop and report.
No change is valid when
No privileged surfaces exist, or every one demonstrably enforces server-side authorization. Do not add roles to a product with one user type.