terok-shield
Default-deny egress firewall for rootless Podman containers.
terok-shield enforces default-deny outbound network filtering on Podman containers using nftables. Containers can only reach explicitly allowed destinations — everything else is rejected with an ICMP error and a per-packet audit entry.
Where it sits in the stack
terok-shield is the firewall layer of the terok ecosystem. The hardened-Podman runtime (terok-sandbox) installs the OCI hooks at setup time; the operator-in-the-loop verdict service (terok-clearance) mutates the live ruleset on Allow / Deny decisions. The shield itself is independent of all of these — it works on any rootless Podman container, with or without the rest of terok.
Features
- Default-deny egress with curated allowlists (domains and IPs)
- Dynamic DNS allowlisting — per-container dnsmasq with
--nftsetauto-populates allow sets on every DNS resolution, handling IP rotation at runtime; degrades to resolution at launch when dnsmasq lacks nftset support or is unavailable, and says so - Live allow/deny at runtime for individual containers
- Per-container isolation — each container gets its own state bundle and audit log
- Connection audit logging (JSON-lines lifecycle logs + kernel-level per-packet nftables logs)
- Fail-closed — hook failure prevents the container from starting
Requirements
- Linux with nftables (
nftbinary) — tested on Fedora 43, Debian 12 and 13, and Ubuntu 24.04, also works on other modern Linux distros - Podman (rootless, recommended ≥ 5.6.0, untested < 4.3.1)
- Python 3.12+
dnsmasq(recommended) for dynamic DNS-based egress control;dig(dnsutils/bind-utils) as fallback
Installation
pip install terok-shield
Quick start
1. Choose your allowlists
terok-shield ships with several bundled profiles (see Allowlist Profiles):
| Profile | Domains |
|---|---|
base |
DNS roots, NTP, OCSP, OS package repos |
dev-standard |
GitHub, Docker Hub, PyPI, npm, crates.io, Go |
dev-python |
Conda, Read the Docs, Python docs |
dev-node |
Yarn, jsDelivr, unpkg |
nvidia-hpc |
CUDA, NGC, NVIDIA drivers |
The default profile is dev-standard. To add a custom allowlist,
create a .txt file in ~/.config/terok/shield/profiles with one domain or IP per line:
e.g. ~/.config/terok/shield/profiles/my-project.txt
api.example.com
cdn.example.com
203.0.113.10
2. Start a container with the shield
terok-shield setup
terok-shield run my-container -- alpine:latest sh
Setup installs global OCI hooks; run resolves DNS and launches the container
with a default-deny firewall — only destinations in the
dev-standard profile are reachable. To use custom profiles:
terok-shield run my-container --profiles dev-standard,my-project -- alpine:latest sh
3. Allow a domain at runtime
terok-shield allow my-container example.com
# Allowed example.com -> <resolved-ip> for my-container
terok-shield deny my-container example.com # revoke later
License
Apache-2.0 — see LICENSES/Apache-2.0.txt.
Metadata
Release files for terok-shield 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| terok_shield-0.9.0.tar.gz | 464.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| terok_shield-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 635.6 kB
Release files / terok_shield-0.9.0.tar.gz
| Download URL | terok_shield-0.9.0.tar.gz |
|---|---|
| Size | 464.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d60b045c9483266ecc3cecff184daf3f5e47db33b075ce3922c7077a7230a4cd
|
|
BLAKE2b-256 checksum How to use checksums |
dcfbe21e40e934a059ea7d29237147cefded6365ddb3e2cc27abcb15b90d3635
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 29, 2026.
Transparency logRelease files / terok_shield-0.9.0-py3-none-any.whl
| Download URL | terok_shield-0.9.0-py3-none-any.whl |
|---|---|
| Size | 171.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8acee6519066c1c827069b265ec08b24c28014b462cc8eb1a3624930d8230a77
|
|
BLAKE2b-256 checksum How to use checksums |
ab67388e9686f11239e08cfd7adf8b1b03c288e752f57819abc6fb65d124aedc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 29, 2026.
Transparency log