Free preview

Untrusted Tasks and Isolation

In one line: Lesson 5's ScriptPath column means the scheduler executes arbitrary code supplied by customers on machines shared with other customers. That is the strongest trust assumption in the entire course.

The three controls

ControlDetail
Authentication and authorizationStrictly control access to resources
SandboxingIsolate code execution using containers (Docker) or virtual machines
Performance isolationMonitor resource utilization and cap or terminate tasks that exhibit atypical behavior

Three controls, three distinct threats — they are not redundant

Each defends against something the others do not, which is why all three are needed:

Authentication and authorization answers "should this task exist at all?" It stops an attacker submitting tasks as someone else, or a legitimate tenant reaching resources they did not pay for. It operates before execution.

Sandboxing answers "can this code touch anything outside itself?" It stops running code from reading another tenant's data, tampering with the host, or reaching the network where it should not. It operates during execution, and it is a correctness boundary — either the isolation holds or it does not.

Performance isolation answers "is this code consuming more than its share?" Sandboxing does not provide this — a container can be perfectly isolated and still consume every CPU cycle on the box, degrading its neighbours without ever escaping. This is the noisy-neighbour problem, and it needs quotas and monitoring rather than isolation.

That third distinction is the one candidates miss. Sandboxing stops you reaching out; performance isolation stops you crowding out. Different threats, different mechanisms.

Containers versus VMs is a real trade, and the answer depends on the trust level

The design offers both, and they are not equivalent:

Containers share the host kernel. Startup is milliseconds, overhead is small, density is high — you can pack many on a machine. But a kernel vulnerability breaks the isolation, so the security boundary is only as strong as the kernel's syscall surface.

Virtual machines have their own kernel with a hypervisor boundary. Startup is seconds, overhead and memory footprint are larger, density is lower. But the boundary is much stronger.

Given Lesson 3's assumption that most tasks are short-lived (seconds to minutes), VM startup time is a real cost — spending seconds booting to run a ten-second task is poor utilization.

That tension is exactly why lightweight VMs exist: AWS built Firecracker for Lambda to get VM-grade isolation with container-grade startup. Mentioning that shows you understand the trade rather than just naming two technologies.

The decision rule: containers for code you partly trust, VMs for code you do not trust at all. Multi-tenant execution of arbitrary customer code is the second case.

Performance isolation is where the scheduler's own requirements come back

"Cap or terminate tasks that exhibit atypical behavior" reuses machinery already in the design:

  • Lesson 5's ResourceRequirements declares what a task should consume, so exceeding it is detectable.
  • Lesson 7's execution cap bounds how long it runs.
  • Lesson 4's resource manager already "terminates tasks that exceed their allocated resource limits."

So performance isolation is largely enforcement of the declared contract rather than new machinery. A task said it needed the Basic tier; consuming Premium-tier resources is a violation the resource manager can see and act on.

Note the honest difficulty carried over from Lesson 7: "atypical behavior" is as hard to define as distinguishing an infinite loop from a legitimate long run. A task using 100% CPU may be efficient or may be mining cryptocurrency. Declared limits are enforceable; intent is not — which is precisely why the design leans on explicit resource declarations rather than trying to infer malice.

The blast radius argument — why isolation is worth its cost

Isolation is expensive. It costs startup time, memory overhead, and density, and Lesson 7 established that idle capacity is money.

The justification is blast radius. Without isolation, one tenant's bug or attack can:

  • Read another tenant's data — a breach, not an outage.
  • Crash the host, taking down every task on it.
  • Consume the machine, degrading every neighbour.

The first is categorically worse than the others. An outage is recoverable; a cross-tenant data breach is a reportable incident, a legal exposure, and a permanent loss of trust.

This is the same reasoning as distributed logging's per-tenant pub-sub instances and CDNs's cells: isolation costs efficiency, and you buy it when the blast radius of a leak is unacceptable. For arbitrary code from paying strangers, it plainly is.

The three controls are not alternatives. Isolation stops a task reading another tenant's data, resource caps stop it starving the fleet, and network policy stops it using your infrastructure as a launch point — and a design with only the first has answered one third of the question.

Key takeaway

Running customer code on shared infrastructure needs three distinct controls: authentication decides whether the task should exist, sandboxing stops it reaching out, and performance isolation stops it crowding out — sandboxing does not provide the third. Containers versus VMs trades startup and density against boundary strength, and short-lived tasks make VM startup costly. Performance isolation is mostly enforcement of the declared resource contract, because limits are enforceable and intent is not.

Interview signal by level

LevelWhat a strong answer sounds like
L4"Run tasks in containers so they're isolated."
L5Adds the other two controls: "authenticate and authorize before we accept the task, sandbox it in a container or VM during execution, and monitor resource usage to terminate anything behaving abnormally."
Staff+Separates isolation from resource control: "sandboxing stops you reaching out; it doesn't stop you crowding out — a perfectly isolated container can still consume every cycle on the box, so noisy-neighbour needs quotas, not isolation. On containers versus VMs: shared kernel means a kernel bug breaks the boundary, so arbitrary customer code argues for VMs — except our tasks are seconds-long and VM boot is seconds, which is exactly why lightweight VMs like Firecracker exist. And performance isolation is mostly enforcing the declared ResourceRequirements, because a declared limit is enforceable while 'atypical behaviour' isn't decidable — 100% CPU is either efficient or crypto mining."

Next: checking the design against the requirements.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue