Authentication answers who the user is.
Authorization answers what the user can do.
A secure system treats capabilities as boundaries
— not conveniences.
Every action, every resource, every piece of data has a lane,
and users must stay within it.
This page introduces the mental model for
designing authorization that is predictable, explicit, and difficult to misuse.
Roles are labels.
Capabilities are actions.
A secure system focuses on:
Roles are just a way
to group capabilities.
Capabilities are the real boundary.
Role‑based access control (RBAC) is simple,
but often too broad.
Capability‑based access control (CBAC) is:
Example:
Instead of:
"Admin can manage users"
Use:
"CanCreateUser" "CanEditUser" "CanDisableUser" "CanResetPassword"
Capabilities are small, clear, and testable.
Authorization belongs at the entry point of an action:
Do not:
Every action must enforce its own boundary.
Soft authorization is when the system:
…but does not enforce the rule on the backend.
That's not security.
That's convenience.
A secure system:
Avoid implicit rules like:
"Admins can do everything"
"If the user created it, they can edit it"
"If the ID matches, it’s allowed"
Implicit rules drift.
Explicit rules endure.
Prefer:
if (!$auth->can('edit_post', $post)) { throw new UnauthorizedException(); }
Explicit authorization is readable, testable, and predictable.
Policies encapsulate authorization logic.
Example:
class PostPolicy { public function edit(User $user, Post $post): bool { return $user->id === $post->author_id; } }
This keeps authorization:
Policies are the architectural home for capability rules.
Do not store:
…inside the session.
Why?
Always fetch authorization data fresh from a trusted source.
A secure system must be able to say:
"This user no longer has this capability." "This role has changed." "This permission is revoked."
Revocation must take effect immediately.
This is why authorization data must not be cached in:
Authorization is dynamic.
A secure system gives users:
Least privilege reduces risk by reducing surface area.
Common mistakes:
Authentication is identity.
Authorization is capability.
They must remain separate.
Authorization is the discipline of keeping capabilities in their lane.
A secure system:
Security is not about trusting the user —
it’s about trusting the boundaries.
This page describes secure defaults and common practices in modern PHP. It is not a complete security guide, and it does not replace formal audits or framework‑specific documentation. These principles are consistent enough to be useful, but security always requires context, judgment, and ongoing review.