Two questions, and be honest. Can your newest starter see every customer's payment details? And could the person who left last month still log in tonight?
If either answer is "probably" or "I'd have to check", you're in good company, and in quiet danger. Permissions are the dullest subject in business software right up until the day they're the only subject. Getting them right isn't a technical chore. It's business design, and here's the shape of it.
Job titles lie, especially in small firms where one person covers three of them. Build roles around responsibilities: who handles enquiries, who approves refunds, who manages pricing. Then give each role what those responsibilities need and nothing extra. That's least privilege, and done well it's invisible: people simply have what their work requires, and the sensitive stuff isn't lying around for browsing.
Plenty of people need to see a booking. Fewer should change it. Fewer still should approve the refund on it. Separating those three keeps work flowing while protecting the actions that cost money, and it's often worth going finer: this role sees the customer record but not the card details, that role sees their own team's jobs but not the whole book. Record-level and field-level access sounds fussy until the first time it saves you.
The moment clients log in, through a portal like the one we built for Darkin Architects, permissions become customer-facing. Which of their colleagues can see which project, what happens when their staff change, who approves on their side: design it with the same care as your internal roles, because a permissions mistake in a portal is a confidentiality incident with a customer attached.
Exporting the customer base. Changing prices in bulk. Granting admin rights. High-impact actions deserve extra friction: restricted to named people, confirmed deliberately, and always recorded. Which brings us to the audit trail: who did what, when, from where. It's not surveillance, it's the ability to answer questions calmly instead of forensically.
Most permission problems aren't hacks; they're drift. The starter cloned from whoever left last. The mover who kept every old access plus the new. The leaver nobody deactivated. A simple routine (grant by role on day one, review on change, revoke on departure, sanity-check twice a year) closes the gap, and it works across your connected systems too, where one login often unlocks several doors.
Two finishing touches make the whole model liveable. Permission failures should be polite and clear ("you need approval rights for refunds; ask Sian") rather than mysterious. And before launch, test the system as each role, not just as the developer's all-powerful account. When we build operational systems, the permission model is part of the product, because who can see what is a business decision wearing technical clothes. Make it deliberately, and the day it matters, you'll be very glad you did.