Abstract

The strongest-sounding security control is physical isolation: no network, no leak. This piece studies why that intuition is wrong. We start from Lampson's 1973 confinement problem, which named the covert channel — a path never designed for communication that a confined program can still modulate to signal out. We follow it to the air-gap myth, where physically isolated machines have been shown to leak through sound, heat, light, electromagnetic emission, and power draw, and then to the modern agent, which can exfiltrate through the very outputs and side effects you allowed it. The defense is not a wall but an accounting: enumerate every shared observable a component can influence, throttle and monitor the ones you cannot remove, and accept that perfect confinement is impossible, so residual channels must be watched rather than wished away.

The most reassuring words in security are 'it's air-gapped.' Pull the network cable, the reasoning goes, and data has nowhere to go. But data does not need a wire; it needs any shared thing a confined program can change and an observer can sense. A fan that spins faster, a chip that runs hotter, a screen that flickers, a response that takes a beat longer — each is a channel that was never meant to carry a message and therefore was never guarded. The leak does not travel down the path you secured. It travels down the one you never thought of as a path at all.

The assumption: no wire, no leak

Isolation feels like a complete answer because it targets the obvious channel: if there is no connection, there is no conversation. The unstated assumption underneath is stronger and shakier — that the only ways information can leave are the ones designed to carry it, so removing those removes the risk entirely.

Butler Lampson punctured that in 1973 with the confinement problem: how do you run a program so it cannot leak the data it processes? His answer was uncomfortable. Beyond the legitimate channels, there are covert channels — paths not intended for communication that a program can nonetheless use to signal, by modulating any resource an observer can measure. Naming them made clear they are the rule, not an exotic exception.

This class is relational between a confined component and a shared environment: the component is correctly denied its official outputs, yet it influences something outside its box that someone else can read. The isolation is real; the leak routes around it through a channel no one classified as one.

🛡️ Countermeasures
  • Redefine 'leak' in the design: any shared, observable resource a component can influence is a potential channel, not just the network.
  • Enumerate channels explicitly rather than assuming isolation closed them, and decide for each whether to remove, throttle, or monitor it.
  • Treat confinement as a bandwidth-reduction and monitoring problem, not a binary that isolation solves outright.

What a covert channel actually is

A covert channel needs only two things: a resource shared between a sender inside the boundary and a receiver outside it, and the sender's ability to change that resource in a way the receiver can distinguish. Classic taxonomy splits them in two. A storage channel signals by setting some observable state — a file's existence, a lock, an error code, a counter. A timing channel signals by modulating when things happen — how long an operation takes, the gaps between events.

The bandwidth can be tiny and still matter. One bit per second is glacial for a video call and more than enough to leak a key overnight. The sender does not need a fast channel; it needs a reliable one and patience, which is why covert channels are so hard to dismiss as theoretical.

The crucial reframe is that the 'channel' is almost never a component's job. It is a side effect of doing its job — using memory, taking time, touching a shared counter — which is exactly why enumerating channels is hard and why isolation of the official paths leaves them open.

A covert channel is any shared observable the confined component can modulate and an observer can read. Where a confined program can leak Covert channel not a designed path Storage channel sets shared state Timing channel modulates when Resource use memory / locks Physical emission heat / sound / power
A covert channel is any shared observable the confined component can modulate and an observer can read.
🛡️ Countermeasures
  • Inventory both storage and timing channels for any confined component, not just its intended outputs.
  • Reduce shared observable state across the boundary (separate resources, cleared counters, uniform error codes) to close storage channels.
  • Normalize timing (padding, fixed schedules) on the observables an outsider can measure to shrink timing channels.

The air-gap myth

Physical isolation raises the bar but does not remove the channels; it just pushes them into physics. A long line of research, much of it by Guri and colleagues, has demonstrated that a machine with no network can still emit data through the analog world: modulating fan or drive noise into acoustic signals, varying processor load to change heat or power draw, blinking indicator lights or screen pixels for an optical receiver, and turning components into weak radio transmitters. A nearby microphone, camera, thermometer, power meter, or radio becomes the receiver.

None of these defeat the air gap as an isolation of networks; they exploit the fact that a computer is a physical object whose activity leaks into its surroundings. The malicious code inside still cannot send a packet — it modulates a fan instead, and the fan is not on anyone's list of network interfaces.

Defenses move to the physical domain: create zones of separation so no untrusted receiver is within range, shield or dampen emissions, remove or disable emitters (speakers, unnecessary indicators, radios), and monitor the environment for the receivers these channels require.

An isolated machine modulates a physical emission that a nearby sensor, not a network, receives. Leaking across the gap the air gap (no network) Isolated machine no network Physical emission sound / heat / light Nearby sensor mic / camera / meter Data recovered slow but reliable modulates crosses air demodulates
An isolated machine modulates a physical emission that a nearby sensor, not a network, receives.
🛡️ Countermeasures
  • Enforce zones of separation so no untrusted receiver (microphone, camera, radio, power meter) sits within range of a sensitive machine.
  • Remove or disable unnecessary emitters — speakers, status lights, radios — and shield or dampen the ones that remain.
  • Monitor the physical environment for the receivers these channels need, and restrict devices around high-sensitivity systems.

Confinement is always leaky

The air gap is a dramatic case of a general truth: any component you confine still touches shared resources to do its work, and each touch is a potential signal. Sandbox a process and it still uses CPU time, allocates memory, returns error codes, and takes measurable durations — all observable, all modulable. The confinement bounds the official outputs; it cannot bound the side effects of computing at all.

This is why the confinement problem has no clean solution, only mitigations. You can remove some shared observables, add noise to others so the signal drowns, and cap the rate at which a component can change any of them — each of which lowers the covert bandwidth without closing it to zero. The goal shifts from prevention to making the channel too slow and too noisy to be worth an attacker's time for the data at stake.

Framed that way, confinement is a budget: how much covert bandwidth can you tolerate for a given secret, and what will you spend — in noise, in throttling, in monitoring — to push the channels below it?

🛡️ Countermeasures
  • Remove shared observables where feasible; where not, inject noise so the covert signal is hard to separate from normal variation.
  • Rate-limit how quickly a confined component can change any shared resource, capping the covert bandwidth.
  • Set a tolerated-bandwidth budget per secret and drive the channels below it, monitoring the residual.

The AI angle: leaking through the channel you allowed

An agent or model is the confinement problem in a new costume. Even if you sandbox it — no arbitrary network, a narrow tool allow-list, reviewed outputs — it still has to produce output to be useful, and that output is a channel. A compromised or manipulated model can encode secrets in the content it is allowed to return: word choices, formatting, the length or timing of a response, the order or pattern of the tool calls it makes. The data leaves through the door you deliberately left open.

The channels are natural to the workload. A summarizer can steganographically embed a leaked value in the phrasing of a summary; a coding agent can hide bytes in variable names or whitespace; a retrieval agent can signal through which documents it chooses to cite or how long it 'thinks'. None of this trips a network-egress rule, because the exfiltration rides the legitimate output.

The countermeasures are the confinement ones applied to outputs: constrain and canonicalize what the model may emit, monitor the semantics and rate of egress rather than only its destination, and seed canary secrets so an attempt to smuggle them out is detected downstream.

The goal is reached by encoding secrets in permitted outputs and side effects, not by opening a new channel. Exfiltrating through allowed output Leak past the sandbox no new channel outputs still allowed Encode in output wording / whitespace Modulate side effects timing / tool order Receiver decodes rides legit egress
The goal is reached by encoding secrets in permitted outputs and side effects, not by opening a new channel.
🛡️ Countermeasures
  • Constrain and canonicalize model output (structured schemas, normalized formatting, capped length) so there is little room to encode a hidden payload.
  • Monitor the semantics and rate of egress — what is leaving and how fast — not only its network destination, and rate-limit sensitive outputs.
  • Seed canary secrets into the environment so any attempt to smuggle them out through outputs or tool calls is detected downstream.

Why perfect confinement is impossible

It is tempting to believe that with enough isolation the channels close. They do not, for a simple reason: a component that produces no observable effect at all is a component that does nothing useful. The moment it has any output, any timing, any resource footprint an outsider can measure, it has a channel of nonzero capacity. Utility and total confinement are in direct tension.

So the honest engineering position is that you can shrink covert bandwidth arbitrarily close to zero — with noise, throttling, and removal of observables — but never reach it while the component remains useful. There is always a residual channel, and the only questions are how slow you have made it and whether you are watching it.

Framed that way, confinement becomes a monitoring commitment as much as a control: since some channel always remains, you must detect its use rather than assume its absence.

⚠️
Utility keeps a channel open. A component with zero observable effect is useless; any useful component has a channel of nonzero capacity, so confinement reduces and monitors leakage — it never eliminates it.
🛡️ Countermeasures
  • Accept a residual channel for any useful component and commit to monitoring it rather than declaring it closed.
  • Push covert bandwidth below the value of the secret with noise and throttling, and document the residual you accept.
  • Re-evaluate when the component gains new outputs or observers, since each addition reopens capacity.

Finding and throttling the channels

Because a covert channel is a modulable shared observable, you can hunt for it the way you would profile a system: enumerate what a confined component can influence — files, counters, error codes, timing, emissions, output content — and, for each, estimate how much information it could carry per unit time. The high-bandwidth channels get closed or throttled first; the rest get monitored.

For an agent, the same discipline maps to egress: catalog every way output and side effects leave the sandbox, measure how much entropy each could smuggle, and put the widest ones under structural constraints and rate limits. Canary secrets turn the abstract into an alarm — if one ever appears where it should not, a channel was used.

The harness stays strictly defensive: it profiles your own component's observable footprint and plants your own canaries to detect misuse; it never builds a working exfiltration tool against a system you do not own.

List the channels a component can modulate, estimate each one's bandwidth, throttle the widest, and monitor the rest. Enumerate, estimate, throttle, watch Enumerate channels outputs & side effects Estimate bandwidth bits per second Throttle widest constrain / noise Monitor residual canaries & rate
List the channels a component can modulate, estimate each one's bandwidth, throttle the widest, and monitor the rest.
🛡️ Countermeasures
  • Maintain a channel inventory per confined component with an estimated bandwidth for each observable, and gate releases on it.
  • Constrain and rate-limit the highest-bandwidth channels first, then monitor the remainder with canaries and egress-rate alerts.
  • Threats to validity: an enumeration only covers the channels you imagined — combine it with removing observables so the unimagined ones have less to carry.

The discipline: account for every channel

Every countermeasure here is one refusal: do not equate isolation with confinement. Removing the official channel does not remove the covert ones, so you enumerate every shared observable a component can influence, remove what you can, throttle and add noise to what you cannot, and monitor the residual that always remains.

The reusable artifact is an assumption-ledger entry: the unstated assumption is that cutting the designed channel stops the leak; the reason it fails is that any useful component modulates shared observables an outsider can read; the tell is any correlation between a confined component's secret and an external observable — or a canary appearing outside; and the assumption-free control is channel enumeration, bandwidth reduction, and monitoring. Carry that entry to any boundary — an air gap or an agent sandbox — and ask the one question this class demands.

Ask it wherever you have confined something: what can this still change that someone outside can measure? Every honest answer is a channel — and the ones you do not name are the ones that leak.

🛡️ Countermeasures
  • Adopt one rule per confined component — enumerate, throttle, monitor — and record the residual bandwidth you accept.
  • Instrument egress semantics and plant canaries so covert use becomes a visible event, not a silent one.
  • Audit agent sandboxes specifically for exfiltration through allowed outputs and side effects, the modern air gap.

Key takeaways

  • A covert channel is a shared observable a confined component can modulate to signal out — never a designed path — so isolating the official channels leaves it open.
  • The broken assumption is that no wire means no leak; Lampson's confinement problem showed storage and timing channels route around isolation.
  • The air gap is a myth of completeness: isolated machines have leaked through sound, heat, light, electromagnetic emission, and power draw to nearby sensors.
  • A sandboxed agent or model can exfiltrate through the outputs and side effects you allowed — wording, whitespace, timing, tool-call patterns — riding legitimate egress.
  • Perfect confinement is impossible: any useful component has a channel of nonzero capacity, so defense reduces bandwidth and monitors the residual rather than eliminating it.
  • Hunt channels by enumerating what a component can modulate, estimating each one's bandwidth, throttling the widest, and planting canaries to detect use.

Practitioner Toolkit

Copy-paste, strictly defensive artifacts you can use today. Nothing here attacks a real system.

Covert-channel review checklistchecklist

Run this for every confined component or boundary.

  • List every shared observable the component can influence: files, counters, error codes, timing, emissions, output content.
  • Estimate a bandwidth for each and rank them; do not assume isolation closed any.
  • Close or throttle the highest-bandwidth channels; add noise where you cannot remove the observable.
  • For agents, catalog every way outputs and side effects leave the sandbox and constrain the widest.
  • Plant canary secrets and alert if one ever appears outside its boundary.
  • For air-gapped systems, enforce separation zones and remove unnecessary emitters.
🔒Egress-constraint rulepolicy

A drop-in rule for agent output channels.

def release(output):
    o = to_schema(output)              # structured, minimal free-form room
    o = normalize(o)                   # canonical formatting, capped length
    if contains_canary(o) or over_rate(o):
        return quarantine(o)           # possible covert exfiltration
    return emit(o)                     # monitor semantics + rate, not just destination
Constrain, normalize, and rate-limit output; scan for canaries before release.
🧪Channel-bandwidth profilerharness

Estimates how much a channel could leak, on your own system.

def channel_bandwidth(run, observe, secret_A, secret_B, trials=10000):
    a = [observe(run(secret_A)) for _ in range(trials)]
    b = [observe(run(secret_B)) for _ in range(trials)]
    return mutual_information_estimate(a, b)   # bits the channel can carry
# Profile your own component's observables; never build a real exfil tool.
Drive a confined component with two secret values and measure how distinguishable an observable is.
🚀Minimum viable defense — do these firstquickstart

The highest-leverage steps before deeper hardening.

  • Enumerate a confined component's channels; do not equate isolation with confinement.
  • Constrain and rate-limit agent output; monitor egress semantics, not only destination.
  • Plant canary secrets and alert on any external appearance.
  • For air gaps, enforce separation zones and strip unnecessary emitters.

Glossary

Covert channel
A path not intended for communication that a confined program uses to signal out by modulating a shared observable.
Confinement problem
Lampson's question of how to run a program so it cannot leak the data it processes; it has mitigations, not a full solution.
Storage channel
A covert channel that signals by setting observable shared state such as a file, lock, or error code.
Timing channel
A covert channel that signals by modulating when events happen, such as operation durations or gaps.
Air gap
Physical isolation of a system from networks; it removes the designed channel but not covert physical emissions.
Covert bandwidth
The rate at which a covert channel can carry information; reducible with noise and throttling but not to zero for a useful component.
Canary secret
A planted, monitored value whose appearance outside its boundary reveals that a covert channel was used.

References

  1. Lampson, A Note on the Confinement Problem (CACM, 1973)
  2. MITRE ATT&CK: Exfiltration (TA0010)
  3. MITRE ATT&CK: Exfiltration Over Physical Medium (T1052)
  4. MITRE ATLAS (Adversarial Threat Landscape for AI Systems)
  5. OWASP Top 10 for Large Language Model Applications
  6. NIST AI Risk Management Framework (AI RMF 1.0)