No cross-tenant access proven34 cross-tenant attempts against 11 endpoints were refused by the application, using real credentials for a second tenant. A further 24 attempts could not be judged and count as neither. This covers what was probed — not the whole application.
Scope
Target
http://127.0.0.1:8002
Started
2026-07-27T14:21:17+00:00
Duration
0.6s
Tool
tenanttrace 0.1.0
Surface probed
11 endpoints of 11 reachable · 12 operations declared, the rest outside this run's shape
None. Every cross-tenant attempt below was refused by the application.
Run integrity
Why the answer above can be trusted: the checks that prove the harness worked, and what the application refused.
Positive controls
✓self-access:A — tenant A read its own object via GET /api/documents/{document_id}
✓self-access:B — tenant B read its own object via GET /api/documents/{document_id}
✓self-access:A:closing — tenant A read its own object via GET /api/documents/{document_id}
✓self-access:B:closing — tenant B read its own object via GET /api/documents/{document_id}
What was checked and held
34 cross-tenant attempts were correctly refused.
attack
refused
aggregate
6
cache
4
idor
8
listing
8
mass_assign
8
24 attempts were inconclusive — the oracle could not decide, which is not the same as enforcement.
GET /api/admin/all-invoices (listing) — excluded by [tenancy] cross_tenant_allowlist, so it was not attacked
GET /api/admin/all-invoices (listing) — excluded by [tenancy] cross_tenant_allowlist, so it was not attacked
GET /api/admin/all-invoices (param_override) — excluded by [tenancy] cross_tenant_allowlist, so it was not attacked
GET /api/customers (param_override) — every one of 1 query-parameter spellings was refused; the endpoint does not honour a client-supplied tenant
GET /api/documents (param_override) — every one of 1 query-parameter spellings was refused; the endpoint does not honour a client-supplied tenant
GET /api/invoices (param_override) — every one of 1 query-parameter spellings was refused; the endpoint does not honour a client-supplied tenant
GET /api/stats (param_override) — every one of 1 query-parameter spellings was refused; the endpoint does not honour a client-supplied tenant
GET /api/admin/all-invoices (param_override) — excluded by [tenancy] cross_tenant_allowlist, so it was not attacked
GET /api/customers (param_override) — every one of 1 query-parameter spellings was refused; the endpoint does not honour a client-supplied tenant
GET /api/documents (param_override) — every one of 1 query-parameter spellings was refused; the endpoint does not honour a client-supplied tenant
Run notes
1 endpoint skipped by [probe] exclude_paths
How to read this report
Confirmed
A canary planted in another tenant's data came back in this tenant's response, or an exact count did not match. Proven, not inferred — these are the only findings that fail CI by default.
Suspected
A hypothesis from reading the source: a query that looks unscoped. It has not been reproduced over HTTP and never gates a build on its own.
Positive control
A tenant reading its own data. If that fails, the harness is broken and an empty finding list means nothing — so the run is marked INVALID rather than clean.
Severity
The inherent severity of the category, never discounted by how sure we are. A suspected critical is still a critical that we are unsure about; flattening the two would let a hypothesis disappear below a CI threshold.
Inconclusive
The attempt ran but the oracle could not decide — a truncated body, a redirect. Deliberately not counted as enforcement.