Guide / 2026-09-28

How to review an AI-generated access-control PR

Use a permission matrix and cross-user tests to review an agent-written authentication or authorization change before merge.

Canopy pull request review beside an agent's findings and code diff
Canopy pull request review beside an agent's findings and code diff

A login screen can work while a signed-in person can still read another person's data. When an agent changes authentication, roles, database policies, or a private API, review the exact permission being granted. This guide uses an example invoice PR to turn that question into a small test matrix, a trace through the server and database, and a clear merge decision. It is a review aid, not a security certification.

Write the permission rule before reading the diff

Imagine a PR that lets a team member open an invoice. The intended rule might be: an active member of the invoice's team may view it; only a billing admin may edit it; outsiders and signed-out visitors may do neither. Have the product owner confirm that rule before asking whether the implementation is correct. Authentication answers who the caller is; authorization answers whether this caller may perform this action on this object now. OWASP recommends defining the allowed operations for each user and resource and denying access by default.

Example review matrix. Replace these rules with your product's actual policy before testing.
CallerInvoiceExpected readExpected edit
Signed-out visitorAny private invoiceDenyDeny
Team memberOwn team's invoiceAllowDeny
Different memberAnother team's invoiceDenyDeny
Billing adminOwn team's invoiceAllowAllow
Removed memberFormer team's invoiceDenyDeny

Follow the request beyond the visible button

Find every changed route, server action, query, database migration, and policy that can read or edit an invoice. A hidden link or disabled Edit button does not establish server-side authorization. Check that the server identifies the current caller and checks the action against the requested invoice rather than trusting a client-supplied team ID or role. Then try the same request with an invoice ID belonging to another team. OWASP calls this object-level authorization: a valid login and a hard-to-guess ID do not themselves grant access. Check list, detail, export, attachment, update, and delete paths that the PR touches; a guard on one page may leave another route open.

  • Record the PR head commit, the route or query inspected, and the exact rule enforced there.
  • Test an unauthorized request at the API or database boundary, not only by clicking the UI.
  • If the intended policy is ambiguous, stop the approval and ask the owner to decide it.

Inspect database and credential changes

If the app uses Supabase, review both table grants and row-level security policies for the affected table. Supabase documents that grants determine which operations a role can attempt while RLS policies determine which rows those operations reach. Confirm RLS is enabled for exposed tables, policies match the example matrix, and tests use distinct users and teams. A privileged secret key can bypass RLS for administrative work and must stay server-side; its presence in browser code is a blocker. For another database or auth provider, inspect its equivalent backend enforcement and test under the actual production roles. Review new dependencies and lockfile changes separately; GitHub's dependency review can show package changes where enabled.

  • Look at migration order and existing grants, not only the new policy text.
  • Check whether a privileged server client is being used for ordinary user requests.
  • Inspect changed environment files and client bundles for credential exposure without pasting secrets into an agent prompt or public PR comment.

Ask a second agent for evidence, then reproduce it

Give a reviewer agent read-only scope, the approved permission matrix, and the PR's latest commit. Ask it to list every affected entry point, cite a file and line for each finding, and separate proven bypasses from untested hypotheses. A human should open the cited code and run the cross-user case with disposable accounts or fixtures. If an agent cannot run the app or lacks access to test users, its output is a review plan, not proof that the change is safe. Keep the implementing and reviewing sessions tied to the same commit so a later fix does not silently invalidate the review.

  • Capture the request, expected denial, observed status and response, and the test account's role.
  • Confirm an allowed request still works; an always-deny rule can hide a broken feature.
  • After a fix, re-run the failed case and inspect the newest diff and CI checks.

Decide what is ready to merge

Approval needs a confirmed product rule, reviewed server and data paths, allowed and denied test results, and the latest PR diff. If the PR changes payment authority, broad tenant access, production credentials, or another high-impact boundary, ask a qualified owner or security reviewer to assess the change. Do not turn a green CI badge into a claim that unconfigured cross-user tests ran. Record the remaining uncertainty and who accepts it. The general PR review guide covers comment and CI follow-up; this page supplies the permission-specific evidence those steps need.

Copyable resources

Read-only access-control reviewer prompt

Use test accounts and fixtures. Do not give the reviewer production secrets or permission to approve or merge.

Review PR [link] at head commit [SHA] against this approved permission rule: [who may read/edit which object]. Do not edit files, post comments, approve, or merge. Map every changed UI, API, server action, query, migration, and database policy that affects this rule. For each possible bypass, give file/line, caller and object, request path, expected result, and evidence. Separate confirmed findings from cases that need a human test. Check signed-out, own-team, other-team, admin, and removed-member cases. List tests and CI results you actually inspected, and identify any credential or dependency changes. End with the cases still unverified.

Frequently asked questions

Is a working login screen enough to approve an authentication PR?

No. A signed-in user may still reach an object or action they should not. Confirm the intended permission rule and test it at the server and data boundary.

What is the fastest useful negative test?

With a disposable signed-in account from another team, request the changed object's ID directly through the affected API or query and verify denial. Also confirm the allowed account still succeeds.

Can an AI reviewer sign off on access control?

It can propose paths and findings. A person must verify the rule, reproduction, and final diff and own the repository's approval decision.

Does Supabase RLS remove the need to inspect backend code?

No. Check both grants and policies and whether a privileged server client or another route bypasses the intended user-scoped access.

Browse more Canopy questions →

Sources and further reading