Auth matrix at scale: testing N×N role pairs automatically
Every IDOR scanner on the market works the same way: take two user sessions, replay requests from user A with user B's credentials, and flag anything that returns 200. This catches the obvious case — two same-role users accessing each other's data. But it misses an entire category of authorization failures: vertical privilege escalation across role boundaries.
If your application has four roles (admin, manager, member, anonymous), a two-user scan tests exactly one pair. There are twelve directional pairs. You're testing 8% of the attack surface and calling it covered. That's not a security audit — it's a spot check.
Why two-user testing isn't enough
Consider a SaaS application with a typical RBAC model: org admin, team lead, member, and billing-only user. A two-user scan with two member accounts will find horizontal IDORs — member A reading member B's data. But it will never find:
- A member accessing the billing portal (cross-role, same privilege tier)
- A team lead accessing org admin settings (vertical escalation, adjacent tier)
- An anonymous user accessing member-only API endpoints (authentication bypass)
- A billing user accessing team management endpoints (lateral movement across functional boundaries)
These aren't theoretical. In our analysis of 200 scan results from BrokenApp users, 34% of confirmed authorization failures were cross-role — meaning they would never have been caught by a same-role two-user scan. The highest-severity findings were disproportionately in this category.
How the auth matrix works
BrokenApp's auth matrix takes a fundamentally different approach. Instead of comparing two users, you define every role in your system and provide credentials for each. The CLI then tests every ordered pair: for N roles, it runs N×(N-1) directional comparisons.
Configuration lives in a roles.toml file that maps role names to session credentials. Each role gets a cookie, a bearer token, or a set of headers — whatever your application uses for authentication.
# roles.toml
[admin]
cookie = "session=eyJhb...admin"
tier = "admin"
[team_lead]
cookie = "session=eyJhb...lead"
tier = "staff"
[member]
cookie = "session=eyJhb...member"
tier = "user"
[anonymous]
cookie = ""
tier = "none"
The tier field is optional but important: it tells BrokenApp about the expected privilege hierarchy. When a lower-tier role accesses a higher-tier endpoint, the finding is automatically classified as a vertical escalation — which typically gets a higher severity rating.
The N×(N-1) pair approach
With four roles defined, BrokenApp runs 12 directional scans. Direction matters: "member accessing admin endpoints" is a critical finding; "admin accessing member endpoints" is expected behavior. By testing every ordered pair, the matrix captures both escalation directions and flags only the ones that violate the expected hierarchy.
The scan process works in three phases. First, BrokenApp crawls the application once per role, recording every endpoint each role can reach and the responses they receive. Second, it builds the cross-role replay set: for every endpoint that role A reached, it replays the request with role B's credentials. Third, it compares responses using the same body-similarity scoring used in standard IDOR detection — but now with role context attached.
$ brokenapp auth-matrix --roles roles.toml --url https://app.example.com
Scanning as admin... 47 endpoints captured
Scanning as team_lead... 38 endpoints captured
Scanning as member... 29 endpoints captured
Scanning as anonymous... 12 endpoints captured
Running 12 cross-role replays...
Replay complete. 1,128 requests analyzed.
Real examples of missed escalation paths
During our beta, one team ran the auth matrix against their multi-tenant project management tool. Their existing two-user scan (member vs. member) had found three IDORs — all horizontal, all read-only. The auth matrix found eleven additional findings:
member → admin: billing endpoint
POST /api/billing/invoices was protected by a UI-only gate. The middleware checked authentication but not the admin role. Any authenticated user could generate invoices.
anonymous → member: file uploads
GET /api/files/:id returned signed S3 URLs without checking session validity. Unauthenticated users could access any uploaded file if they had the ID.
team_lead → admin: user management
PUT /api/users/:id/role allowed team leads to promote users to admin. The endpoint checked for 'staff' tier but not specifically for 'admin' tier.
billing → member: project data
The billing role was intended to be scoped to financial data only, but GET /api/projects/:id/tasks returned full project details to any authenticated session.
None of these would have appeared in a member-vs-member scan. The billing endpoint escalation — the most critical finding — required testing a lower-tier role against a higher-tier endpoint, which only the full matrix covers.
Interpreting the heatmap output
The auth matrix outputs a grid where rows represent the "attacker" role (the role whose credentials are being used) and columns represent the "target" role (the role whose endpoints are being accessed). Each cell shows the number of endpoints where the attacker successfully accessed the target's resources.
admin team_lead member anon
admin — — — —
team_lead 3 — — —
member 5 2 — —
anonymous 2 1 4 —
✓ 17 authorization failures
5 critical | 8 high | 4 medium
Reading this matrix: the anonymous row is the most alarming. Anonymous users can access 2 admin endpoints, 1 team lead endpoint, and 4 member endpoints. These are authentication bypasses — the most severe class of authorization failure. The member row shows 5 admin endpoint accesses, indicating vertical escalation. The diagonal is always empty (a role accessing its own endpoints is expected).
BrokenApp also generates a JSON report with the full endpoint list for each cell, so you can drill into exactly which routes are affected and prioritize remediation.
Compliance implications
If you're subject to SOC 2, PCI DSS, or HIPAA, the auth matrix output maps directly to control requirements. SOC 2 CC6.1 requires logical access controls that restrict access based on role. PCI DSS Requirement 7 mandates least-privilege access to cardholder data. HIPAA's access control standard (164.312(a)) requires that only authorized users access ePHI.
A passing auth matrix — where the only non-zero cells are in expected directions (higher roles accessing lower-tier endpoints) — serves as evidence that your application enforces role-based access control at the API level, not just the UI level. Auditors care about the API level because that's what an attacker interacts with.
# Export compliance-ready report
$ brokenapp auth-matrix --roles roles.toml --format pdf --output auth-matrix-report.pdf
Report includes: matrix heatmap, endpoint-level findings,
CWE mappings, OWASP references, and remediation guidance.
Run the auth matrix as part of your CI pipeline and you get continuous compliance evidence — not a point-in-time snapshot from a yearly pentest, but proof that every deploy enforces the access control model your compliance documentation describes.