Scrydon
Platform

Notebook egress governance

Control which external hosts isolated Python notebooks can reach — PyPI, custom domains, or a fully air-gapped organisation policy.

Marimo notebooks run Python code inside an isolated runtime whose only reachable destinations are the ones your organisation's egress policy allows. An organisation that has not configured one runs the platform default — Allow Scrydon default traffic on, which permits the curated package registries and nothing else — so pip install works out of the box while every other destination stays blocked. The Egress panel lets an IT admin widen, tighten, or fully close that policy to match the organisation's risk posture.

Egress is organisation-scoped and snapshotted when compute is prepared. A policy change fences and replaces affected notebook runtimes before more code executes; another organisation's runtime is unaffected.


How egress is enforced

The Runtime Plane builds the effective egress snapshot from operator defaults and the active organisation policy. Every interactive runtime and single-use notebook job receives a trusted in-runtime egress enforcer. The untrusted Python container has no network capability that can reconfigure or bypass that enforcer.

Production support also requires a Kubernetes CNI that enforces NetworkPolicyCalico, Cilium, or Azure network policy on AKS. NetworkPolicy limits control-plane and workload east-west paths; the in-runtime enforcer owns destination policy. Operators must qualify both controls before claiming the boundary.

Confirm NetworkPolicy enforcement and the isolated runtime tier before relying on egress governance as a security control. On AKS, configure an appropriate network-policy engine when provisioning the cluster.

az aks update --resource-group <rg> --name <cluster> --network-policy azure

or provision the cluster with Calico or Cilium.


Opening the panel

  1. Sign in as an organisation owner or organisation admin.
  2. Go to Settings → Governance → Egress.

The panel shows two controls:

  • Allow Scrydon default traffic — a toggle that enables the platform's curated allowlist.
  • Custom allowed domains — a list you maintain for organisation-specific destinations.

The Scrydon default allowlist

When Allow Scrydon default traffic is turned on, the sandbox gains access to the package registry hosts that pip needs to install packages from PyPI:

HostPurpose
pypi.orgPackage index — pip fetches metadata and version lists here
files.pythonhosted.orgWheel and source distribution downloads
registry.npmjs.orgnpm registry — npm install in the Agent sandbox

These three hosts are the complete curated set. The rule for membership is narrow: a host is included when a package manager the sandbox ships (pip, npm) needs it, and nothing else. Source hosts such as github.com, model hubs, and registries for other toolchains are not included — add them as custom domain entries if you need them.

Scrydon maintains this list. When new trusted public registries are added, they will appear in a platform release note. Enabling this toggle always uses the current version of the list.


Adding custom allowed domains

Click Add domain to append a domain to your custom allowlist. Enter either:

  • An exact hostnamecdn.example.com allows only that subdomain.
  • A parent domainexample.com allows example.com and any subdomain under it (e.g. api.example.com, cdn.example.com).

Domain matching is case-insensitive. IP addresses are not accepted as allowlist entries.

After editing the list, click Save. A notebook already connected under a different snapshot is replaced before its next execution; reconnect if the UI reports that the previous runtime became stale.

Two planes: the kernel and the browser

Each entry also carries a Browser resources switch, and it matters more often than it looks.

An allowlist entry governs the kernel — the Python process in the sandbox. But some notebook output is fetched by the browser instead: a Plotly map's basemap tiles, a remote image, a web font. Those requests are governed by the notebook document's Content-Security-Policy, so an entry that only the kernel can use will not make a map render.

  • Off (the default, and what every pre-existing entry means) — the kernel may reach the host. The browser may not.
  • On — the kernel may reach it and notebook documents may load non-executable resources from it: images, tiles, fonts, and fetch/XHR. It never permits scripts, frames, or plugins from that host, whatever the switch says.

Turn it on only for hosts whose content you are willing to have every notebook viewer's browser contact directly — the host sees each viewer's IP address, and for map tiles also the area and zoom level being viewed. A data API your notebooks call server-side should stay off.

Turning the switch on for tile.openstreetmap.org is what makes go.Scattermap(..., style="open-street-map") render. The switch is unavailable in denylist mode, where entries are the hosts you are blocking.

Users do not have to guess. When a notebook is refused a browser resource, a notice appears above it naming the exact host, so the request that reaches you is "please allow tile.openstreetmap.org for browser resources" rather than "the map is broken". Blocked scripts are deliberately not surfaced that way — the policy never grants script execution to an external host, so there is nothing for you to enable.

Example: allow a private package index

If your organisation hosts a private PyPI mirror at pypi.internal.example.com:

  1. Add internal.example.com (parent domain) — this also covers any other internal hosts under that domain.
  2. Or add the exact hostname pypi.internal.example.com if you prefer a tighter scope.
  3. Click Save.

Notebooks will now be able to pip install from your private index in addition to (or instead of) the public PyPI hosts.


Turning egress off entirely (deny-all)

With Allow Scrydon default traffic off and no custom domains added, the sandbox has no external network access.

This is not where a new organisation starts — the curated allowlist is on until an admin turns it off. Deny-all is the right posture when every required package is pre-baked into the notebook image or uploaded manually.

In this mode:

  • Dependency reconciliation fails when a declared package must be fetched from PyPI.
  • requests.get("https://api.example.com") raises a connection error.
  • Any attempt to reach an external host is blocked and recorded.

Pre-installed packages

The pinned notebook image ships with a base set of packages — no egress is required to use them:

  • Data / numerical: pandas, numpy, scipy, duckdb
  • Visualisation: matplotlib, altair
  • Notebook runtime: marimo, pyarrow, polars
  • Scrydon helpers: scrydon (the built-in table / KB / LLM client)

If a package you need is not in this list, declare it in the notebook source. Scrydon reconciles the dependency set with uv before the kernel becomes ready. For example, a notebook that imports plotly needs pypi.org and files.pythonhosted.org reachable — that is what Allow Scrydon default traffic grants, and it is on unless an admin turned it off. With it off, preparation fails before the cell executes.

Package upload (coming soon): A future release will let you upload Python wheel files directly to the platform, making them available to notebooks without any egress. This is useful for completely air-gapped deployments or for packages not available on public registries.


Permissions

RoleCan viewCan change
Organisation ownerYesYes
Organisation adminYesYes
MemberNo (redirected to account settings)No

Troubleshooting

See the dedicated troubleshooting section in the Marimo notebooks page for step-by-step remedies when a notebook can't install a package or reach a host.


On this page

On this page