pk.org: Computer Security/Lecture Notes

Part 3 - Mandatory Access Control

Bell-LaPadula, compartments, Biba, Chinese Wall, type enforcement, and role-based access control

Paul Krzyzanowski – 2026-10-08

Discretionary access control leaves every decision to the owner of a file, and an organization has no way to define a rule its members cannot override. The U.S. Department of Defense faced this problem in the early 1970s. It wanted a computer to hold documents at several classification levels and to serve users with different clearances, and it could not accept a system in which any user who could read a Top Secret file could also make it readable by everyone. The 1972 Anderson report that introduced the reference monitor (see Part 1) was written for that problem, and mandatory access control models are its descendants.

In mandatory access control, or MAC, the access rules come from the organization rather than from the owner of each object, and the system enforces them against everyone, owners included.

Every subject and every object has a label that an administrator or a policy assigns. The rules that compare labels are fixed: the kernel applies them on every access, and the owner of an object cannot change the outcome. The models differ in what a label contains and what the comparison is. They are introduced here in an order where each one changes one thing from the one before: Bell-LaPadula sets up labels and two rules, first with levels alone and then with compartments added to the label; Biba reverses the direction; the Chinese Wall model makes the decision depend on access history; type enforcement replaces the hierarchy with named domains and types; and role-based access control replaces the subject with a business role.

Multilevel Security and Bell-LaPadula

The first formal model, one whose rules were stated mathematically and proved to keep a system in a secure state, was published by David Bell and Leonard LaPadula of MITRE, a nonprofit that runs federally funded research centers, in 1973. The work was sponsored by the U.S. Air Force, and its purpose was to state the government’s rules for classified information precisely enough that a computer could enforce them. The Bell-LaPadula model describes multilevel security: a system that holds information at several levels of sensitivity and prevents it from flowing downward.

Objects are given a classification from an ordered set of levels. The military levels are Unclassified, Confidential, Secret, and Top Secret. Subjects are given a clearance from the same set. The model’s purpose is confidentiality, and it enforces it with two rules:

  1. The simple security property, or no read up. A subject may read an object only if the subject’s clearance is at least as high as the object’s classification. A user cleared for Secret may read Secret and Confidential files and may not read Top Secret ones.

  2. The star property (written \(*\)-property, after the placeholder its authors used before they named it), or no write down. A subject may write an object only if the object’s classification is at least as high as the subject’s clearance. A user cleared for Secret may write Secret and Top Secret files and may not write Confidential ones.

A third rule, the discretionary security property, says that ordinary permissions still apply within the limits set by the first two. A file’s owner can restrict access further but the owner cannot extend it past what the labels allow.

The second rule exists because of the Trojan horse problem: a program that attempts to perform a malicious function the user is not aware of. Suppose a user cleared for Secret runs a program. The program is a Trojan horse, or the user’s account has been taken over. The program reads a Secret file, which the first rule allows, and writes its contents to an Unclassified file, where anyone can read it. Discretionary control cannot stop this, because the program runs with the user’s rights and the user may read the file. The star property stops it: a process at the Secret level may not write anything below Secret, whatever its intentions. Information can move up the hierarchy and never down.

Read literally, the rule would stop a Top Secret user from ever writing an unclassified memo. The model handles this by letting a user run a process at a level below their clearance: the process is then held to that lower level, and it cannot read anything above it. The examples here assume each process runs at its user’s full clearance.

In these rules, “write” means adding to an object without reading it. An operation that both reads and writes a file must satisfy both rules, which here means the file is at the analyst’s own level. A Secret-cleared analyst with three files shows both rules at once:

File Classification Read Write only
A Confidential allowed denied (write down)
B Secret allowed allowed
C Top Secret denied (read up) allowed

The analyst may append to a Top Secret file they cannot read, which is allowed by the model and, in a real system, usually prevented by the discretionary property. Every “allowed” in the table still needs the ordinary permissions to agree.

Limits of the Model

Bell-LaPadula was implemented in a series of operating systems built for the government, including versions of Multics and Honeywell’s SCOMP, and it is the model behind the U.S. Department of Defense’s Trusted Computer System Evaluation Criteria of 1983, known from its cover as the Orange Book. It also has limits that every later model responds to:

Compartments and Need to Know

Bell-LaPadula separates information vertically, by level. Organizations also separate it horizontally, by project. Intelligence agencies hold signals intelligence and human intelligence at the same classification level and do not want every analyst cleared for one to see the other. The principle is need to know: a clearance establishes that a person may be trusted with information at a level, and a separate decision establishes which information at that level the person needs.

The Bell-LaPadula label has a second part that the examples so far left out. The full label is a level and a set of compartments, which the 1973 reports call categories; the level-only form came first here because the rules are easier to see with it. A label is written as a level and a set, such as {Top Secret, {Nuclear}} or {Top Secret, {Nuclear, Signals}}, and a subject holds a compartment only if someone decided that it needs that project’s information.

Separating information sideways in this way, as well as up and down, is called multilateral security. The rules now have two parts, and a subject may read an object only if both hold:

  1. The level test, which is the Bell-LaPadula rule from before: the subject’s level is at least as high as the object’s.

  2. The compartment test: the subject’s compartment set includes every compartment in the object’s.

Failing either test denies the access. When both tests pass, the subject’s label is said to dominate the object’s. Dominance replaces the level comparison in both Bell-LaPadula rules: a subject may read an object only if the subject’s label dominates the object’s, and may write an object only if the object’s label dominates the subject’s.

Because both tests have to pass, a higher level is not enough on its own, and some pairs of labels cannot be compared at all:

The set of all labels, ordered by dominance, forms a lattice: any two labels have a least label that dominates both and a greatest label that both dominate. For {Secret, {A}} and {Secret, {B}}, the least label that dominates both is {Secret, {A, B}}, which is where a report drawing on both would have to live, and the greatest label that both dominate is {Secret, {}}, the most that could be shared with both without a compartment. Dorothy Denning published the lattice formulation in 1976, and it gives the rules a single statement: information may flow from a label to any label that dominates it, and nowhere else. A diagram of the lattice shows every allowed flow as an upward edge.

The U.S. intelligence community runs its most sensitive material this way, as Sensitive Compartmented Information (SCI). SCI is not a classification level above Top Secret; it is a set of compartments, and a person needs both the Top Secret clearance and the specific compartment authorizations.

The cost is in additional administration. When an analyst who holds compartments A and B writes a report that combines information from both, the write rule allows the report to exist only under a label that dominates the analyst’s, so the system labels it with both compartments, and only subjects cleared for both may read it.

Each distinct set of compartments is in effect a new label, with its own set of subjects who dominate it, so a report that combines A and B creates a label that neither the A analysts nor the B analysts can read. The number of distinct labels grows with every combination that someone creates, and collaboration across compartments requires either an administrator to grant a new compartment or a trusted subject, one that is exempt from the write rule, to produce a sanitized copy: a version with the B material removed, which the trusted subject then labels with only compartment A so that the A analysts can read it.

Outside government, Bell-LaPadula has seen little use. Its hierarchy of levels formalizes the government’s classification rules, but companies have found that their own access policies rarely reduce to an ordering of levels. A bank cares more about who may change an account balance than about who may read it, a consultancy’s problem is conflicts between clients rather than clearances, and a server’s is confining the programs it runs. The models that follow each take up one of those needs.

The Biba Integrity Model

Bell-LaPadula protects secrets from flowing to people who should not read them. It does nothing to protect trustworthy data from being corrupted by sources that should not write it. The Bell-LaPadula rules do not prevent a subject at a lower level from writing to an object at a higher level, so a low-clearance process can corrupt a Top Secret file that it cannot read.

Kenneth Biba, also at MITRE, described a model with the same structure and the opposite goal in a 1975 report, published in 1977. The report describes several integrity policies; the one we cover here, and the one people mean by the Biba model, is the strict policy.

The Biba model assigns integrity levels rather than classifications. A high level means the data is trusted and the subject is trusted to produce it. The two rules are Bell-LaPadula’s, reversed:

  1. No read down. A subject may read an object only if the object’s integrity level is at least as high as the subject’s. A trusted process may not take input from an untrusted source.

  2. No write up. A subject may write an object only if the subject’s integrity level is at least as high as the object’s. An untrusted process may not modify trusted data.

The threat is contamination. An installer that runs with high integrity must not read configuration data from a file that a downloaded program could have written, because whatever it reads may affect what it does at its higher privilege. A browser that reads pages from arbitrary servers runs at low integrity and must not be able to write the system’s files. Where Bell-LaPadula keeps information from flowing down, Biba keeps it from flowing up.

Side by side, the two models differ only in direction:

A system can run both, with a confidentiality label along with an integrity label on every object, but few do. The strict Biba rules fit real systems even worse than Bell-LaPadula’s, because programs that process untrusted input are the normal case, not the exception. A low-integrity browser may read a low-integrity download, but nothing at a higher level may then use what the browser produced, and a system where a download can never be promoted to trusted data needs a trusted procedure outside the rules to do the promoting.

Windows Integrity Levels

Microsoft shipped a restricted form of Biba in Windows Vista in 2007 as Mandatory Integrity Control. Every process and object has an integrity level: Low, Medium, High, or System. Ordinary user processes run at Medium, processes elevated through the administrator prompt run at High, and system services run at System. The rule enforced by default is no write up: a process may not modify an object whose level is higher than its own, whatever the object’s discretionary permissions say. The label is stored in the object’s SACL (System Access Control List), and an unlabeled object is treated as Medium. Windows can also enforce no read up and no execute up on an object whose label requests them, but it does not implement Biba’s no read down.

The first main use of Mandatory Integrity Control was Internet Explorer 7’s Protected Mode. The goal was to ensure that a browser taken over by a malicious page could not modify the user’s files or the system’s. The browser ran at Low integrity, so a page that exploited it was running in a process that could not write to the user’s documents, registry, or to system directories. It could still read the user’s files, so the integrity level confined what an exploit could change, not what it could see.

Later Windows versions built the AppContainer sandbox on top of integrity levels, and the Edge browser’s renderer processes and Universal Windows Platform applications run inside it. The integrity levels are still there, visible with the icacls command, as one layer of a larger mechanism.

The Chinese Wall Model

Every model so far decides access from labels that were assigned in advance. In 1989, David Brewer and Michael Nash published a model where the decision depends on what a user has already done. A consulting, advertising, or accounting firm serves clients that may compete with each other. An employee who has seen one airline’s confidential plans must not then see another airline’s, since the employee could carry what they learned from one competitor to the other. However, the same employee may still have a beverage company as a client, because a beverage company does not compete with an airline and nothing the employee learned about the airline can harm it. The access policy depends on history: what the employee may see next is determined by what the employee has already seen.

The Chinese Wall model organizes objects in a two-level hierarchy. Each object, a document or a record, belongs to one company dataset, which is the collection of all the data the firm holds about one client. Each company dataset belongs to one conflict of interest class, which groups the datasets of companies that compete with each other. In an implementation, every object contains the names of its dataset and its class as a label, which is what the system checks for access decisions. For example, a firm’s conflict of interest classes might be:

The first rule governs reading: a subject may read an object in a company dataset only if every object the subject has previously read is either in the same company dataset or in a different conflict of interest class.

Before the employee has touched anything, access to every dataset is available. After the employee reads a Delta document, access to the other three airlines’ datasets is denied, and the beverage companies’ datasets are still available. Once the employee reads a PepsiCo document, Coca-Cola’s and Keurig Dr Pepper’s datasets are denied as well. The wall is built by the subject’s own actions, and the system records every access in order to enforce it. The record has to outlast a login session, since the conflict does not end when the employee logs out.

A second rule governs writing to stop information from crossing the wall through a third party. A subject may write to a company dataset only if the first rule permits it to read that dataset and it is not permitted to read any other company dataset, except for sanitized information. The rule confines writing to employees whose unsanitized read access is a single dataset.

An employee who is permitted to read unsanitized data from two datasets, whether in the same class or in different ones, may not write into either. Reading across classes is still allowed, since that is what the first rule permits. What the second rule removes is the combination of reading widely and writing, because an employee who does both is the third party through whom one client’s information could reach another’s dataset. Without the rule, an employee with access to Delta and PepsiCo could copy Delta’s information into PepsiCo’s dataset, and a colleague permitted to read PepsiCo and United could then obtain Delta’s information. The restriction is severe, and firms live with it by separating the people who enter data into a client’s dataset from the people who analyze data across clients, and by letting those analysts produce only sanitized output.

The model is a dynamic form of separation of duties. A static separation would forbid an employee from ever working for two competing clients. The Chinese Wall instead lets the employee read either client’s data until the first read happens, and from then on forbids reading the competitor’s. Operating system kernels do not implement this because they do not know what a client is. The model lives in the applications of banks, law firms, and consultancies, where regulators expect information barriers of this kind between advisory and trading work.

Type Enforcement

Bell-LaPadula and Biba determine access by comparing ordered labels, with different rules for reading and writing. They suit organizations that think in terms of clearances, and they are not suited for most servers. The threat on a server is a compromised program, not a disloyal employee, and the policy a server needs is “this web server is only allowed to access these specific files,” stated separately for each program, file, and operation.

Compartments can express part of that, since the web server and its content can share a label. The trouble is that every access in a lattice follows from comparing labels, and the comparisons chain. If the web server also appends to a log, and a log analyzer reads that log and writes reports, the labels have to line up so that each of those accesses is allowed, and the same lineup then allows the analyzer to read the web content and the server to write the reports. The policy never asked for either.

A server needs a list of permitted combinations of program, operation, and file, with nothing else implied beyond the list. In 1985, Earl Boebert and Richard Kain of Honeywell proposed type enforcement as a mandatory model based on such a list rather than on classification levels.

Type enforcement is an implementation of the access matrix in which the rows and columns are classes rather than individuals. Every subject is assigned a domain, a class of subjects, and every object a type, a class of objects. The matrix has a row per domain and a column per type, and a cell holds the operations that the domain may perform on the type. A policy is a list of rules that fill in the cells, and anything the policy does not allow is denied. There is neither a hierarchy nor a notion of up or down. The grouping is what makes the matrix practical to implement: thousands of processes and millions of files on a server map onto a few hundred domains and a few thousand types, so the matrix is small compared with what it governs, and the policy applies to every process in a domain without anyone listing the processes.

The model reached general use through SELinux, Security-Enhanced Linux, which the U.S. National Security Agency released as a set of kernel patches in December 2000 and which became part of the standard Linux kernel in 2003. Every process in an SELinux system runs in a domain, every file has a type stored as an extended attribute, and the policy is a list of rules of this form:

allow httpd_t httpd_sys_content_t:file { read getattr open };

The rule says that processes in the httpd_t domain (the web server) may read, examine, and open files of type httpd_sys_content_t (the web content). Every other file on the system has some other type, and unless another rule grants httpd_t access to that type, the web server may not touch those files. One rule shows what is allowed; only the absence of a rule anywhere in the policy makes an access denied. The check is made by a reference monitor in the kernel after the ordinary permission bits have been checked, and either check can deny.

The difference appears when the web server is compromised. A traditional server that has been taken over does whatever its user ID permits, and if it runs as root that is everything. Under SELinux, the compromised process is still in httpd_t, because the domain is a property of the process and not of the attacker’s intentions. It can read web content, write its log, and accept connections, but it cannot read the password file or anyone’s home directory, even as root, because nothing in the policy allows httpd_t to touch files of those types. The policy confines the program to what it was meant to do, and a flaw in the program does not enable more access.

SELinux is the default on Red Hat Enterprise Linux and Fedora, and Android has shipped a type enforcement policy since version 4.3 in 2013, enforced for every process since version 5.0 in 2014. Every app on an Android phone runs in a domain that restricts it to its own files and to the system services the policy allows apps to reach; the permissions an app declares are checked separately, by the framework, above SELinux. Ubuntu and Debian ship a different mandatory access control system, AppArmor, which confines a program by the paths it may access rather than by types. We will cover AppArmor in detail later, with the other mechanisms for confining code that is already running.

The cost of type enforcement is the size of the policy. Small compared with the system is still not small. A rule is written for a domain, type, and class of object, such as a file, a directory, or a socket, and a typical service touches dozens of types through several object classes each: its configuration, logs, data, temporary files, and the sockets it listens on. A software distribution’s policy covers every service it ships, whether or not the service is installed, so the standard SELinux policy contains tens of thousands of rules.

A missing rule can cause a program to fail in unexpected ways, usually with an ordinary permission-denied error that gives no hint that SELinux was involved.

An administrator who cannot find the cause of such a failure has a quick fix available: disable SELinux, after which the program works and the machine runs with only discretionary permissions applied. Enough administrators take that route that SELinux ships with tools for finding the cause: the kernel records every access denial in an audit log, and a tool reads the log, explains which rule was missing, and generates the appropriate rule. Those tools do as much for the system’s security as the kernel code, because an enforcement mechanism that administrators disable offers no protection.

Role-Based Access Control

The models above assign rights to subjects, directly or through labels. In an organization, rights are associated with jobs.

A hospital does not state that a particular person may read patient charts; it authorizes nurses to do that. A person who is a nurse gets access, and the access is taken away when that person no longer serves as a nurse.

Role-based access control, or RBAC, puts that structure into the access control system. It was defined in 1992 by researchers at NIST, the U.S. National Institute of Standards and Technology, and became a U.S. standard in 2004.

An RBAC system has four kinds of entities:

Permissions are assigned to roles and users are assigned to roles. A user never holds a permission directly. When a user starts a session, the system activates some of the user’s roles, and the permissions of the active roles define what the user can access. A hospital’s version might give the Doctor role the right to read and update charts and write prescriptions, the Nurse role the right to read charts and record vital signs, and the Billing role the right to read charges and submit claims. A person who holds both the Nurse role and the Billing role can activate either one, or both.

The session is what ties access to the job rather than to the person. A nurse activates the Nurse role when coming on duty and can read charts for the length of the shift. When the shift ends and the session closes, the person still holds the role but has none of its permissions: a role that is held but not active grants nothing. On its own, that does not keep an off-duty nurse from starting a new session and activating the role again. If the hospital adds the restriction that the Nurse role may be activated only during a scheduled shift, an off-duty nurse cannot read charts at all, and the hospital’s records show not only who read a chart but under which role.

The gain is administrative. A hospital with 5,000 employees and 500 permissions has 2.5 million possible user-permission pairs. With roles, the numbers shrink. If the hospital defines 50 roles with about 20 permissions each, and each employee holds two, an administrator maintains about 1,000 role-permission assignments that rarely change and 10,000 user-role assignments that change whenever someone is hired, promoted, or leaves. Removing a departing employee is one operation, and it removes every right at once.

Hierarchies and Constraints

Roles can be arranged so that one inherits another’s permissions. A role hierarchy lets Attending Physician include everything in Doctor, which includes everything in Clinical Staff, so that common permissions are defined once. The hierarchy is a hierarchy of permissions, and it often follows the organization chart, but it does not have to: a department head does not need every permission of every nurse in the department.

A constraint limits how roles may be combined. The important one is separation of duties, applied to roles: a single person may not hold the roles that together perform all steps of a sensitive transaction. The person who submits a purchase order may not approve it, and the person who writes code may not deploy it alone. A static constraint forbids assigning two such roles to the same user. A dynamic constraint allows the assignment and forbids activating both roles in one session. It resembles the Chinese Wall, but it is weaker: the wall remembers what a subject has done and persists across sessions, while the dynamic constraint forgets at logout, so a user who activates one role, logs out, and logs in with the other has satisfied it.

Roles Are Not Groups

Unix groups and Windows groups look like roles, and the difference is what each one names. A group is a set of users, and a file’s owner decides what the group may do with the file. A role is a set of permissions, and an administrator decides which users hold it. In an RBAC system, what a nurse can do is the list of permissions in the Nurse role, available in one lookup. In a group-based system it has to be assembled by searching every object for entries that mention the nurses group. Reviewing a person’s access means producing that list, and a group-based system cannot produce it directly.

Where RBAC Lives

A role is useful only when it names a business function. Being allowed to connect to the database is not a role. Being a payroll administrator is a role, and it contains the permission to change an employee’s salary. The operations that make up a business function, such as changing a salary or approving a claim, are operations of an application, not reads and writes of files, so an operating system cannot enforce most of them. RBAC therefore lives mainly inside applications and the services they are built on, which check the role before performing the operation.

RBAC is the model of most of the systems that organizations administer above the operating system. Database systems such as PostgreSQL and Oracle have roles as a first-class object, with grants to roles and roles granted to users. Windows domains assign permissions to Active Directory groups that are used as roles.

Cloud platforms use the word too. In Amazon Web Services, a role is an identity with attached permissions that a user or a running service assumes to obtain temporary credentials; it is a looser thing than the role of the formal model, and the permissions attached to it can be as broad as an administrator writes them. The credentials the Capital One attacker obtained were those of a role that the firewall assumed. Every permission she exercised had been granted to that role by an administrator.

RBAC fails when roles multiply. A large organization that creates a role for every combination of permissions anyone has ever needed may end up with thousands of roles, each held by a few people, and the structure that was supposed to be easier to audit than individual permissions is harder. The condition is called role explosion.

A role is a fixed set of permissions, and some decisions depend on the circumstances of the request: the time of day, the network the user is on, whether the device is managed, the department that owns the document. Attribute-based access control, or ABAC, generalizes roles to rules that test attributes of the subject, the object, and the environment. A rule such as “allow if the user’s department equals the document’s department and the request arrives from the corporate network” cannot be written as a role. Cloud policies include such conditions, and most large systems use roles for the baseline and attribute conditions for the exceptions.

Two Meanings of Mandatory

In the broad sense, any access control that users cannot override is mandatory. By that definition the Chinese Wall model is mandatory, since the wall is built by the system, and an RBAC deployment is mandatory when only an administrator assigns roles and permissions.

In the narrower sense used in the Orange Book and in the Common Criteria, the international standard for evaluating security products, mandatory access control means label-based control of information flow: Bell-LaPadula, Biba, and their relatives. Security engineers who say “MAC” without qualification usually mean the narrow sense, and SELinux is called a MAC system because its domains and types are labels that the kernel compares.

The Models Compared

Each model decides the same question, “may this subject perform this operation on this object,” but each one bases the decision on a different kind of label and applies a different rule to it:

Model What the label is The rule What it protects
Discretionary (Unix, Windows) Owner and permission entries The owner decides Whatever the owner chooses
Bell-LaPadula Classification and clearance No read up, no write down Confidentiality
Bell-LaPadula with compartments Level plus a set of compartments Read only what the label dominates Need to know
Biba Integrity level No read down, no write up Integrity
Chinese Wall Company dataset and conflict class One dataset per conflict class, fixed by the first access Conflict of interest
Type enforcement Domain and type Only what a rule allows Confinement of programs
Role-based Role Permissions follow the role Administrative scale

A real system runs more than one of these models, with one layered above another. Bell-LaPadula itself assumes a layer beneath it: its discretionary security property says that ordinary permissions still apply under the labels, so even the government systems that implemented it ran a discretionary model and a mandatory one together. A Linux server with SELinux runs the Unix permission bits with type enforcement above them. Windows runs discretionary ACLs with integrity levels above them.

An Android phone runs three layers, from the bottom up:

  1. Unix permissions. The phone runs a Linux kernel, and every app gets its own Unix user ID, so the discretionary permission bits keep apps out of each other’s files.

  2. Type enforcement. The kernel also runs SELinux, and its policy confines every app’s process to the files and system services the policy grants apps, whatever its user ID.

  3. Android permissions. Above both, the Android framework enforces a permission model of its own that decides whether a particular app may use the camera or read contacts, and prompts the user for permission.

Each layer catches what the one below it cannot express. We will cover the mechanisms that confine a program beyond the kernel’s permissions, and how an app’s permissions are enforced, in detail later.


Lecture 6: Part 1 | Part 2 | Part 3
Lecture 6 Study Guide | List of terms