Mandatory Access Control (MAC): the system decides, not you
Mandatory access control explained: a system-wide policy based on security labels that no user, not even a resource owner, can override. Security clearances and classifications, the Bell-LaPadula model (no read up, no write down) that closes the trojan-horse gap DAC leaves open, the Biba integrity mirror, and how SELinux, AppArmor, and Windows Mandatory Integrity Control bring military-grade MAC to everyday operating systems.
The denial at 3 a.m.
David gets paged at 3 a.m. An attacker has exploited a vulnerable plugin on the company’s public web server and has a shell running as the web server’s account. In the logs, David can see what happened next. The attacker went looking around the filesystem and tried to read a directory of HR exports that, through an old mistake, was readable by the web server’s group. The Linux permissions would have allowed it. The read failed anyway, and next to it in the audit log sat a line beginning avc: denied. SELinux had never given the web server’s process any business with files of that type, and no file permission could change that.
That’s mandatory access control (MAC) at work. The previous article ended on DAC’s original sin: the owner decides, so information goes wherever an owner, or a program running with the owner’s rights, sends it. A trojan horse leaks a sensitive file and DAC sees nothing wrong, because the access was authorized. For most business data that’s an acceptable price for convenience. But some information must not flow, whoever wants to send it, and for that you need a model in which discretion itself is removed.
MAC flips DAC’s defining question. DAC asks what the owner wants; MAC asks what the classification allows, and the owner’s wishes simply aren’t part of the answer. A general who owns a Top Secret document can’t email it to an uncleared clerk, not because they lack permission to send email, but because the system forbids that flow of information and nobody short of the security officer can override the rule. Access is decided by a central, system-wide policy based on labels, and it’s mandatory because it’s imposed, not chosen. The model was born in defense and intelligence and formalized in the same 1985 Orange Book that named DAC, but as David’s night shows, it also runs on Linux servers, on your phone, and in your browser’s sandbox.
Labels: clearances and classifications
MAC’s machinery starts with labels. Every subject, a user or a process acting for one, carries a clearance. Every object, a file, a message, a record, carries a classification. The system compares the two on every access. In the classic government scheme a label has two parts. One is a hierarchical level, the familiar ladder of Unclassified, Confidential, Secret, and Top Secret, each strictly more sensitive than the last. The other is a set of non-hierarchical compartments, such as NUCLEAR, CRYPTO, HR, or FINANCE, which encode need to know. A label is the pair, for example (Secret, {CRYPTO, NUCLEAR}).
Access requires the subject’s label to dominate the object’s: the subject’s level must be at least as high, and the subject’s compartments must include all of the object’s. Someone cleared (Top Secret, {CRYPTO}) can’t read a (Secret, {NUCLEAR}) document. Their level is high enough, but they lack the NUCLEAR compartment. Labels form a lattice, a partial order in which some pairs simply can’t be compared, and that structure is what lets MAC enforce need to know on top of classification level. It’s far more precise than a single ladder.
One subtlety catches newcomers: a subject’s clearance, the most they’re trusted with, isn’t the same as the level they’re currently working at. A Top Secret analyst may log into a Secret session to work on Secret material, and while there the write-down rules treat them as a Secret subject. Systems that let a subject run at their maximum and quietly track the highest thing they’ve touched use a high-water mark, raising the effective level as they read upward, which is simple but tends to over-classify everything downstream.
A clearance also isn’t a role. It says how sensitive the information you’re trusted to handle is, independent of what your job needs, and compartments narrow it further. That separation between trust and job function is why MAC and RBAC end up layered together in real high-security systems: RBAC decides what your job lets you do, and MAC decides what your clearance lets you see.
Bell-LaPadula: no read up, no write down
Labels say who’s trusted with what, but the clever part of MAC is in the flow rules that use them. The foundational model is Bell-LaPadula, built in the 1970s to protect confidentiality, and it has two deceptively simple rules.
The first is no read up, also called the simple security property. A subject may not read an object classified above its clearance, so a Confidential user can’t open a Secret file. That’s the obvious rule, the reason clearances exist at all. The second is no write down, the star property, written *-property. A subject may not write to an object classified below its clearance, so a Top Secret process can’t write into an Unclassified file. That’s the rule people don’t expect, and it’s the whole point: it stops classified information flowing downward to people not cleared for it.
Stay with the second rule, because it closes the gap DAC left open. Remember the trojan horse: David hands Sara a program that reads a sensitive file and copies it somewhere David can reach. Under Bell-LaPadula, Sara’s process runs at the sensitive level, so it can’t write down to any place that David, at a lower level, can read. The system blocks the leak regardless of what Sara’s program tries or what any owner allowed. MAC controls the flow of information, not just access, and that’s the capability DAC fundamentally lacks. As a slogan: reading down and writing up are allowed; reading up and writing down are not.
---
config:
flowchart:
rankSpacing: 80
nodeSpacing: 55
---
flowchart TD
accTitle: Bell-LaPadula no-read-up and no-write-down rules
accDescr: A subject cleared at the Secret level branches to its four possible operations. Writing to a Top Secret object (write up) is allowed. Reading a Top Secret object (read up) is denied. Reading an Unclassified object (read down) is allowed. Writing to an Unclassified object (write down) is denied. Allowed operations are drawn with solid arrows and denied operations with dotted arrows. The net effect is that information can only ever flow upward, toward higher classification.
SUBJ["Subject cleared: Secret"]
SUBJ --> WU["Top Secret object<br/>write up: ALLOWED"]
SUBJ -.-> RU["Top Secret object<br/>read up: DENIED"]
SUBJ --> RD["Unclassified object<br/>read down: ALLOWED"]
SUBJ -.-> WD["Unclassified object<br/>write down: DENIED"]Two refinements make Bell-LaPadula workable. The tranquility principle says labels shouldn’t change while in use; strong tranquility forbids it outright and weak tranquility allows changes that don’t break the rules, because a label that shifts mid-operation can quietly open a leak. And because pure no-write-down would make it impossible ever to declassify or summarize anything, real systems designate a few trusted subjects, carefully vetted processes or officers allowed to move information downward under controlled review. They’re the deliberate, audited exceptions that keep a rigid model usable, and the fact that they have to be designated and trusted shows how seriously MAC takes downward flow.
Biba: the integrity mirror
Bell-LaPadula protects secrecy, keeping data from leaking down. Sometimes you care about the opposite: keeping low-quality data from corrupting high-integrity data. That’s integrity, and the Biba model is Bell-LaPadula turned upside down. Its rules mirror the original exactly: no read down, so you don’t read data less trustworthy than you and let it corrupt your reasoning, and no write up, so you don’t write into data more trustworthy than you. Where Bell-LaPadula makes information flow upward toward secrecy, Biba makes it flow downward toward less-trusted zones, so trusted data stays clean.
Biba is essentially how Windows Mandatory Integrity Control works, and it explains why a low-integrity process, such as a sandboxed browser tab, can’t write into high-integrity system locations. Confidentiality and integrity are twin concerns, and MAC has a model for each. Real systems often want both at once, which gets complicated quickly, one reason pure multilevel security is rare outside defense while targeted MAC is everywhere.
Beyond secrecy: Clark-Wilson and the Chinese Wall
Bell-LaPadula and Biba are the famous pair, but the MAC family has models for concerns they don’t capture. Clark-Wilson targets commercial integrity. Instead of levels, it insists that data change only through well-formed transactions run by certified programs, and that duties be separated so no single person can both make and approve a change. It’s the formal ancestor of “you can’t approve your own expense report,” the separation of duties that RBAC makes practical in the next article.
The Chinese Wall model, also called Brewer-Nash, captures conflicts of interest, which are dynamic in a way levels aren’t. A consultant may look at one bank’s data; the moment they do, the policy must forbid them from touching a competing bank’s data. Access on one side of the wall removes access on the other, based on history, which no static clearance can express. These models show that MAC isn’t only about military secrecy: the same idea of a system-imposed, non-discretionary policy models financial integrity and conflicts of interest, and those ideas return in policy-based and attribute-based control later on.
MAC in practice: SELinux
The most widely deployed MAC system in the world ships on every Android phone and most enterprise Linux servers: SELinux, Security-Enhanced Linux, originally developed by the NSA and now part of the mainline kernel. It isn’t mainly about military classification levels. Its workhorse is type enforcement: every process runs in a domain, every object has a type, and a central policy states exactly which domains may act on which types. A web server in the httpd_t domain can read files of type httpd_content_t and nothing else, even if the DAC permissions would allow more.
That “even if DAC would allow more” is the essence of MAC, and it’s what saved David’s night. When the compromised web server tried to read the HR exports, the Linux permissions were on the attacker’s side, but SELinux’s policy had never granted httpd_t any access to that type, so the kernel refused. An owner can’t chmod their way around it; the policy is mandatory. That’s why SELinux is such a strong containment tool: it boxes a compromised process into exactly what its role legitimately needs, which is the “assume breach” principle of Zero Trust applied at the operating-system level.
Every labeled thing in SELinux carries a context, written user:role:type:level, for example system_u:object_r:httpd_content_t:s0, and ls -Z or ps -Z will show them. The four fields reveal that SELinux bundles three access-control models at once: type enforcement, the everyday workhorse; an RBAC layer that limits which types a role may reach; and an optional MLS layer, the s0 level, for Bell-LaPadula-style multilevel deployments. Most systems use type enforcement and leave MLS off, which is why “SELinux means military classification” is a common but wrong assumption.
SELinux runs in one of three modes: enforcing, which denies and logs; permissive, which allows but logs what would have been denied, invaluable when developing policy; and disabled. Because a wrong policy blocks legitimate work with cryptic AVC denials, tired operators reach for setenforce 0 to switch to permissive mode and often never switch back, throwing away the whole mandatory layer. The disciplined path is to read the denial, generate a targeted policy adjustment, for example with audit2allow, and stay enforcing. Turning MAC off to make an error go away is the most common way organizations quietly lose the protection they deployed.
MAC everywhere else
Once you know its shape, MAC shows up throughout modern computing. AppArmor, the default on Ubuntu and SUSE, is a path-based MAC that confines programs to declared file paths and capabilities, simpler than SELinux but built on the same mandatory principle. Windows Mandatory Integrity Control tags processes with integrity levels, Low, Medium, High, and System, and forbids low-integrity code from writing to higher-integrity objects. That’s Biba in production, and the reason a sandboxed browser or a downloaded file runs at Low and can’t tamper with your system.
The app sandboxes on iOS and Android are MAC too: a system policy confines each app to its own data and a declared set of entitlements, and no app, however much its developer might wish, can reach another app’s private storage. Containers and hypervisors rely on SELinux or AppArmor profiles to stop a compromised container escaping to the host. Even your browser’s site isolation behaves like MAC, a mandatory boundary the sites themselves can’t negotiate away.
What changed between the failed multilevel mainframes and today’s ubiquitous sandboxes is who does the labeling. Classic MAC asked people to classify data, which was slow and error-prone. Modern targeted MAC labels software components, this app, that service, this container, which a developer or a distribution can define once and ship. The policy is still mandatory and the end user still can’t override it, but the burden moved from classifying every document by hand to declaring what each program may touch, and that shift let mandatory control escape the defense niche and become invisible, default infrastructure on billions of devices.
Multilevel security and why MAC didn’t take over
Running genuinely different classification levels on one system, true multilevel security (MLS), is one of the hardest problems in security, and its history is humbling. In the 1980s and 1990s vendors built MLS operating systems and databases evaluated to the Orange Book’s demanding B1 to A1 classes, and almost all of them failed commercially. They were expensive, slow to certify, and painful to use, and the market for one machine safely handling Secret and Unclassified together was smaller than hoped. Full MLS stayed in defense and intelligence, and its ideas were repackaged into the lighter, targeted MAC that ships today.
Where information really must cross levels, defense systems use a cross-domain solution or guard, a small, heavily assured component whose only job is to move data between a high and a low network under strict rules, inspecting and cleaning every transfer. And to stop a subtle leak in which the mere existence of a high-level record reveals something classified, MLS databases use polyinstantiation: two records can share the same key, one visible at each level, so a low-cleared user querying an apparently free slot never learns that a high-cleared record already occupies it. They’re exotic mechanisms, but they show how deep the commitment to controlling flow, not just access, goes when national security is at stake.
If MAC is strictly stronger than DAC, why is your laptop’s main model still discretionary? Because assurance without usability doesn’t survive real work. The rigidity that blocks the trojan horse also blocks the analyst who legitimately needs to move a chart from a classified deck into an unclassified briefing, and every such point of friction becomes pressure to weaken, bypass, or switch off the policy. History rewarded the models people actually kept enabled. That’s why modern MAC went targeted: instead of classifying everything, SELinux and AppArmor confine a handful of high-risk services, such as web servers and containers, and leave the rest of the system on ordinary DAC. You get most of the containment for a fraction of the labeling cost.
Even a perfectly enforced label policy has a remaining weakness: the covert channel. Bell-LaPadula stops a high process from writing down a file, but two colluding processes can still leak information through side effects the label rules don’t govern. A high process can vary its CPU usage or fill a disk in a pattern a low process watches, signaling bits without ever writing anything classified. These timing and storage channels are slow and hard to exploit, but in the highest-assurance settings they have to be analyzed and reduced. Labels control the named flows of information, not every physical one, so MAC raises the bar enormously without ever reaching an absolute.
Strengths and weaknesses, honestly
MAC provides real control over information flow, the one thing DAC can’t do, so it resists the trojan horse and the confused deputy by structure rather than by vigilance. Its policy is central and consistent: the organization, not each owner, states the rules, so “no Secret data ever reaches an Unclassified channel” can be enforced as an invariant. It’s tamper-resistant by design, since ordinary users, owners included, can’t weaken it. And as a containment layer it’s superb, boxing a compromised process into exactly its labeled needs.
That same rigidity is the cost. Everything has to be labeled, and labeled correctly, and keeping labels accurate as data is created and transformed is genuinely hard. The central policy has to anticipate every legitimate workflow, and when it doesn’t, people hit walls with no discretionary way out, which is why unmanaged MAC gets switched off. It’s administratively heavy and needs specialist skills. It drifts toward over-classification, labeling things higher when in doubt, which then stalls collaboration. And no MAC system fully eliminates covert channels. MAC buys assurance and pays for it in flexibility and effort.
MAC and DAC aren’t alternatives. Real systems run them together, and a request has to pass both the discretionary permissions and the mandatory policy. DAC lets people manage their everyday sharing, and MAC draws the hard lines no sharing may cross. Removing DAC would make systems unusable; removing MAC would remove the guarantees. High-assurance environments keep both, with MAC as the floor that isn’t negotiable.
Back to the research folder
Return to Sara’s /research/roadmap folder from the DAC article, but now imagine the organization runs MAC, with the roadmap classified Confidential and Daniel cleared only to Internal. Sara can still set discretionary permissions, because DAC is still there, but they no longer have the last word. When Daniel tries to open q3.pdf, the mandatory policy compares his clearance with the file’s classification, finds that Internal doesn’t dominate Confidential, and denies him regardless of any ACL Sara added. And if some helpful program of Daniel’s tried to copy the file to an Internal share, no write down would block it, because a Confidential process can’t write to an Internal object.
The leak DAC couldn’t prevent is now structurally impossible, not because Sara was careful but because the system’s policy makes that flow illegal. That’s MAC’s whole value in one scene. It also shows the cost: someone had to classify the roadmap, clear Daniel, and keep both labels up to date. Nobody gets that assurance for free, which is why MAC is used where the stakes justify the overhead and complemented by lighter models everywhere else.
And MAC still leaves something unsolved. It stopped the leak, but it said nothing about why Daniel should or shouldn’t see the roadmap in terms of his job. His clearance is about trust and sensitivity, not about the fact that he works in support and the roadmap belongs to product. Expressing “access follows your job” cleanly, across thousands of employees, is a different problem from controlling information flow, and it’s the one the next model was built for. MAC draws the hard line; RBAC organizes everything inside it.
Where MAC fits, and its modern descendants
In the map from the DAC article, MAC is the answer to uncontrolled information flow. It sits as a mandatory floor beneath the more flexible models: DAC handles owner-driven sharing, RBAC handles job-based access at enterprise scale, ABAC handles context, and MAC, where present, overrides all of them with label rules nobody can negotiate. In a fully layered system a request must satisfy the MAC policy, the DAC permissions, the RBAC role check, and any ABAC rules, and any layer can deny it. MAC is also the conceptual ancestor of ideas you’ll meet later: its central policy that owners can’t override is the seed of policy-based access control and policy as code.
You may never configure a Bell-LaPadula lattice, but you almost certainly work inside its descendants. The data classification tiers most companies run, Public, Internal, Confidential, Restricted, are MAC labels by another name, and the tooling that stamps a sensitivity label on a document and then refuses to let it be emailed outside the company is enforcing no write down in spirit. Data loss prevention (DLP) is the commercial reincarnation of information-flow control: it inspects content, reads or assigns a classification, and blocks flows that would send sensitive data somewhere unauthorized, applied to email, uploads, and USB drives instead of classified networks. The cloud revived these ideas at scale. When you tag a storage bucket or dataset as sensitive and a policy stops it leaving a region or being made public, that’s mandatory, label-driven flow control in cloud vocabulary, and Microsoft Purview sensitivity labels, AWS tags wired into service control policies, and Google’s VPC Service Controls all express “this data may not go there, whoever asks.” Even confidential computing, which keeps data encrypted and isolated from the host operator, pushes the label-and-enforce instinct into hardware.
Knowing this lineage is practical. When a DLP rule annoys you by blocking a legitimate send, you can now see it as a no-write-down rule missing a trusted-subject exception, and you know the right fix is a controlled, audited downgrade path, not switching the rule off.
Recap
Mandatory access control removes discretion to gain assurance. The system decides, not the owner: a central policy based on labels governs access, and no ordinary user, not even an owner, can override it. Labels combine a level with compartments, forming a lattice that enforces both sensitivity and need to know, and access requires the subject’s label to dominate the object’s. The flow rules are the core: Bell-LaPadula, with no read up and no write down, protects confidentiality and closes the trojan-horse gap, and Biba mirrors it for integrity. MAC runs quietly everywhere, through SELinux type enforcement, AppArmor, Windows Mandatory Integrity Control, and the iOS and Android sandboxes, all layered over discretionary permissions. And assurance costs flexibility, so MAC is a firm floor for high-stakes data, complemented by lighter models rather than replacing them.
Three questions to test yourself
- Using the no-write-down rule specifically, explain why Bell-LaPadula stops the exact trojan-horse leak that DAC allows. What would have to be true about the attacker’s target level for the leak to succeed under Bell-LaPadula?
- A teammate says, “We use SELinux, so we’re doing multilevel military security.” Correct the misconception: what does SELinux’s type enforcement actually enforce, and how does that differ from Bell-LaPadula classification levels?
- Your organization wants both to keep secrets from leaking and to keep untrusted input from corrupting critical data. Which model handles each concern, and why can enforcing both at once create conflicting label requirements for the same subject?
Hands-on exercises
- Watch MAC deny something DAC allowed. On an SELinux system, such as a Fedora or RHEL virtual machine, put SELinux in enforcing mode, then make a service read a file outside its allowed type, for example by moving web content to a path not labeled
httpd_content_tand reloading. Watch the denial appear in the audit log even though the DAC permissions are fine, then useaudit2allowto see what policy would be needed. - Find the integrity levels on your own machine. On Windows, use a tool such as Process Explorer to see the integrity level of your browser and of a system process, and confirm the browser runs lower. On a phone, read an app’s declared entitlements or permissions. Connect what you find to Biba’s no write up.
- Design a two-level label scheme. For a small dataset you know, such as HR records and public announcements, define two classifications and two clearances, then write the Bell-LaPadula read and write rules for a subject at each level. Identify one legitimate workflow your rules would block, and describe the controlled exception a real MLS system would need to allow it.
Frequently asked questions
What is Mandatory Access Control (MAC)?
Mandatory access control is an authorization model in which a central, system-wide policy decides access based on security labels, and no ordinary user, not even the owner of a resource, can override it. Subjects carry a clearance, objects carry a classification, and the system compares the two on every access according to fixed rules. It's mandatory because the system imposes the policy instead of leaving it to a user's discretion, which makes it the opposite of DAC.
What is the difference between MAC and DAC?
In discretionary access control (DAC), the resource owner sets the policy and can share access at will. In mandatory access control (MAC), a system-wide policy based on labels governs access, and users, owners included, can't change it. DAC favors flexibility and convenience; MAC favors assurance and control over where information flows. They're usually layered, so a request must satisfy both the discretionary permissions and the mandatory policy.
What is the Bell-LaPadula model?
Bell-LaPadula is the classic MAC model for confidentiality. Its two rules are 'no read up' (a subject can't read data above its clearance) and 'no write down' (a subject can't write to a level below its clearance). Together they stop classified information flowing down to people not cleared for it, which is exactly the trojan-horse leak DAC can't stop. Biba is its mirror image for integrity: no read down, no write up.
Is SELinux an example of MAC?
Yes. SELinux (Security-Enhanced Linux) is the best-known modern MAC implementation. It labels every process and object with a security context and enforces a central policy, mainly through type enforcement, that the file's owner can't override with chmod. AppArmor, Windows Mandatory Integrity Control, and the app sandboxes on iOS and Android are other everyday MAC mechanisms layered on top of discretionary permissions.
Why is MAC harder to use than DAC?
Because the rigidity that makes MAC secure also makes it inflexible: every subject and object has to be labeled correctly, the central policy has to anticipate legitimate workflows, and users can't grant a quick exception when the policy blocks real work. Mislabeling breaks things, over-classification stalls collaboration, and running the policy is a specialist skill. That administrative weight is why MAC is reserved for high-assurance needs rather than used everywhere.