
A virtual machine is a software-based simulation of a physical computer. Think of it like an apartment in a building:
Just like apartment tenants shouldn't be able to walk into each other's units, VMs must be completely separated from each other. Without isolation:
Isolation = the guarantee that what happens in one VM cannot affect or be seen by another VM
A hypervisor is the software layer that sits between physical hardware and virtual machines. It:
Traditional hypervisors like the Nitro Hypervisor do many things:
This complexity makes them hard to verify for correctness — there are too many moving parts to mathematically prove they work perfectly.
A hypervisor is like a building manager who handles rent, repairs, security, and scheduling — doing everything makes it hard to guarantee any one thing is done perfectly.
A separation kernel is a minimal software component with one job only: enforcing isolation between compartments.
| Policy (decisions) | Mechanism (enforcement) |
|---|---|
| Which VMs to create | Actually isolating them |
| How to allocate resources | Checking every request |
| When to schedule a VM | Blocking unauthorized access |
The separation kernel only does mechanism — it doesn't decide what to isolate, just enforces the isolation once told to.
By stripping away everything except isolation enforcement, the separation kernel becomes:
AWS extracted the isolation logic from the full Nitro Hypervisor into a dedicated Nitro Isolation Engine — their separation kernel. The full hypervisor still handles policy but must ask permission from the Isolation Engine before touching any VM state.
Normal software testing checks: "Did it work in these specific cases?"
But testing cannot prove software works in all cases. There are always edge cases you didn't think to test.
Formal verification uses mathematical proofs to show that software behaves correctly in every possible situation — not just the ones you tested.
Isabelle/HOL (Higher-Order Logic) is a proof assistant — software that:
Think of it as a very strict math teacher that checks every line of your proof and won't accept hand-waving.
AWS's proof comprises 330,000 lines of machine-checked mathematics — comparable to seL4, the landmark OS verification project that inspired this work.
Before you can prove software is correct, you need to precisely define what "correct" means. A formal specification is an exact mathematical description of how the system should behave.
Specifications are written as contracts:
PRECONDITION: What must be true BEFORE the program runs
POSTCONDITION: What must be true AFTER the program runs
Example from the article: When a virtual CPU that is already running tries to turn itself on:
AlreadyOn, and nothing else changesTheir specifications guarantee total correctness, meaning:
The article describes four types of guarantees the proofs establish:
None value in Rust (like accessing a null pointer)Full Rust has many advanced features (traits, dynamic dispatch, complex lifetimes) that make formal reasoning very difficult.
AWS created μRust, a restricted subset of Rust that:
The meaning of μRust programs is defined directly in terms of higher-order logic — the language Isabelle/HOL understands. This means:
μRust is like a simplified version of English designed for legal contracts — it loses some expressiveness but gains precision and unambiguity.
Low-level programs manipulate memory directly using pointers. Reasoning about this is tricky because:
Separation Logic is a specialized mathematical logic designed to reason about programs that manipulate memory. Its key feature:
It lets you say: "This piece of code only touches this region of memory, and that piece of code only touches that region — and those regions are separate."
This makes it much easier to reason about what a function does and doesn't affect.
The Nitro Isolation Engine must guarantee that operations on one VM's memory never touch another VM's memory. Separation Logic is the perfect tool for expressing and proving this.
Given a program and a desired outcome (postcondition), what is the least restrictive starting condition that guarantees the outcome?
result = x + yresult is a valid integer (no overflow)x + y must not exceed the maximum integer valueThe "weakest" precondition is the most permissive one — it doesn't over-constrain the inputs.
This gives a systematic, mechanical way to verify programs — which is why it can be automated.
The formal verification works at two levels:
How do you connect these two levels?
Refinement is a proof technique that shows:
"Every behavior possible in the concrete implementation is also a valid behavior in the abstract specification."
In other words, the implementation is a faithful realization of the high-level spec — it doesn't do anything the spec doesn't allow.
Think of a blueprint (high-level spec) and the actual building (implementation). Refinement proves the building matches the blueprint — every room, every wall, every door is where the blueprint says it should be.
"Confidentiality" is an intuitive concept, but to prove it mathematically, you need a precise definition.
Noninterference says:
If two system states are indistinguishable to an observer before a step, they must remain indistinguishable after the step.
Consider two machines, A and B, each with:
Before: A and B have the same public register value → they look identical to the observer.
Bad program: "If private register = 1, set public register = 1"
After running this program:
Now A and B look different — the observer can deduce the private values! This is an information leak.
If indistinguishability is always preserved:
BEFORE: AFTER (BAD program):
A: pub=5, priv=0 A': pub=0, priv=0 ← different!
B: pub=5, priv=1 B': pub=1, priv=1 ← observer can now distinguish!
↑ indistinguishable ↑ distinguishable = information leaked
Here's how all the concepts connect in the Nitro Isolation Engine verification:
GOAL: Prove VMs are truly isolated from each other
STEP 1: Extract isolation logic into a SEPARATION KERNEL
(Nitro Isolation Engine — small, focused, auditable)
STEP 2: Write the engine in μRUST
(verifiable subset of Rust)
STEP 3: Write FORMAL SPECIFICATIONS
(pre/postconditions using SEPARATION LOGIC)
STEP 4: Prove FUNCTIONAL CORRECTNESS
(using WEAKEST PRECONDITION CALCULUS in Isabelle/HOL)
STEP 5: Connect implementation to high-level spec
(using REFINEMENT)
STEP 6: Prove CONFIDENTIALITY and INTEGRITY
(using NONINTERFERENCE / indistinguishability preservation)
RESULT: Mathematical guarantee that no VM can read or modify
another VM's data — ever, in any circumstance
| Concept | What It Is | Why It Matters |
|---|---|---|
| Virtual Machine | Software-simulated computer | Multiple customers share hardware |
| Hypervisor | Manages VMs on hardware | Creates and enforces VM boundaries |
| Separation Kernel | Minimal isolation-only component | Small enough to formally verify |
| Formal Verification | Mathematical proof of correctness | Guarantees beyond testing |
| Isabelle/HOL | Proof-checking software | Mechanically validates every proof step |
| Specification | Precise definition of correct behavior | Defines what we're proving |
| μRust | Verifiable subset of Rust | Expressive yet formally tractable |
| Separation Logic | Logic for memory reasoning | Proves memory regions don't overlap |
| Weakest Precondition | Systematic proof technique | Automates correctness proofs |
| Refinement | Connects abstraction levels | Links spec to implementation |
| Noninterference | Indistinguishability preservation | Makes confidentiality mathematically precise |