The open-source governed-sandbox control plane for any workload — identity, controls, and audit are the product; the sandbox is a pluggable commodity. Anything you run under your own credentials inherits your full blast radius; Wardyn is the layer in between — per-run identity, credentials minted and revoked per run, one audited path off-host, no resident key. Coding agents are the flagship use.
Status: pre-alpha. Interfaces are not stable. Do not run production workloads. "Wardyn" is a working name — trademark clearance (USPTO full-text + org / domain / package handles) is still pending, so the name and the personal
github.com/cjohnstoniv/wardynmodule path may change before a 1.0.
Pick by who runs this box. Everything here pulls cosign-signed, SBOM-attested images — docs/VERIFY.md checks that — no clone needed.
Your own machine — no SSO; the installer mints an admin token and prints where to read it (grep WARDYN_ADMIN_TOKEN ~/.wardyn/.env), rather than into your scrollback:
curl -fsSL https://github.com/cjohnstoniv/wardyn/releases/download/v0.7.0/install.sh | shCosign-signed, not tip-of-main — only the script is pinned; it installs the newest release (WARDYN_VERSION overrides). Installs into ~/.wardyn, opens Getting Started on http://127.0.0.1:8080 as an admin (WARDYN_HOME, WARDYN_PORT override).
A managed laptop, one daemon per developer — desktop profile a′: docs/DESKTOP.md.
Each human gets an SSO identity and an admin or member role (docs/OPERATIONS.md).
- A shared host — compose
--profile sso+WARDYN_OIDC_ROLE_MAP: OPERATIONS.md §"Second user, same host". - Kubernetes — a published OCI chart (the command after this list);
.claude/skills/wardyn-k8s-setup/carries an agent-readable recipe for the same path. - Managed laptops under org governance — desktop profile m′:
docs/DESKTOP.md.
# NOT releases/latest — it excludes pre-releases, and every Wardyn release is
# one, so that endpoint 404s and leaves this empty.
WARDYN_VERSION=$(curl -fsSL "https://api.github.com/repos/cjohnstoniv/wardyn/releases?per_page=1" \
| sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p' | head -1)
helm install wardyn oci://ghcr.io/cjohnstoniv/charts/wardyn \
--version "${WARDYN_VERSION:?could not resolve a version — refusing an unpinned install}" \
--namespace wardyn --create-namespace \
--set auth.adminToken.secretRef.name=wardyn-authNeeds an admin token or OIDC, a Postgres DSN and an age identity — role map, substrate
and values table: deploy/helm/wardyn/README.md.
Install nothing — sign in with SSO and read docs/MEMBERS.md: what a member can do, your first run, and what to ask your admin for.
Building from source is a contributor path — see CONTRIBUTING.md. Clone, then make setup
(a failed image pull falls back to building from this checkout; WARDYN_BUILD_LOCAL=1 forces it).
That is the whole setup. The barrier is the only requirement — no model, no
API key, no agent. Put the sandbox rules in a small YAML (or JSON) policy and
hand it to one wardyn run — interactive or unattended:
cat > sandbox.yaml <<'YAML'
allowed_domains: [] # the sandbox can reach nothing
first_use_approval: always_deny # an off-allowlist host is a hard 403, no human
min_confinement_class: CC1 # refuse to launch below hardened runc
auto_stop_after_sec: 900 # reaper backstop
YAML
wardyn run --agent claude-code --task-mode exec \
--task 'echo hello from a governed sandbox' \
--policy-file sandbox.yaml --waitThat runs a plain shell command in a governed sandbox: --task-mode exec means
no agent and no model are involved at all. (--agent still names which sandbox
image to launch — it is an image label, not a statement that an AI runs your
task.) The policy is written out here because the one-line install ships no
repo — from a clone, the same four keys with their comments are
examples/policies/sandbox.yaml.
wardyn policy render -f <file> checks either. --image brings your own base
(docs/ENVBUILD.md). To stop everything:
cd ~/.wardyn && docker compose down (from a clone: make compose-down).
Want an agent to write the code? Then connect a model — optional, and equally first-class at the CLI or in the UI:
claude setup-token | wardyn subscription connect # subscription (never resident)
echo "$KEY" | wardyn secret set anthropic-api-key # API key
# Bedrock: WARDYN_BEDROCK_REGION/MODEL (+ WARDYN_BEDROCK_AWS_DIR for ~/.aws SSO)
wardyn setup status # what's configured + the next command per unmet checkSkipping this is a supported end state, not an unfinished setup: setup status
reports model access as optional and never as a gap to clear. Most of the
built-in demos need no model either — see
TRY-IT.md's "governance demo (no keys)".
- Docker +
composev2 (Postgres rides in the compose file). Fence/CC1 needs nothing more; Wall/CC2 adds gVisor'srunsc, Vault/CC3/dev/kvm+ Kata —wardyn setup wall|vaultprints the steps for your host. - Go 1.26+, Node 22 + pnpm 9 — only to build from source.
go install …/cmd/wardyn@latestgives the CLI only;wardyndneeds-tags docker+ a builtui/dist— usemake setupor the image.
| Capability | What it does | Detail |
|---|---|---|
| Governed runs | Per-run identity in a gatewayless sandbox, driven from a terminal-first cockpit | ARCHITECTURE.md |
| Egress + approvals | Only path out is the proxy; an unlisted host can hold mid-flight — once, run, until, always | POLICIES.md |
| Record Mode | Run once open, get the minimal policy, replay confined | TRY-IT.md |
| Workspaces & secrets | Mounts only what the workspace declares; secrets write-only, never readable back | OPERATIONS.md |
| Policies & confinement | One policy picks the barrier: Fence (runc), Wall (gVisor), Vault (Kata, experimental); a host that can't enforce it refuses. Right-size it — a read-only scan or an indexer does not need what an autonomous agent needs | POLICIES.md |
| Model access | Key, subscription or Bedrock injected proxy-side; the sandbox holds an inert sentinel | TRY-IT.md |
| CI / headless | No UI, no human: the governed run's exit code becomes the pipeline's | CI.md |
| Audit + attach | Three audit streams. The audit log itself is append-only — a Postgres trigger refuses UPDATE, DELETE and TRUNCATE on it. PTY replay is a separate store (upserted per cast, retention-swept), each upload audited. Attach live from browser or SSH |
SSH.md |
| UI sandbox gateway | Relay a declared loopback port (editor, dev server) to a browser over its own origin — a per-run origin is the documented production default | UI-SANDBOXES.md |
Everything else — env and policy reference, deployment, sample workspaces — is indexed in docs/.
Six narrated walkthroughs ship with this release, about 41 minutes end to end; the rest of the series is being re-recorded on 0.7 and lands in the same release as each episode passes (those rows read coming soon). Every one drives the real console against real sandboxes — the policies are live, the refusals are real, and the audit rows on screen were written by the run you are watching. Start with 03a if you only watch one; it is the boundary itself.
The series uses a coding agent as its worked example, because that is the case most people arrive for. The mechanics on screen — the egress boundary, the credential brokering, the audit trail — are the same for any sandboxed workload.
| Episode | What it shows | Length |
|---|---|---|
| 00 — Meet Wardyn | The front door. One keyless run answers what a run may reach, what it may touch, and what it is handed | coming soon |
| 01 — Why govern agents | The blast radius anything inherits when it runs as you | 6:50 |
| 02 — Set up the host | make setup, from a bare host to a running control plane |
7:26 |
| 03a — What it stops | The core. Four things that happen to a host a run may not reach, then the secret the sandbox is never handed | 11:45 |
| 03b — The network, three more ways | A real agent boxed in, a policy recorded from a run, an approval that lasts one connection | 5:05 |
| 03c — Authorized, then issued | A bearer token attached at the boundary; a PAT that only ever exists in a pipe | coming soon |
| 03d — The kinds that can't use a header | SSH keys, brokered GitHub tokens, cloud STS — credentials no header injection can carry | 5:58 |
| 04 — Add a workspace | Onboarding a source, so a run can mount only what was declared | coming soon |
| 05 — Your first policy | Writing the ceiling every run is clamped to | 3:58 |
| 06 — Your first run | One governed run, launched and read back from its record | coming soon |
| 07 — Interactive runs | Attaching a live terminal to a running sandbox | coming soon |
| 08 — An autonomous agent | A real coding agent doing real work inside the boundary | coming soon |
| 09 — Record a run | Run open, derive the minimal policy, replay it confined | coming soon |
| 10 — Approvals and egress | Deciding a held request — once, this run, until, always | coming soon |
They ship as release assets,
not in the repo, so a clone stays small. Links pin v0.7.0; later releases
re-publish under the same filenames. An episode without a link has not been
re-recorded on 0.7 yet; it is uploaded to this same release the moment its take passes.
flowchart LR
entry(["Human operator<br/>UI or wardyn CLI"])
subgraph control["Control plane (trusted)"]
wardynd["wardynd<br/>REST API + embedded UI<br/>policy · approvals · broker · audit"]
pg[("Postgres<br/>append-only audit")]
wardynd --> pg
end
subgraph sandbox["Per-run sandbox (UNTRUSTED) — gatewayless network"]
%% rec declared first: else dagre routes the launch edge through it
rec["wardyn-rec<br/>PTY recorder"]
agent["Coding agent<br/>claude-code / codex-cli"]
rec -->|"cast, brokered to wardynd"| proxy["wardyn-proxy<br/>L2 egress sidecar"]
agent -->|"only path out"| proxy
end
entry --> wardynd
wardynd -->|"launch (docker driver)"| agent
proxy -->|"allowlisted L7, creds injected"| net(("Internet / APIs"))
A trusted control plane launches each run into an untrusted, gatewayless sandbox
whose only path out is the wardyn-proxy sidecar, credentials injected there.
Decision logs and masked casts flow back into the append-only audit log
(THREAT-MODEL.md §8). Wardyn never adds power:
a run reaches at most what you can, clamped by policy.
What Wardyn does not defend against is published in full (THREAT-MODEL.md). Notable residuals:
- The model-API channel is an unavoidable data-exit path. Prompts and tool calls are logged; nothing stops an agent encoding data into a permitted prompt.
- Domain fronting and DNS-tunnel exfil need TLS interception, which ships only for operator-listed hosts (off by default) — most non-LLM egress stays opaque.
- CC1/Fence shares the host kernel, and the 1-hour minted-token window before revocation is minimized by TTL, never eliminated.
- The UI sandbox gateway defaults to a shared browser origin across runs, separated only by a path-scoped cookie, unless the operator sets a per-run origin template — the documented production default (UI-SANDBOXES.md).
Wardyn is pre-alpha. The current release is the one the install line above
pins — the same version internal/version's Version and the chart's
appVersion carry — and CHANGELOG.md is what each release
added. Two deployment lanes, both running real sandboxes, not one inverted into
the other:
deploy/compose— the local 10-minute trial. The only lane that runs on a laptop without a real cluster, and the only one with recorded demos (the Getting Started demo steps).- Kubernetes:
helm install wardyn oci://ghcr.io/cjohnstoniv/charts/wardyn --version <release>— the chart is published as a signed OCI artifact, so no clone and nohelm repo add. Seedeploy/helm/wardyn— the deployment story:make kind-quickstartfor a one-command real-cluster install, or a production Helm install onto your own Kubernetes. Not yet at Compose parity (see the chart README's "Known gaps").
Still unbuilt: SPIRE, OpenBao, an MCP gateway, arbitrary-domain TLS interception, OTLP/OCSF sinks, SAML/SCIM-provisioned team SSO, Compose's own L1 default-deny — see ROADMAP.md and CHANGELOG.md.
Apache-2.0, and free for anyone to use for any purpose, commercial use included — at any scale, with no fee, no seat limit, no registration and no telemetry. There is no paid edition and no hosted backend: every control above is in this repo and runs on your infrastructure, or it doesn't run. There is also no CLA, which means no single party — including the maintainer — can relicense this project's accumulated work later.
LICENSING.md is the one page to hand your legal team: the grant,
what the artifacts contain, redistribution obligations, patents, warranty, and the
disclosed risks. TRADEMARKS.md covers what you may call things,
which Apache-2.0 §6 deliberately does not.
Every published image is cosign-signed with an attested SBOM and build
provenance — docs/VERIFY.md shows how to check that yourself.
Contributor sign-off via DCO (Signed-off-by). CNCF Sandbox is the governance
target, not a status. Contributions welcome — see CONTRIBUTING.md.
