Kaggle Notebook Sandbox Architecture: Design Notes for Secure Execution
An architecture note outlining the requirements, minimal design, trust boundaries, operational checks, failure modes, and design‑change triggers for Kaggle’s container‑based notebook execution environment.
22 Feb 2026, 18:37 UTC

Requirements
Kaggle Kernels must execute arbitrary user‑supplied Python/R code while protecting the shared infrastructure from:
- Resource exhaustion (CPU, memory, disk) that could affect other users.
- Unauthorized network traffic that could lead to data exfiltration or abuse.
- Accidental or malicious modification of the host filesystem or other users’ data.
At the same time, the platform must provide a responsive experience: low startup latency, access to common data‑science libraries, and a writable location for notebook outputs that persists until the user explicitly saves them.
Smallest Suitable Design
Container Base Image
The execution environment starts from a Docker‑derived image that contains a minimal Linux distribution plus a pre‑installed stack of libraries (NumPy, Pandas, Scikit‑learn, etc.). This “pre‑baked” image satisfies the latency requirement because the container can be started without downloading large dependency layers at runtime.
Resource Controls via cgroups
Each kernel session is placed in its own cgroup that enforces hard limits on:
- CPU shares (e.g., 2 vCPU equivalent).
- RAM (typically 9 GB for free tiers, higher for paid).
- Disk usage for the writable layer (≈5 GB).
These limits are applied by the container runtime before the user process starts, guaranteeing that a runaway notebook cannot consume more than its quota.
Network Sandbox
Outbound traffic is filtered by an egress whitelist managed at the container‑network level (often via iptables or a CNI plugin). Only domains required for package indexes (pypi.org, anaconda.org) and a few approved APIs are allowed; all other destinations are dropped.
Data Boundaries
Input datasets are mounted read‑only into the container at a predictable path (e.g., /kaggle/input). The writable layer for outputs is mounted at /kaggle/working and is ephemeral: it disappears when the container stops unless the user explicitly commits the file as a versioned output.
Trust and Data Boundaries
The trust model assumes:
- The host kernel and container runtime are trusted.
- User code is untrusted and must be confined.
- Input data is trusted only insofar as it is provided by Kaggle or the user; it is made read‑only to prevent tampering with the source.
- Outputs are trusted to the extent that the user chooses to save them; otherwise they are treated as transient.
These boundaries are enforced by the combination of read‑only mounts, cgroup limits, and the network whitelist. No privileged capabilities (e.g., SYS_ADMIN) are granted to the container.
Operational Checks
- Verify pre‑installed libraries: In any notebook cell run
!pip list(or!conda list). Expected check: the output includes entries for numpy, pandas, scikit‑learn with version numbers. No special permissions are needed; the command runs as the notebook user. Risk: none beyond normal command execution. - Confirm network egress filtering: Execute
!ping -c 1 8.8.8.8. Expected check: the command fails with “Network is unreachable” or similar, indicating the ICMP packet was dropped. No extra privileges required. Risk: none; the packet is simply dropped by the host. - Observe memory enforcement: Run a cell that allocates a large array, e.g.,
import numpy as np; a = np.zeros((10000, 10000))(≈800 MB). Then check the built‑in resource monitor (sidebar) or run!free -m. Expected check: used memory rises but never exceeds the configured limit; if the limit is surpassed the kernel will terminate with an OOM message visible in the notebook UI. Permissions: any user can run the code. Risk: possible loss of unsaved work if the kernel OOMs.
Failure Modes
- OOM termination: When a notebook attempts to allocate more RAM than its cgroup allows, the kernel is killed abruptly. The UI shows a generic “Kernel died” message; no detailed trace is provided.
- Network block: Attempts to
pip installa package from a non‑whitelisted index fail with a timeout or connection error, which can be confusing if the user expects internet access. - Output loss: Forgetting to click “Save Version” before stopping the notebook results in the writable layer being discarded, erasing any intermediate files.
- Startup latency spikes: If the platform updates the base image and a user’s notebook pulls a newer version, the first launch may take longer than usual while layers are fetched.
Conditions That Would Change the Design
- Relaxed network policy: If Kaggle decided to allow outbound traffic to arbitrary endpoints (e.g., to support user‑run webhooks), the network whitelist would need to be replaced with a more granular proxy or VPN solution, increasing the attack surface.
- Higher‑performance workloads: Should the platform target GPU‑intensive deep‑learning training with multi‑node scaling, the single‑container model would need to be swapped for a pod‑based orchestrator (e.g., Kubernetes) with shared storage and inter‑pod networking.
- Persistent user environments: Providing long‑lived, user‑specific environments (similar to a personal dev box) would require moving from ephemeral writable layers to a durable volume backed by a network file system, altering both backup and security considerations.
- Different language runtimes: Adding first‑class support for Julia, Rust, or compiled languages would necessitate extending the base image with additional toolchains and possibly adjusting cgroup priorities to account for differing startup characteristics.
Each of these conditions would prompt a re‑evaluation of the trust boundaries, resource enforcement mechanisms, and the balance between isolation and usability that currently defines the smallest suitable design for Kaggle Kernels.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.