A client portal has one failure that matters more than all the others combined: showing one customer another customer's data. It does not crash. It does not appear in an error log. It looks completely normal until somebody notices, and by then it has been happening for months.
This is worth being specific about before the build, not after.
The three ways it actually breaks
The guessable address. A document lives at a URL. The URL contains a number. Someone changes the number. If the check happens only in the interface — if the server hands over the file to anyone who asks for it — the portal has a door with a label instead of a lock.
The session that outlives the relationship. A person leaves the client company. Their login still works, because nothing connected "employee left" to "access ends". Six months later they are still receiving your customer's invoices.
The role that was added in a hurry. Someone needed to see one extra thing, so they were given a role that includes forty extra things. Nobody audits it, because there is nothing to audit against.
What to specify before anyone writes code
Write these down, in your own words, before the estimate:
- Who is a user? A person, or a company with several people? If several, who may add and remove them — you, or them?
- What is the unit of access? An order, an account, a branch, a region. Say it out loud; it is usually more complicated than the first answer.
- What happens when someone leaves? Both on your side and theirs.
- Who sees money? Almost every portal has one field that not everyone at the client should see.
- What is logged? Not for compliance theatre — so that when someone asks "who downloaded this", there is an answer.
How it gets tested
Access rules are the thing we test hardest, because they are the thing that fails quietly. In practice that means a suite where the interesting tests are the negative ones: a client requesting another client's order and getting a refusal, a document fetched by a guessed address and refused, a session that expired mid-form, an invitation used twice.
Those paths never appear in a demo. They are exactly what a portal is judged on the day something goes wrong. In the system we run, the browser side alone carries several hundred automated checks, and the ones worth their keep are almost all negative.
Two things worth paying for, one that is theatre
Worth it: checks enforced on the server for every request, not once at login. And an audit trail you can actually read.
Worth it: two-factor sign-in for anyone who can see money. It is cheap now, it is expected by business clients, and it removes an entire category of incident.
Theatre: a security page describing your commitment. Nobody has ever been protected by one, and clients who care will ask the two questions above instead.
The honest summary
Portal security is not a feature you add; it is a set of decisions you make before the first screen exists, and then keep testing. If a studio quotes you a portal without asking who may see what, they have not scoped the expensive part. Our portal scope and price name it explicitly, and the article on what a portal costs explains why it moves the number.