unboundcompute/security-agent-skills/auditing-declarative-authorization
Claude Code and agent skill by unboundcompute/security-agent-skills
- community
Checking that the SKILL.md file is still in the repository.
Audit authorization expressed as configuration or framework convention rather than inline code: row-level security and policy rules, framework before-action and middleware filters that must be attached to every protected route, serverless and gateway access rules, and object-ownership checks. Covers routes that skip the filter, policies with a permissive default, rules that check authentication but not ownership, and gaps between where the rule is declared and where the data is accessed. Use when reviewing role- or policy-driven access control. Coverage and correctness are separate checks.
Install
npx vskill@latest install unboundcompute/security-agent-skills/auditing-declarative-authorizationSKILL.md
Auditing declarative authorization: coverage and correctness are two audits
Modern authorization is often declarative: a policy attached to a table, a filter registered on a controller, a rule in a gateway or serverless config. The strength of that model is also its weakness, security depends on the rule being attached to every path that needs it, and on the rule actually expressing the intended constraint. The failures are gaps (a route the filter never covers) and mis-statements (a rule that checks the wrong thing), and both are invisible if you only read the routes that are protected.
When to use
- You are reviewing role- or policy-driven access control.
- Authorization is enforced by row-level policies, controller filters, middleware, or
gateway rules.
- Protection depends on a rule being attached per route, per table, or per resource.
Scope check
Audit access control in systems you own or are authorized to test, with test accounts across roles and tenants. If you can't name the authorization, stop.
The loop
- Locate every declared rule and its scope. Inventory the authorization rules:
row-level policies, controller filters, middleware, gateway or serverless access rules, and ownership checks. For each, determine exactly which paths, tables, or resources it covers. The audit is about coverage and correctness, so start by mapping what each rule protects.
- Find the paths the rule does not cover. Enumerate every route, query, or
resource access and check which are not covered by any rule. A framework filter that must be added per controller is missing wherever a developer forgot it; a policy on one table does not protect a sibling table or a raw query that bypasses the policy layer. The uncovered path is the bug.
- Check the default of the policy layer. When no rule matches, does access default
to deny or allow? A row-level-security system with policies enabled but a permissive fallback, or a gateway that allows unmatched routes, grants access wherever a rule is absent. Confirm the default is deny.
- Check that the rule states ownership, not just presence. Does the rule confirm
this user may access this specific object, or only that the user is authenticated? A filter that checks "logged in" but not "owns this record," or a policy that scopes by table but not by row or tenant, lets any authenticated user reach another's data. Authentication is not authorization.
- Check the declaration-to-access gap. Is the rule enforced at the same layer the
data is actually accessed, or can a code path reach the data beneath the rule (a raw query under row-level security, a direct service call under a gateway rule, an admin path that skips the middleware)? A rule declared in one place and data reached in another is unenforced there.
- Confirm and record. Confirm a gap by accessing a protected resource through the
uncovered path or as the wrong user; confirm a mis-statement by reaching another user's object through the rule. Kill the lead if every path is covered, the default is deny, and rules enforce ownership at the access layer. Record with the exact uncovered path or wrong-object access.
Where declarative authz leaks
- Coverage is per path, correctness is per rule. Check both; the protected routes
tell you nothing about the unprotected ones.
- The default when no rule matches is the whole ballgame. Deny-by-default contains
mistakes; allow-by-default amplifies them.
- Authenticated is not authorized. A filter that stops at identity, not ownership,
is a horizontal-access bug.
- Rules and data can drift apart. A path that reaches the data below the rule's
layer is unprotected no matter how the rule reads.
Worked example (a confirm and a kill)
Confirm. An app enforces access with a per-controller before-action filter. Anewer controller exposing the same records was added without the filter. Requestingthose records through the new controller returns any user's data with only a validsession. Confirmed missing-filter gap,high, remediation = enforceauthorization globally with explicit opt-out, or add the filter and a test that everycontroller is covered.Kill. Row-level security is enabled with a deny-by-default fallback, every tablehas an ownership-scoped policy keyed to the tenant and user, raw queries run under thesame policy, and no code path reaches the data beneath the policy layer. Cross-userand uncovered-path attempts return nothing. Killed,kill_reason="deny-by-default, ownership-scoped policies on every table enforced at the data layer,no bypass path."
Rationalizations to reject
- "Authorization is handled by the framework." → Only where the rule is attached.
Enumerate the paths that lack it.
- "The policy is enabled." → Enabled with what default and what scope? A permissive
default or table-only scope still leaks.
- "The user is authenticated." → Authentication is not ownership. Check that the rule
constrains which object, not just which user.
- "The rule is declared on the model." → And the data is reached where? A path under
the rule's layer is unprotected.
Executing this in practice
You need the full set of declared rules and their scopes, a complete enumeration of routes and data accesses to find the uncovered ones, and the ability to request protected resources through each path and as different users. A call graph that maps every access to the data and shows which are covered by a guard is ideal; the coverage-and-correctness pass is the method.
Related
auditing-guard-gaps- the unguarded-peer pattern, here applied to declarative
rules and routes.
finding-fail-open-flaws- the permissive-default failure mode of a policy layer.hunting-business-logic-flaws- authorization of outcomes reached through a
permitted path.
- FINDING-SCHEMA.md - source = the uncovered path or
wrong-user request, sink = the protected resource it reaches.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/auditing-declarative-authorization/SKILL.md
Popularity
- Repository stars
- 5
- Repository forks
- 2
- 7-day trend score
- 9
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/unboundcompute/security-agent-skills/auditing-declarative-authorization)