Authentication: logins, roles and permissions done properly
Who a user is, what they may do, and how that is enforced on every request. The pieces of a proper login system and why we never build our own.
The short answer
Every application with a login answers two questions on every request: who is this, and what may they do? The first is authentication; the second is authorisation. Both must be enforced on the server every time, never only by hiding a button in the interface. The pieces are well understood: an identity provider or established library for logins, sessions and resets; roles and permissions designed with the business and checked in code by permission, not by role name; two-factor for staff and administrators; secure session cookies; rate-limited logins; audit logs of sensitive actions; and an account recovery flow that has actually been tested. We never build our own password storage or session handling, and neither should anyone else.
The pieces
| Piece | What it does | Baseline |
|---|---|---|
| Identity provider or library | Handles passwords, sessions, resets, two-factor, social and passwordless login | An established, maintained service or library; never home-made |
| Password handling | Storage, strength rules, breach checks | Delegated to the provider; long passphrases; no arbitrary composition rules |
| Two-factor | A second proof: authenticator app, passkey, hardware key | Required for staff and admins; offered to customers; required where money or personal data is at stake |
| Sessions | Proving the user across requests | Secure, HttpOnly, SameSite cookies; sensible expiry; invalidated on logout and password change |
| Roles and permissions | What each user may see and do | Designed with the business; enforced by permission on the server for every request |
| Rate limiting | Slowing brute force and credential stuffing | On login, reset and two-factor endpoints |
| Audit log | Who did what to sensitive data and when | Logins, permission changes, exports, deletions |
| Recovery | Getting back in when a factor is lost | A tested flow that does not become the weakest link |
Designing roles with the business
- List the actions in the system: view, create, change, delete, export, approve, for each kind of data.
- List the people: the actual roles in the business, including the awkward ones: the part-time bookkeeper, the external accountant, the locum.
- Fill the grid: which role may do which action, decided by the people who run the business.
- Find the exceptions: the manager who is also a practitioner; the owner who should see everything but not accidentally delete it.
- Encode permissions, group them into roles, and check permissions in code.
- Review quarterly: who has which role, and remove the departed.
Why we use providers
Identity is a specialism under constant attack. Providers and established libraries have been hardened by years of it and are updated when new attacks appear. Using them means passwordless options, two-factor, breach detection and secure defaults arrive built in, and the application’s own code is reduced to deciding permissions, which is the part that is genuinely specific to the business. Building the rest is not craftsmanship; it is unnecessary risk.
What this means for you
Insist that your software delegates logins to an established identity provider or library, enforces permissions on the server for every request, designs roles with the people who run the business, requires two-factor for staff and administrators, secures sessions, rate-limits logins, logs sensitive actions and tests recovery. Those are the baseline, not the premium tier, and they are where the difference between a contained incident and a breach is decided.
Frequently asked questions
Why not just build a simple login ourselves?
Because simple logins are where application breaches originate: passwords stored badly, sessions that never expire, reset links that can be guessed, no protection against brute force. Established identity services and libraries have solved these problems under attack for years. Building your own is choosing to repeat their early mistakes with your customers' accounts.
What is the difference between a role and a permission?
A permission is one specific right: view invoices, edit customers, delete a booking. A role is a named bundle of permissions assigned to people: receptionist, practitioner, manager. Roles make administration manageable; permissions make enforcement precise. The mistake is checking the role name in code instead of the permission, which breaks the moment roles change.
Do we need two-factor for customers too?
Offer it, and require it where the account controls money, personal data or anything a takeover would damage. For staff and administrators it is not optional. Passwordless options such as passkeys and magic links are increasingly the better default for customers, because they remove the password that is reused and phished.
Sources
- OWASP Cheat Sheet Series: Authentication Cheat Sheet (accessed 2026-09-12)
- OWASP Cheat Sheet Series: Authorization Cheat Sheet (accessed 2026-09-12)