A logged-in user has established an identity. An export or download also needs an access decision: may this person perform this action on these records, with these fields, within this account? A handler that checks only for a session leaves those questions unanswered.
Review the complete route from the incoming request to the returned file. A hidden button, a filtered list, or a successful login can coexist with a direct endpoint that returns another customer's data. The server must enforce the relevant permissions at the point where it selects and releases the records.
Define the permitted action and resource
Consider two illustrative features: exporting active customer rows and downloading an invoice. Start by writing their access rules in ordinary language.
For the export, identify who may export, which tenant's customers are eligible, and which fields may leave the system. Viewing individual records does not automatically imply permission to export them in bulk. Confirm whether the application defines separate permissions and how they apply to the caller.
For the invoice, distinguish customer ownership from administrative permission. A customer may be allowed to download an invoice belonging to their account. An administrator needs the appropriate permission and scope. A support role's access requires an explicit policy decision; its name alone does not establish authority.
Trace scope into the data selection
Follow the authenticated identity to the trusted account or tenant context. Then inspect how that context constrains the query and any later object lookup. A customer identifier supplied in a request is input to validate, not proof that the caller owns that customer.
For an export, a status filter such as “active” describes which rows match the requested report. It says nothing about who may receive them. The authorized scope and requested filters must both constrain the selection.
For a download, look for a resource lookup constrained by the permitted account or tenant and the requested invoice identifier. Retrieving an unrestricted invoice first and applying an ownership check afterward creates a broader intermediate exposure and more opportunities for an unsafe return path.
Inspect alternate paths too. A scoped list query does not protect a separate download handler that looks up the same object globally.
Check the actual release path
Trace every return, redirect, and error branch between selection and delivery. Identify where permission denial stops processing and whether file generation or delivery can happen before that decision.
If the feature uses background exports, review both job creation and retrieval of the finished artifact. Permission to request a report does not establish that every signed-in user may fetch its result. Define how the job and file remain associated with the authorized scope.
Likewise, inspect any alternate file URL the endpoint returns. Establish what grants access to that URL and how long the grant lasts. A download route can enforce ownership correctly while its storage path exposes the same document through another route.
These are review questions to adapt to the actual architecture. They do not imply every export needs a queue or a separate file service.
Build negative cases with distinguishable records
Use safe fixtures representing two accounts, different tenants where applicable, and callers with different permissions. Give their records distinct contents so an assertion can detect which data escaped.
Define proposed cases before running them:
| Request | Expected boundary |
|---|---|
| Authorized customer requests their own invoice | Returns the permitted document. |
| Same customer directly requests another account's invoice identifier | Denies access without returning that document. |
| Caller can view customers but lacks export permission | Denies the export under the agreed permission policy. |
| Caller changes a tenant or account request parameter | Cannot expand access beyond their authorized scope. |
| Authorized exporter requests active customers | Returns only eligible rows and fields within the permitted scope. |
Confirm the application's error contract instead of choosing a new response code during the review. Inspect the body as well as the status: an error response containing invoice data still violates the boundary.
Prove the negative test reaches the boundary
A denial test can pass for an unrelated reason. A nonexistent invoice, malformed request, or invalid session may fail before the ownership rule runs.
Use an existing foreign invoice and a valid caller session for the cross-account case. Establish that the fixture belongs to the other account. Then check the denied response and any relevant side effects, such as file delivery or an export job being created.
Pair denial checks with an authorized success case. Rejecting every request prevents leakage but also breaks the feature. For the export, inspect the actual returned rows and permitted fields rather than checking only that a file exists.
When the suspected defect is an unrestricted identifier lookup, the regression check should distinguish that implementation from a scoped lookup.
Review logs, filenames, and audit records separately
Authorization and incidental disclosure deserve separate findings. Inspect generated filenames, application logs, error reports, and export metadata for customer details or document contents that do not belong there.
Define a safe audit record for exports and downloads. It should identify the actor, action, relevant scope or resource reference, time, and outcome as required by the system's audit policy. Restrict access to the audit record itself and avoid copying invoice contents or exported rows into it.
An export audit trail should let an authorized reviewer determine who exported which authorized selection. Record an appropriate selection reference or bounded description rather than putting the dataset into general-purpose logs. Define failed-attempt logging separately so denial remains observable without exposing protected content.
Leave an actionable review decision
Write the finding against the exact query, lookup, or release branch. State the unauthorized action it permits, the required scope or permission check, and the discriminating test. Keep formatting feedback separate so it cannot obscure the access defect.
Before approval, request observed results for the agreed negative and authorized cases. Record which route and revision were checked, what remains unverified, and who owns any outstanding storage, audit, or background-job check. A passing browser flow supports only that flow; direct endpoint access needs its own evidence.
The Agentic Developer Interview includes Security Boundary Review and Authorization Boundary cards covering export permissions, tenant and ownership checks, negative access tests, and safe audit metadata.