[Explainer]

What a whole-repo authorization scan reads

The access-control surface of a repository, read the way a researcher reads it: routes, gates, tenant bindings, and the object references behind them.

Aevral,

Authorization failures are the quiet ones. Some injection patterns announce themselves in the string; a missing ownership check just lets the request through. The code runs, the tests pass, and the only thing that changed is who has access to what. That is the surface Aevral reads, and this page is exactly what that means.

The surface it reads

A repository's access-control surface has four recurring shapes. Routes: which handlers exist and what mounts them, including the debug ones. Gates: the role checks, ownership assertions, and middleware that decide who gets in. Tenant bindings: where the tenant or organization id comes from, because a value the caller names and a value the session carries are different security facts. Object references: the ids passed to queries, because an attacker-controlled key on a row lookup is the Broken Object Level Authorization shape (OWASP API1:2023), an entry whose related weaknesses include CWE-639, Authorization Bypass Through User-Controlled Key.

The class vocabulary maps cleanly. IDOR and BOLA are the object-level failure: the caller names the record. Broken Function Level Authorization (OWASP API5:2023) is the gate failure: the route itself is under-guarded, a shape within the broader CWE-284 category, Improper Access Control. Aevral's three reading classes, authorization, IDOR, and business-logic access control, cover exactly this family and nothing else.

Why cross-file context is the job

An authorization rule is rarely one line. The gate lives in middleware, the handler assumes it, the ORM scopes the query, and the role check sits three files from the route it guards. A change to any one of them moves the rule, which is why reading authorization is cross-file by nature: the unit of meaning is the rule, not the line.

The prefix-match bug is the canonical example. An equality check on the organization id becomes a startsWith check to support a planned hierarchy, and suddenly org acme-1 matches user org acme. Nothing in that line looks wrong. The finding is only visible against the rule the change quietly rewrote, which lives across the files that define who may access what.

What comes out

A scan runs on your trigger from the console, on the default-branch snapshot, at rest. You get a GitHub Check on the scanned commit and the full report in the console. Each finding carries its evidence: the file, the lines, and the reason a human should look, plus a fix prompt you can hand to your coding agent.

A finding is a lead, not a confirmation. Aevral runs no validation pass on findings and generates no patches; a scan is not a clean bill of health. The human decides, which is the only part of the loop that should not be automated.

What it is not

It is not a general SAST: no memory-corruption classes, no injection classes. It is not a secrets scanner, not a dependency scanner, not a pentest, and it does not replace any of them; the works-alongside pages map that boundary honestly.

Sources

OWASP API1:2023 Broken Object Level Authorization; OWASP API5:2023 Broken Function Level Authorization; CWE-639: Authorization Bypass Through User-Controlled Key; CWE-284: Improper Access Control.

Read next

The scan product; Aevral and Claude Security; Works alongside your stack.

More guides


Scan your whole repo for access bugs.

One GitHub App. A report with evidence. A prompt for the agent you already use.