Security / Field note
A customer login is not a fence around the data
Signing in proves an identity. Each record lookup still needs to establish which customer, role and operation that identity may access.
A customer signs in, opens an invoice and sees exactly the information expected. It is an ordinary success, which makes it an easy place to stop testing. The more useful next question concerns an invoice belonging to somebody else.
Authentication establishes who is asking. Authorization decides whether that identity may perform this operation on this record. Those decisions meet in a customer portal, but one cannot do the other's work. A valid account is not a general admission ticket to the database.
Every lookup carries a business boundary
Imagine a hypothetical distributor serving several customers through one application. Each customer has orders, invoices, documents and staff with different roles. A request for one invoice needs to carry enough trusted context to answer which customer owns the record and whether this user may read it.
A customer identifier submitted by the browser is useful request data. It is not proof of membership. The server needs to derive or validate that relationship using the authenticated identity and the application's own records. Otherwise the browser is being invited to mark its own homework.
Predictable identifiers are not the root problem
Long, random-looking identifiers can make accidental discovery less likely. They do not replace an access decision. Links travel through emails, bookmarks, support tickets and logs. A design should remain correct even when a valid identifier becomes known to somebody who cannot access its record.
OWASP's authorization guidance emphasizes denying access by default and checking permissions on every request. For a shared customer application, the engineering interpretation is to make ownership and permitted action part of each protected path, including the less visible routes used for exports, attachments and background work. [1]
The hidden paths deserve equal attention
An application might filter the invoice list correctly but overlook the PDF endpoint. It might protect downloads while allowing an administrative search to return names across customers. A cached response might also need to include the relevant tenant context in its cache key. Each path can undo an otherwise sensible boundary.
Scheduled jobs introduce another version of the question. A job acting on behalf of a customer needs trustworthy customer context and an appropriate service identity. Carrying that context through a queue, a worker and a storage lookup should be part of the design, rather than something the worker infers from whichever record it happens to receive.
Prove the boundary with synthetic neighbors
An isolated test can use two fictional customers, each with a user and a small set of records. The first user should reach the first customer's permitted record. The same user should receive the intended denial for the second customer's record. Repeat that comparison for the page, API, download and export routes selected for the review.
Include role differences within a customer as well. A sales viewer and a billing administrator may belong to the same organization while holding different permissions. Tenant isolation and role authorization are related boundaries, and a useful test avoids collapsing them into one customer-ID comparison.
Check what a denial reveals
Rejecting a request is only part of the response. The application should avoid leaking sensitive record details through an error message, a redirect or a diagnostic page. It should also retain a useful security event when appropriate, without placing confidential invoice contents or access tokens into the log.
The result of this exercise should name the tested route, requesting identity, record owner, required action and observed decision. After a correction, repeat the same cases and confirm legitimate access still works. That record is more useful than a broad claim that the portal is secure.
Customer boundaries become easier to maintain when they are explicit in both implementation and tests. New developers can see the policy; future changes can be checked against it. The application then has a much better answer to an uncomplicated customer expectation: my account should show my business, and your account should show yours.
Sources + further reading
Source dates describe the original material. Publication above is the date this Zyel article went live.
- Authorization guidanceOWASP · Checked Nov 4, 2026
Reader discussion
What would you ask next?
Questions, useful corrections and thoughtful disagreement are welcome. Comments are reviewed before they appear.
No reader comments yet.