Skip to main content

hermetic

This is lightweight sandboxing for semi-trusted code or for disabling APIs in unit tests. What is semi-trusted code? Things like pluggy plugins, LLM generated code. Unit test code is trusted, but as design decision, you may want to avoid accidentally creating integration tests.

Run a python tool, or your application with certain APIs disabled, such as network or subprocess.

The previously safe library you depend on was hijacked and will be sending your password files to a remote server. Or you installed this and the malicious hackers didn't include evasive code to defeat this fig leaf of a security feature and the day is saved.

If Alice and Bob know about your application and specifically are targeting this, this tool won't help. See docs for a discussion of how to defeat hermetic-seal.

Usage

Programmatic API

You can use hermetic directly in your Python code via the hermetic_blocker context manager or the @with_hermetic decorator.

Decorator

The @with_hermetic decorator is the easiest way to apply guards to an entire function.

from hermetic import with_hermetic
import requests


@with_hermetic(block_network=True, allow_domains=["api.internal.com"])
def process_data():
    # This will fail because all network access is blocked by default.
    # requests.get("https://example.com") # --> raises PolicyViolation

    # This is allowed because the domain is on the allow-list.
    return requests.get("https://api.internal.com/data")


process_data()

Context Manager

For more granular control, use the hermetic_blocker context manager.

from hermetic import hermetic_blocker
import os


def check_system():
    # Subprocesses are allowed here
    os.system("echo 'Checking system...'")

    with hermetic_blocker(block_subprocess=True):
        # Inside this block, os.system() would raise a PolicyViolation
        print("Running in a sandboxed context.")
        os.system("echo 'This will fail.'")  # --> raises PolicyViolation

    # Subprocesses are allowed again
    os.system("echo 'Exited sandbox.'")


check_system()

Where could this work?

There are APIs you don't need but an application or 3rd party library you depend on needs. So you block them.

The 3rd party library must be unaware of hermetic or monkeypatching. Import order is important, hermetic must run early enough to intercept all imports to the banned API. Then use of the banned API is blocked and the whole app stops.

This already works in unit testing where there isn't an adversarial relationship between the developers testing the code and writing the code under test, where you block network traffic to guarantee a unit test is pure of network side effects.

Is this defeatable?

Yes, by many routes. Native code, import order tricks, undoing a monkey patch, bringing along a vendorized copy of APIs, and so on.

This is "envelope instead of postcard" level security. This is "lock your door with standard key that can be picked with a $5 purchase on Ebay" level security.

Real sandboxing is running your code in a docker container.

Prior Art

This technique of monkey-patching for isolation is well-established, particularly in the testing ecosystem.

For stronger sandboxing, consider:

  • pysandbox: Uses Linux seccomp for kernel-level syscall filtering.
  • RestrictedPython: Rewrites Python AST to enforce constraints.
  • Docker: OS-level virtualization.

Command-Line Interface

Use the hermetic command to run any Python console script, separating its arguments with --.

Syntax: hermetic [flags] -- <command> [command_args]

Common Flags:

  • --no-network: Disable all network activity.
  • --allow-localhost: Allows network connections to localhost (used with --no-network).
  • --allow-domain <domain>: Allows connections to a specific domain (repeatable).
  • --no-subprocess: Disable creating new processes.
  • --fs-readonly[=/path/to/root]: Make the filesystem read-only. Optionally, restrict all reads to be within the specified root directory.
  • --no-environment: Disable environment variable reads and mutations.
  • --no-code-exec: Disable eval, exec, compile, and runpy execution helpers.
  • --deny-import <module>: Deny importing a module or package prefix (repeatable).
  • --no-interpreter-mutation: Disable sys.path, cwd, and site mutation surfaces.
  • --block-native: Block imports of native C extensions.
  • --profile <name>: Apply a pre-configured profile (e.g., block-all).
  • --trace: Print a message to stderr when an action is blocked.

CLI Examples:

Block network access for the httpie tool:

$ hermetic --no-network -- http [https://example.com](https://example.com)

hermetic: blocked action: network disabled: DNS(example.com)

Run a script in a read-only filesystem where it can only read from ./sandbox:

$ hermetic --fs-readonly=./sandbox -- python my_script.py

# my_script.py will raise PolicyViolation if it tries to read outside ./sandbox
# or write anywhere.

Apply the block-all profile to completely lock down a script:

$ hermetic --profile block-all -- my_analyzer.py --input data.csv

Project Links

Metadata

Release files for hermetic-seal 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hermetic-seal 1.0.0
File Size Uploaded
hermetic_seal-1.0.0.tar.gz 34.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hermetic-seal 1.0.0
File Interpreter ABI Platform
hermetic_seal-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 77.9 kB

Release files / hermetic_seal-1.0.0.tar.gz

Download URL hermetic_seal-1.0.0.tar.gz
Size 34.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fc2e0c6578db78af4bde13bddd166e8d3f494a798eaf5b6b568e0e7b7fa002ae
BLAKE2b-256 checksum
How to use checksums
92fd7ab64877de9fa5faf5a255bb85ffc62feca5556cb0192fd35dcee2c4e964
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 30, 2026.

Transparency log

Release files / hermetic_seal-1.0.0-py3-none-any.whl

Download URL hermetic_seal-1.0.0-py3-none-any.whl
Size 43.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad5587e642d6c9222774bef5ab5ed6823787aef6f48b71daa074111475c0cfd1
BLAKE2b-256 checksum
How to use checksums
cc1f90b5395de71af800bd11f2a1a7c46a7440b94ad6ca5b56225885fc345dd1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page