Access Control
Authentication answers "Who are you?". Access control answers the follow-up question: "Now that we know who you are — what are you allowed to do?" Getting this second layer wrong is how breaches happen even when passwords are unbroken: a legitimate user reaches data or capabilities they were never supposed to touch.
Subjects, Objects, and Permissions
Every access control model works with three elements:
| Term | Meaning | Examples |
|---|---|---|
| Subject | The active entity requesting access | user, process, service account |
| Object | The passive resource being protected | file, database row, network port, device |
| Permission | The type of operation allowed | read, write, execute, call, transfer |
A reference monitor sits between every subject request and its target object, consulting a policy to decide allow or deny.
The principle of least privilege is the governing philosophy: grant each subject only the minimum permissions it needs to complete its task, and nothing more. This limits the blast radius of any compromise.
The Access Control Matrix
The complete set of permissions can be written as a matrix with subjects as rows and objects as columns. Each cell lists the permissions that row's subject holds over that column's object.
Example — university phone system:
| Internal | Local | Long Distance | International | |
|---|---|---|---|---|
| Public | CRT | |||
| Students | CRT | CRT | R | R |
| Staff | CRT | CRT | CRT | R |
| Admin | CRT | CRT | CRT | CRT |
(C = call, R = receive, T = transfer)
Real systems have millions of subjects and objects, so storing the full matrix is impractical — most cells are empty. Two sparse representations are used in practice:
Access Control Lists (ACLs)
An ACL is stored with each object: it lists every subject that holds some permission on that object, along with what those permissions are. The Linux getfacl command shows an ACL attached to a file:
# file: example
# owner: seed
# group: seed
user::rw-
group::rw-
other::r--
ACLs make it easy to answer "who can touch this object?" but expensive to answer "what can this subject touch?"
Capabilities
A capability is the dual: it is stored with the subject and lists everything that subject is permitted to access. Capabilities make it easy to audit what a subject can do, but revoking access to a single object from all subjects requires touching every subject's capability list.
Discretionary Access Control (DAC)
In DAC, the owner of an object decides who else may access it and with what permissions. Linux file permissions are the canonical example: chmod 644 file.txt is an owner making a discretionary choice.
- Most common design in commercial operating systems
- Flexible and easy to use
- Generally less secure than MAC — a compromised or malicious owner can hand off permissions
Mandatory Access Control (MAC)
In MAC, a central policy administrator sets access rules based on security labels. Individual users cannot change permissions on objects they own — the policy is mandatory and system-wide.
A common MAC implementation uses security clearances and need-to-know: a subject must hold the right clearance level and demonstrate an operational need before access is granted.
SELinux (Security-Enhanced Linux) and AppArmor both implement MAC on Linux, attaching security labels to processes and files and enforcing policies that constrain even root-level processes.
Bell-LaPadula Model (Confidentiality)
Bell-LaPadula assigns every subject and object a security level (e.g., Unclassified < Confidential < Secret < Top Secret). Its two core rules preserve confidentiality:
| Rule | Direction | Mnemonic |
|---|---|---|
| Simple security ("no read up") | A subject may NOT read an object at a higher level | You can't read what you're not cleared for |
| Star property ("no write down") | A subject may NOT write to an object at a lower level | You can't leak secrets downward |
Biba Model (Integrity)
Biba is the integrity counterpart to Bell-LaPadula — it prevents low-integrity data from contaminating high-integrity objects. Its rules are the mirror image:
| Rule | Direction | Mnemonic |
|---|---|---|
| Simple integrity ("no read down") | A subject may NOT read an object at a lower integrity level | Don't let bad data in |
| Star property ("no write up") | A subject may NOT write to an object at a higher integrity level | Don't corrupt trusted data |
Side-by-side comparison
| Model | Goal | Read restriction | Write restriction |
|---|---|---|---|
| Bell-LaPadula | Confidentiality | No read up | No write down |
| Biba | Integrity | No read down | No write up |
Role-Based Access Control (RBAC)
RBAC is an evolution of group-based permissions. Instead of assigning permissions directly to individual users, an administrator defines roles (e.g., Nurse, Physician, Administrator), assigns permissions to roles, and then assigns users to roles.
Benefits:
- Permissions follow job functions, not individual identity
- When a user changes jobs, reassigning their role is sufficient
- Supports role hierarchy — a senior role inherits the permissions of subordinate roles
Example — hospital RBAC hierarchy: CEO inherits from CTO, COO, and CMO; Physician inherits from Clinical Staff; and so on down the tree. A user assigned the Physician role automatically gets all Clinical Staff permissions.
Attribute-Based Access Control (ABAC)
ABAC generalises RBAC by making access decisions on the basis of arbitrary attributes attached to subjects, objects, or the environment. Authorizations are expressed as predicates over those attributes.
Example 1 — movie streaming:
- Users with
age >= 13may access PG-13 content - Users with
age >= 17may access R-rated content
Example 2 — Electronic Health Record system: A doctor may access a patient's full record only if:
subject.location == "hospital"subject.assigned_to == patientcurrent_timeis between 08:00 and 20:00
ABAC is well-suited to dynamic, context-sensitive environments where static role assignments are too coarse-grained.
The Confused Deputy Problem
The confused deputy is a classic access control vulnerability. A deputy is a program that runs with elevated privileges on behalf of users (like a Set-UID binary or a server). When the deputy does not validate whether the requesting user is actually authorized for the operation it is about to perform on their behalf, an attacker can trick the deputy into exercising its elevated privileges in unintended ways.
Classic example: A compiler running as Set-UID root accepts a user-specified output path for billing records. The user supplies /etc/passwd as the output path. The compiler, using its elevated privileges, overwrites the file — not because the user was authorized to write to /etc/passwd, but because the compiler was. The compiler was the confused deputy.
Defense: the deputy must check the requesting user's authority (not just its own) before performing privileged operations.
Linux Capabilities
Traditional Unix uses an all-or-nothing root model: a process either has full root power or it doesn't. Linux capabilities split the monolithic root privilege into about 40 discrete units (e.g., CAP_NET_BIND_SERVICE to bind to ports below 1024, CAP_SYS_PTRACE to use ptrace). Programs can be granted only the specific capabilities they need — a practical application of least privilege that reduces the damage a compromised service can cause.
Key Takeaways
- Access control (authorization) is separate from authentication: authentication establishes identity; access control decides what that identity may do.
- The access control matrix is the complete formal model; in practice it is stored as ACLs (per object) or capabilities (per subject).
- DAC lets owners control their own objects (flexible, less secure); MAC enforces a central policy regardless of ownership (restrictive, higher assurance).
- Bell-LaPadula enforces confidentiality with no read up / no write down; Biba enforces integrity with no read down / no write up.
- RBAC ties permissions to organizational roles; ABAC generalizes further by evaluating arbitrary attribute predicates.
- The confused deputy problem shows that privilege is not the same as authorization — a powerful program must check whether its caller is allowed, not just whether it itself is allowed.
- The principle of least privilege underpins all good access control design: give every subject only what it strictly needs.