Skip to content

cjohnstoniv/wardyn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

346 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Wardyn

License: Apache-2.0 Status: pre-alpha Go 1.26 CI

The open-source governed-sandbox control plane for any workload — identity, controls, and audit are the product; the sandbox is a pluggable commodity. Wardyn governs run-identity and tokens for anything you launch — a script, a build, a plain command, or a coding agent (its flagship use): a wardyn authorizes one specific, scoped action — which is exactly what the broker mints.

Name & trademark. "Wardyn" is a working name — a formal trademark clearance (USPTO full-text + GitHub org / domain / package handles) is still pending, so the name may change before a 1.0. The module path github.com/cjohnstoniv/wardyn is a personal namespace for now; re-homing to a dedicated org later is a one-line change.

Wardyn's Getting-started page — pick a confinement barrier (Fence / Wall / Vault) with your host's real capabilities detected live


What Wardyn Is

Anything you run under your own credentials — a script, a build, a CI job, a coding agent — inherits your full blast radius. A prompt-injected agent, a poisoned dependency, or a compromised MCP server inherits the same repos, cloud access, and reach as whatever launched it. Wardyn is the governance layer between a human operator and anything running on their behalf; a run doesn't have to be an agent at all, but coding agents (Claude Code, Codex CLI, and successors) are the flagship use, so most of what follows is framed around them:

  • Per-run identity. Every run gets a SPIFFE ID (spiffe://<trust-domain>/agent-run/<id>) distinct from the human; the human's sub, the run's act, and the accountable sponsor travel together in every token, commit, and audit event. [shipped] (embedded JWT-SVID issuer; SPIRE-backed [v0.5+ — planned]).

  • Broker-minted scoped credentials. The agent never holds a credential; the broker mints short-lived, repo-scoped, down-scoped credentials on demand, injected proxy-side. Approval-required grants mint inside the Postgres transaction that verifies an APPROVED request for that exact run+scope — no widening. [shipped]

  • Layered egress. A run's sandbox is gatewayless — its only path off-host is the wardyn-proxy sidecar (L0 [shipped]), which enforces an L7 allowlist, method rules, first-use approval, and proxy-side credential injection (L2 [shipped]). The env-var-bypass class is defended structurally: with no route, an agent that ignores HTTP_PROXY reaches nothing. L1 default-deny and an MCP gateway are [v0.5+ — planned]. Full table in ARCHITECTURE.md; what "planned" covers is in ROADMAP.md.

  • Three-stream append-only audit. The control-plane event log (Postgres trigger blocks UPDATE/DELETE), PTY replay via wardyn-rec, and the eBPF/Tetragon ground-truth stream (kernel.* correlated on run_id) — all [shipped]. Ground-truth is detection, not prevention and honestly degradable (/healthz reports ebpf_groundtruth=unavailable without a sensor; blind inside CC3/Kata guests; its Tetragon mapper is validated against documented shapes, not a live deployment yet). SIEM export (JSON webhook/syslog/file) is [shipped] and free; OTLP/OCSF [v0.5+ — planned].

  • Confinement Classes. Friendly UI names — Fence = CC1, Wall = CC2, Vault = CC3. CC1/Fence (hardened shared-kernel runc) [shipped], CC2/Wall (gVisor userspace kernel — default) [shipped], CC3/Vault (Kata microVM) [experimental] — live-proven on a Docker daemon with the Kata runtime registered (needs /dev/kvm; not on Docker Desktop). Fence needs only Docker; Wall adds runsc; Vault adds /dev/kvm + Kata. Policy can mandate a minimum class; the plane refuses a run a substrate cannot satisfy.

  • Bring Your Own Image (BYOI). A run may name an arbitrary base image; the plane wraps it with the runner tools (opt-in via WARDYN_ENVBUILD) and gates launch on an in-sandbox self-test, fail-closed. The wrap is wrap-only — a FROM + COPY that adds layers and never runs image-controlled code on the host: a base carrying ONBUILD triggers is refused, because those would execute on the host daemon at wrap time. A tag or a digest-pinned ref (repo@sha256:…) both work; pinning is honored end-to-end and recommended, but not enforced — Wardyn resolves a mutable tag at wrap time, so what a tag points at stays the operator's call. [shipped]

  • Model access without resident keys. An Anthropic API key or a Claude subscription (from the operator's live login) is injected proxy-side, never resident; a containerized plane connects a Wardyn-managed Claude subscription via container login. AWS Bedrock is operator-configured (bearer proxy-injected; SigV4 keys resident, documented). [shipped]


Architecture at a glance

Wardyn system overview: a trusted control plane (wardynd + Postgres) launches each run — coding agent, script, or build — into an untrusted, gatewayless per-run sandbox whose only path off-host is the wardyn-proxy egress sidecar

A trusted control plane (wardynd + Postgres) launches each run — a coding agent, a script, a build, whatever the workload is — into an untrusted, gatewayless sandbox whose only path out is the wardyn-proxy sidecar; credentials are injected at the proxy, and every decision and PTY session streams back into the append-only audit log.


Why Now

Coding agents today inherit developer credentials at launch. No purpose-built, open-source governance layer existed to scope, gate, and attribute what an agent can do. The incumbent tools have filled parts of the gap in ways that create new problems:

  • Existing governance controls ship as paid tiers of commercial platforms, closed-source services, or vendor-bundled runtimes — you cannot audit what you cannot read, and you cannot run it on your own infrastructure without a commercial agreement.
  • Existing sandboxing tools have overclaimed their isolation properties: in documented red-team exercises, hook-based in-agent enforcement was bypassed via the dynamic linker (ld-linux/mmap); at least one commercially-shipped sandbox escaped via a CVE in the container runtime.

Wardyn's thesis is that the real boundary is structural (no network path, no resident credentials, enforcement outside the agent process) and that honest disclosure of residual risks is a feature, not a liability. See threatmodel/.

The substrate is a pluggable commodity: every major subsystem (sandbox, identity, secrets, egress, policy, audit) sits behind a seam with a blessed, tested default and documented swappable alternates. See docs/PLUGGABILITY.md.


What It Does

Identity, approval, and the credential mint

The delegation chain is human sub → agent-run SPIFFE ID → scoped minted credential; wardynd mints it at sandbox start and every downstream token and commit carries it (embedded identity provider, or SPIRE at v0.5). A CredentialGrant is eligibility, not issuance — with RequiresApproval set the broker mints only inside the Postgres transaction that verifies approvals.state = 'APPROVED' for this run_id+grant_id and claims minted_jti, so minted scope equals what the approver saw. On run stop the kill-switch cascades automatically: teardown → deny-list run token → revoke credentials → durable state.

Egress model

L0 gatewayless sandbox → L1 default-deny nftables/NetworkPolicy (blocks 169.254.169.254) → L2 wardyn-proxy (L7 allowlist, method rules, first-use approval — always_deny/deny_with_review/wait_for_review holds the connection for a live decision — plus proxy-side credential injection) → L3 MCP/tool gateway (v0.5). The same seam carries the corporate lanes (upstream proxy hop, artifact-mirror redirection, brokered SCM creds). Full table in ARCHITECTURE.md.

Audit streams

  1. audit_events (Postgres, append-only — UPDATE/DELETE trigger raises). System of record.
  2. eBPF/Tetragon ground-truth — a tamper-proof counterpart to agent self-report: detection, not prevention (flags the ld-linux/mmap bypass, never blocks), honestly degradable via /healthz, blind inside CC3/Kata guests. Opt-in.
  3. PTY session replay via wardyn-rec (execs asciinema; GPL subprocess, never linked). Each stream is keyed on run_id and exported to customer SIEM free.

Recorded profiles → governed reruns

The primary way to onboard real work: record a named interactive session in a workspace, then rerun it as a governed profile — the New Run dialog offers recorded sessions as fast-track profiles with observed egress preloaded. Verify re-runs the steps in a fresh CONFINED session (a live re-run, not a byte-for-byte replay): default-deny egress limited to the workspace's approved set unioned with the baseline clone/registry hosts. HONEST RESIDUAL: that baseline is a fixed default, not derived from the workspace's own source — a local_dir workspace that clones nothing still gets the GitHub bundle (incl. *.githubusercontent.com), so a confined verify is much tighter than the open recording but is not minimal. See TRY-IT Level 2.5.

AI Run Composer (optional)

Describe a task in plain English and Wardyn proposes a confined run (agent, repo, confinement, egress, grants) and grades it deterministically. It's advisory (backend never sees run credentials) and off by default; configure a backend via WARDYN_COMPOSER_CONFIG (see examples/composer-configs/; fake.json needs no key) and the Describe surface appears in the New Run dialog — else it falls back to the manual wizard. See TRY-IT Level 3.


Honest Security Posture

Wardyn publishes what it does not defend against. The full published residual-risk list is in threatmodel/THREAT-MODEL.md.

Notable residual risks:

  • The model-API channel is an unavoidable data-exit path. The LLM gateway logs every prompt/token/tool call but cannot prevent an agent from encoding data into a prompt to a model it is permitted to call.
  • Domain fronting and DNS-tunnel exfil are not closed below the optional L2 TLS-intercept tier. Per-run TLS interception is shipped for operator-listed MITM-eligible hosts (LLM endpoints, artifact registries — opt-in, off by default); interception of arbitrary domains is the v0.5 target, so most non-LLM HTTPS egress remains an opaque CONNECT tunnel.
  • Tier-1 hardened-runc shares the host kernel. A kernel 0-day on a runc-only host defeats the sandbox boundary. Wardyn defaults to CC2 (gVisor) for this reason.
  • The 1-hour minted-token window before kill-switch revocation is a real exposure window that cannot be fully eliminated, only minimized by TTL.

Requirements

  • Docker with the compose v2 plugin (Docker Desktop or a native Docker Engine). Fence/CC1 runs need nothing more; Wall/CC2 adds gVisor's runsc, Vault/CC3 adds /dev/kvm + a Kata runtime — wardyn setup wall|vault prints the exact steps for your machine.
  • Go 1.26+ and Node 22 + pnpm 9 — only for building from source (host mode builds bin/wardynd + the UI locally).
  • Claude Code CLI (optional, host mode) — make setup stages an existing claude login so sandboxes can use your subscription; without one, runs have no model access until you add an API key (or Bedrock) in the UI.
  • Postgres is included in the compose file — nothing external to install, no hosted service to sign up for.

go install github.com/cjohnstoniv/wardyn/cmd/wardyn@latest installs the CLI. But wardynd is not go install-able (it needs -tags docker + a built ui/dist; a bare install has no embedded UI or sandbox runner) — run it via make setup or the container image.

Quickstart (pre-alpha)

Status: pre-alpha. Interfaces are not stable. Do not run production workloads.

git clone https://github.com/cjohnstoniv/wardyn
cd wardyn
make setup   # brings up the containerized control plane + opens the UI

make setup (== scripts/setup.sh) runs containerized mode — the default: wardynd runs in a compose container (sandbox→control-plane callbacks route in-network, so workspace Verify/Record work even on Docker Desktop + WSL2 NAT), starts Postgres, opens the UI, and prints commands for any missing confinement barrier. Stop with make compose-down.

Give it a model — pick any, all first-class at the CLI (or in the UI):

claude setup-token | wardyn subscription connect   # Claude subscription (never resident)
echo "$KEY"        | wardyn secret set anthropic-api-key   # API key
# or Bedrock: set WARDYN_BEDROCK_REGION/MODEL (+ WARDYN_BEDROCK_AWS_DIR for ~/.aws SSO)
wardyn setup status   # what's configured, with the exact next command per unmet check

Host mode (WARDYN_SETUP_MODE=local) is an advanced escape hatch — wardynd runs as you, using your resident Claude login directly (note: its workspace Verify/Record callbacks don't route under Docker Desktop + WSL2 NAT). Team mode (multi-user SSO/RBAC) does not exist yet and is not scheduled — see ROADMAP.md.

Prove the egress boundary hands-on first? The UI's /demos screen launches interactive sandboxes with no repo and no keys — see TRY-IT Level 0.5.

Prefer one file and one command? Write your sandbox rules as a small YAML (or JSON) policy and hand it to a single wardyn run — interactive or unattended:

wardyn run --agent claude-code --image ubuntu:24.04 --task-mode exec \
  --task 'echo hello from a governed sandbox' \
  --policy-file examples/policies/sandbox.yaml --wait

The commented examples/policies/sandbox.yaml is a sealed floor you can edit at a glance; wardyn policy render -f <file> checks it.

In a pipeline instead of on a desktop? docs/CI.md — one script brings up a fresh control plane on any CI runner (GitHub Actions, Azure DevOps), runs one governed BYOA sandbox (your image, or just a plain command), and exits with the task's exit code. No UI, no human.

The local access model in one picture

The local access model: your machine is the hard ceiling — everything you can do bounds everything a sandbox can; the Wardyn policy ceiling clamps that down; and each run receives only the minimal subset (scoped credential, task egress allowlist, onboarded mounts) its task needs

On your desktop, Wardyn never adds power: a sandbox reaches at most what you (the operating user) already can, the operator policy clamps that to what you allow, and each run gets only the minimal subset (scoped credential, egress allowlist, mounts) it needs.

New to Wardyn? docs/TRY-IT.md is the guided walkthrough (no-key governance demo, hands-on demo sandboxes, then a real Claude Code run); docs/sdk.md covers the Go SDK + raw curl API; deploy/compose/README.md the compose stack, no-login local mode, and TLS; and examples/ holds demo policies and configs.


Deployment Surface

Two paths — only one runs sandboxes today:

Path Location Status
Docker Compose deploy/compose/ [shipped] — the only working data plane today
Helm chart (one blessed chart) deploy/helm/wardyn/ [v0.5 — planned] — render-checked only (helm lint + helm template in CI); there is no Kubernetes runner driver yet, so the chart deploys the control plane but cannot create sandboxes yet

No "bring your own arbitrary Kubernetes manifests." The parity rule: a feature is not done until it passes the conformance suite on both Docker and kind — today only the Docker target runs functionally (see Status below).


Status

v0.4 (pre-alpha) is the current release: containerized setup by default, a first-class credential CLI (wardyn subscription, wardyn setup status), YAML policies, container workspaces with their own model credentials, Bedrock via AWS SSO, and the corporate-network build/egress lanes. v0.1–v0.3.1 shipped per-run identity, the approval FSM and credential broker, the L2 egress proxy and append-only audit, CC1/CC2 confinement, CI mode (BYOA), and the repo-scoped git-broker.

Still unbuilt: SPIRE, OpenBao, L1 default-deny, an MCP/tool gateway, arbitrary-domain TLS interception, a Kubernetes runner driver, OTLP/OCSF sinks, and multi-user team mode.

Full shipped-and-planned detail — including the named gaps with no milestone — is in ROADMAP.md; per-release detail is in CHANGELOG.md.


Components

wardynd (control plane: REST API, embedded UI, policy engine, approval FSM, token broker, audit ingest) · wardyn-runner (docker driver) · wardyn-proxy (L2 egress sidecar) · wardyn-rec (PTY recorder) · wardyn-tetragon-ingest (ground-truth ingest, opt-in) · wardyn-git-helper (stdout-only git credential broker) · wardyn-scan / wardyn-verify (workspace onboarding) · wardyn (CLI). Full per-binary roles in ARCHITECTURE.md.


License and Governance

Apache-2.0. Contributor sign-off via DCO (Signed-off-by). No enterprise/ directory — every control is in the open. No hosted backend either: it runs on your infrastructure or it doesn't run. Nothing here is a free tier of a paid product — there is no paid product. Every control described above (identity, egress, audit, approvals) is in this repo under Apache-2.0, not gated behind a commercial license. CNCF Sandbox is the governance target.

Contributions welcome. See CONTRIBUTING.md.


Wardyn is a working name, pending trademark search.

About

Open-source governance control plane for coding agents — per-run identity, brokered credentials, layered egress, approvals, and an append-only audit. Apache-2.0, self-hosted.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors