Most Viruses Should Be Impossible by Construction
Antivirus software is a tax. We pay it because the operating system hands every program we run the keys to everything we own.
Double-click an installer. On Windows, macOS, or Linux, that program starts life with roughly the same power you have. It runs as you. It can read your documents, your photos, your browser cookies, your SSH keys. It can open a socket to anywhere on the internet. It can walk your entire home directory and do whatever it likes with what it finds. You granted it none of this. It arrived with all of it, by default, the instant it started, because that is what running “as a user” means.
This is ambient authority: a process can act because of who it is, the user id it inherited, instead of what it was handed. Once you accept that model, almost every category of malware we worry about is just a program doing exactly what the OS allowed.
Ransomware reads your files and encrypts them, exploiting no bug at all. It is allowed to read your files and write them back. A data-stealer reads your secrets and opens a network connection, both sanctioned operations. A file infector rewrites executables on disk, also allowed. The malicious program is not breaking the rules. The rule was that there are no rules.
Antivirus is a sane answer to an insane default
Mocking antivirus would be unfair. Given a world of ambient authority, signature scanning and behavioral detection are the correct engineering response. If every program can touch everything, the only place left to intervene is to watch what programs do and recognize the bad ones. Match a known-bad byte pattern. Notice that a process just opened four hundred files in your Documents folder and started writing high-entropy data over them. Flag the new binary phoning home to an IP in a sketchy range.
This works, sort of, and the people who build it are very good at it. But it is a symptom fight. Detection runs after the dangerous capability is granted, so it is a race: the scanner against the payload, the signature database against the next variant, the heuristic against the obfuscator written specifically to defeat it. You can win that race most of the time. You cannot win it by construction, because the underlying grant was made before the fight started. The whole edifice exists to claw back authority that should never have been ambient.
Take away the capability and the malware has nothing to do
Cathedral starts from the opposite default. There is no ambient authority. Not the filesystem, not the clock, not the network, not even the power to spawn another process. Authority is always a capability: an unforgeable value that confers one specific, narrow power, obtained through a visible path, held by a principal, and revocable. If a program can do something, it is because it holds something that lets it.
A capability reads like a typed handle over a specific object:
Capability<File::Write("/users/zach/docs/report")>
Capability<Network::Connect("api.stripe.com:443")>
Capability<Clock::Read>
A program holds the authority it was given and nothing else. The consequence worth sitting with: a program that holds no capability to your files literally cannot read them. Not “is checked and denied.” There is no global filesystem root in its address space waiting to be reached, no ambient /home it can enumerate, no open() that succeeds because the user id matched. The authority to name your documents is a value, and that program was never handed it.
So consider ransomware here. It wants to encrypt your files, which means reading them, which requires a read capability it does not have. It cannot ask silently, because minting fresh authority is the job of a small set of trusted brokers: a host prompt, the store, the OS loader. It cannot derive it from something it already holds, because you only ever narrow a capability, never widen one. A handle to its own scratch folder does not transitively become a handle to your tax returns. The encrypt-everything payload sits on top of an authority graph containing exactly what you let it touch, which for a photo editor or a game is approximately nothing of yours.
A data-stealer hits the same wall from two sides. Reading your secrets needs a capability over them; exfiltrating them needs a network capability. Here Cathedral does something even ambient-authority systems with per-permission prompts cannot: it reasons about the combination. A policy ceiling can forbid a conjunction even when each grant alone would be fine.
// A ceiling can forbid a combination even when each grant alone is allowed.
deny Principal::App when
holds Capability<Read<Photo>> and
reaches effect network_io;
Photo-read plus network is a different animal than either alone. Legacy permission systems grant them one at a time and never reason about the pair. The whole class of “benign-looking app that reads your data and also happens to phone home” is a combination the system can refuse to allow to exist.
This is what “sandboxing by default” means. Sandboxing here is what the capability model already produces: a component never handed a capability cannot use that authority, so the default is the sandbox. The interesting policy work is setting ceilings on an already-minimal, already-visible authority flow, instead of clawing power back from a process that started omnipotent.
Be precise about the boundary
Cathedral does not make all malware impossible, so let me be exact about what it removes and what it does not.
It removes whole classes defined by access to things you own: ransomware, data-stealers, file infectors, the broad family of “a program I ran touched data it had no business touching.” Those depend on ambient authority over your files and network. Take the authority away and the category has nothing to operate on. The claim holds for any program regardless of language, because the confinement is on system access, not on the program’s instructions. A C++ binary asking to read a file goes through the same capability check as anything else. If it does not hold the handle, the read does not happen. The language the malware was written in is irrelevant to whether it can name your documents.
It does not remove what lives inside a granted capability or below the capability layer. Hand a program a capability over a folder and it can still do bad things in that folder. A genuinely malicious app you grant broad authority to is still malicious; capabilities make the grant explicit and revocable, they do not read intent. And there is a hardware floor worth naming.
Cathedral’s own code is written in Omega and is proof-carrying, so OS components isolate from each other by the type system. But a user app can be written in anything, C++ included, and the OS cannot trust an instruction stream its toolchain did not compile. Raw CPU instructions in a native binary, an rdtsc here, a stray memory write there, are confined by the hardware rather than the language: a separate address space, the memory management unit (MMU), and where used, virtualization to trap instructions. So the isolation story has two layers. OS code is language-isolated. App code is hardware-isolated and capability-confined: the MMU keeps its instructions out of memory it does not own, and the capability model keeps its system access to exactly the authority it holds. Both layers do real work; neither alone is the whole story.
That hardware floor is also why “make a sandbox completely undetectable to the code inside it” is not free for native binaries. A program that reads raw CPU state directly can sometimes tell it is being virtualized. Confining what it can do to your system holds regardless; making it believe a fabricated reality, down to the timestamp counter, is the part that needs hardware trapping. That is the only residue.
The mental model
Antivirus asks, every day, forever: is this program behaving badly right now? Cathedral asks once, at grant time: does this program hold the authority to do the bad thing at all? Most of the time the answer is no, and a program that holds no key cannot turn a lock that was never given to it.