Open-source prototype · Linux 5.19+

Two-factor approval for AI agents.

WardenClaw stops the risky commands of an AI agent on your Linux server right in the kernel and runs them only after you sign them on your phone. The key never lives on the server, so even a hijacked agent can't approve itself.

  • Below the agent. The kernel sees every program the agent starts, including the ones launched by scripts and child processes.
  • A signature, not a button. Ed25519 over the exact command, made on your phone. The agent can't produce one.
  • Quiet until it matters. Routine work runs and is journaled; your phone gets what trips a rule. Keep your sandbox: this works on top of it.

Take back control.

Approve on Android, iPhone or in a terminal. Any agent harness.

Where it fits

Sandbox, built-in approvals, WardenClaw: three different jobs

Sandbox

Claude Code and Codex sandboxes, Docker

What it covers

Limits on where any code can reach: files, network, system calls, including code inside an interpreter.

What it leaves open

Whether this particular command should run at all.

Built-in approvals

Claude Code, Codex, OpenClaw

What it covers

A question before each tool call the agent reports, answered with a button, a chat message or an allow-list.

What it leaves open

The answer is not signed and is checked on the same host as the agent. A child process of an approved script never shows up.

WardenClaw

Under any agent harness on Linux

What it covers

Every program start in the agent's tree, checked in the kernel. The risky ones wait for a signature made off the server.

What it leaves open

What a running process does inside itself: interpreters, file writes, network. That stays with the sandbox.

Use them together: the sandbox limits how far anything can reach, WardenClaw asks you about the risky steps inside those limits.

Scope

What it closes, and what it doesn't yet

Closes

  • Every program start in the agent's tree. Each execve and execveat stops in the kernel and is checked against the rules, including starts from scripts and child processes. Starts through memfd_create, fexecve, a direct call of ld.so or a 32-bit call are gated or refused too.
  • Forged and replayed approvals. A decision is an Ed25519 signature over the exact command with a single-use nonce and a ±60 s window, made with a key that never lives on the agent's host. The agent can't approve its own card: it holds no paired device key.
  • A command swapped after approval. For a signed command wardend stops the new program before its first instruction and compares it with the signed envelope; a mismatch is killed.
  • The model turning the guard off, in the hardened install. wardend runs as a root system service and the agent as its own user, so the kernel refuses the agent's signals, ptrace and memory writes against wardend, and its binary, config, key and unit belong to root. redteam/hardened-check.sh checks this as the agent user.

Not closed yet

  • Tripwire knows programs by name and by list. A multi-call binary (busybox cat, busybox rm), a file reader outside the list (hexdump) or a system program copied under another name runs as an ordinary start: journaled, no card. --policy-mode root asks about every new command instead, at the cost of many more cards.
  • Only exec is gated. Interpreters (python -c, node -e), shell redirections, LD_PRELOAD, file writes and network inside a running process are not. Work handed to a daemon or another host (docker, ssh, systemd-run) is out of sight once approved, and work started outside wardend's tree (another login, cron) is not seen at all. Keep a sandbox around the agent.
  • A single-user trial can be turned off. Without the hardened install wardend and the agent share a user, so the model can stop or rewrite wardend without a single exec.
  • No post-check without a card. Starts that need no card are not re-checked after the kernel continues them. The TOCTOU stop-and-compare covers only commands that were signed.
  • Same-inode swaps. Changing a file's content in place between check and exec is not caught; the binary hash is not part of the envelope yet.
  • Only listed variables are shown. The card shows the environment variables from a list of those that change what a program does: the loader, shells, interpreters, git, proxies. The rest of the environment, including anything that looks like a secret, is signed only as a hash, so a variable outside the list can change an approved command without your seeing it.
  • A cut journal tail passes the check. wardend verify-journal catches a record removed from the middle, not the last records removed from the end.

Threat model The vector table and its tests

The problem

The approval lives on the host it guards, and the agent can reach it

Nobody at the screen

An agent on a server keeps working while you sleep. Its permission prompt waits at a screen you are not looking at, so people widen the allow-list or switch on an auto mode, and whatever passes runs with the agent's rights.

A button the agent's side trusts

An approval is usually just an RPC call. Any client with the right scope, or a /approve typed in chat, resolves it. There is no signature, so the gate can't tell your "yes" from one produced inside the loop.

A reviewer inside the blast radius

Server-side auto-reviewers run on the same host, often on the same model, as the agent they review. If the host is compromised, it approves itself.

Hooks only see what they are shown

A plugin hook guards only the calls the agent framework chooses to report. A child process started by an approved script never shows up there.

How it works

One signed decision per risky command, enforced below the agent

wardend checks every program start in the agent's process tree at the syscall level. What trips a rule goes to the phone as a card, and wardend accepts nothing but a valid signature.

  1. Agentstarts a program, itself or through a script
  2. Kernel and wardendstop the start and check the rules; if none trips, it runs and is journaled
  3. Phoneshows the card of a start that tripped a rule
  4. Yousign allow or deny with the phone's key
  5. wardendchecks the signature and answers the kernel: CONTINUE or EPERM
  1. Freeze

    wardend runs the agent under a seccomp user-notification filter. Every execve in the tree stops in the kernel while the supervisor reads argv, cwd, the real binary and the parent chain from the stopped process and checks them against the rules. What trips no rule continues at once and is journaled.

  2. Describe

    A command that trips a rule becomes a canonical envelope and a sha256 digest, byte-identical in Go and TypeScript (shared test vectors). wardend sends it to the phone through a relay over one outbound WebSocket, encrypted end to end. Cards and decisions are signed, so the relay can't forge them.

  3. Sign

    The app recomputes the digest itself, shows what the command does, and signs allow or deny with the device's Ed25519 key. If the digest doesn't match the envelope, the only thing it will sign is deny.

  4. Verify and run

    wardend checks the trusted device, a ±60 s time window, a single-use nonce and the digest, then answers the kernel with CONTINUE or EPERM. What the approved command starts is checked on its own; only the same tool family passes for 10 minutes (ssh under scp). Every exec and decision lands in a hash-chained, signed journal.

Detailed diagrams

Who answers on the phone

Start by pressing buttons. Hand over the routine when the numbers say so.

01 You decide

Manual

Every card waits for you. One line in plain words, a risk color, two big buttons: Allow once or Deny. The exact command, argv and process chain are one tap away.

02 Judge suggests

Observe

A judge proposes a verdict with a reason and a 0 to 100 risk score, and you still press the button. The journal records whether it matched you. Watch it for a while before you trust it.

03 Judge decides, within rules

Autopilot

The judge allows below your risk threshold and denies what it finds dangerous; everything else stays with you. A deterministic block-list (rm -rf on roots, dd, mkfs, curl | sh, gateway config, secrets) goes to you before any model sees it. Text aimed at the reviewer inside a command means deny. Three denials in a row fall back to Observe.

Three switches, set separately

What needs a signature

server · policy_mode

  • tripwire default only a start that trips a rule
  • root every start outside an approved tree and every delegating spawn

Whether the answer is enforced

server · mode

  • observe default nothing waits; the journal records what would need a card
  • deny-list only the deny_always rules block
  • ticket what needs a signature waits for one

Who answers on the phone

app · Mode tab

  • Manual default you
  • Observe the judge suggests, you press
  • Autopilot the judge decides within your rules

The server's observe and the phone's Observe are different things: the first enforces nothing, the second only means the judge suggests.

The judge runs on the phone's side: the app asks a model at a URL you set; the agent host never sees its prompt, its keys or its journal. Stop in the Mode tab switches back to Manual at once, and autopilot turns itself off after an hour.

Security, honestly

What it guarantees and what we measured

Fail-closed by default

  • No signed allow within the TTL (120 s): the exec gets EPERM.
  • The supervisor dies: every exec in the tree gets ENOSYS until the service restarts.
  • The queue is full (64 pending): EAGAIN, never an automatic allow.
  • Forged, replayed, stale or foreign-key tickets are rejected (covered by tests).
  • A process in the tree can't install its own notification filter to answer "yes" around wardend.

TOCTOU: the race the kernel leaves open

The kernel copies execve arguments after the supervisor answers, so another thread can swap argv in between. We ran a hostile binary that flips argv[1] between SAFE-ARG and EVIL-ARG in a loop, 40 runs per mode, with the device approving only SAFE-ARG.

Adversarial argv swap, 40 runs per mode
ModeApprovedRan with swapped argvKilled by post-check
off 5 4 n/a
poll 7 3 7
stop 8 0 6

stop (the default for commands that need a signature) sends SIGSTOP to the caller before CONTINUE. The new image halts before its first instruction, /proc exe and cmdline are compared with the signed envelope, and a mismatch is killed. A swapped program never executes a single instruction. Cost: about 1 to 1.5 ms per approved root.

Can the model turn wardend off?

Only if it runs as the same user. A malicious model that controls the harness shares that user's rights, so in a same-user install it could signal, ptrace or overwrite wardend without any exec. The strong guarantee needs a hardened install: wardend as a root system service, root-owned binary and config, the harness as an unprivileged child under its own user. That is the install we recommend. Every vector it closes is covered by a test.

curl -fsSL https://wardenclaw.dev/install.sh | sudo sh

One command, hardened by default, starts in observe mode. The release signature is checked before anything is written.

Recommended: hardened install Why the model can't turn it off

Numbers

Measured on a Raspberry Pi 5

+0.35–0.55 ms

per exec under the supervisor (1000 × /bin/true: 0.51 s → 1.06 s)

3,162 → 819

cards a day, root mode → tripwire, replaying a 25-hour journal of a busy agent (98,053 execs; peak 34 cards in 2 minutes)

~20 ms

added to a whole claude-cli turn

310 µs

median kernel receive-to-reply inside the supervisor (p95 510 µs)

Compared

Close neighbours, and where WardenClaw differs

WardenClaw compared with related tools
WardenClawagentshgrithClaude Code Remote ControlOpenClaw approvals
Where the gate sits Kernel (seccomp on execve)Kernel (seccomp user notify, Landlock, FUSE, eBPF)ptrace + seccompAgent's permission promptGateway tool approvals
Where you approve Phone app or wardenctl in a terminalLocal TTY, TOTP, WebAuthn, APITelegram, Slack, Discord, WhatsApp buttonsPhone or webMobile app, Control UI, /approve in chat
Decision is a signature the gate verifies Yes: Ed25519, key off the hostNot documented: approval is a terminal prompt, a TOTP code, a WebAuthn key or a REST callNonce + HMAC webhookNoNo
Automatic judge On the phone side, outside the hostPolicy rulesLLM scoring on the hostNoServer-side reviewer on the gateway host
Audit trail Hash chain + Ed25519 signatures, verifiable by a third partyHMAC-chained auditNot assessedNot assessedApproval history (30 days)
Status Prototypev0.20.5, Apache-2.0v0.3.4, MPL-2.0 + paid tiersGenerally availableBuilt into OpenClaw

Based on public docs and repositories as of September 2026. agentsh is the closest in mechanics and covers far more than exec; the detailed comparison follows.

agentsh, side by side

agentsh, by Canyon Road, is the closest tool in mechanics and the more complete one. It governs what a process does after it starts: files, network, signals, databases. WardenClaw gates one thing, the start of a program, and puts its effort into who says yes.

WardenClaw and agentsh, as of 2026-10-01, agentsh v0.20.5
WardenClawagentsh
What is intercepted Program starts only: execve and execveat in the agent's process tree. A file write or a network connection made by a process that is already running is not gated. File, network, process and signal activity, including subprocess trees; also Postgres-family database traffic and MCP tool calls. docs: overviewdocs: database proxydocs: MCP security
Decisions a rule can make Run, deny, or wait for a signed approval. allow, deny, approve, redirect, audit, soft_delete. Redirect steers a command, a path or a connection to an approved alternative instead of failing it. docs: policy modeldocs: steering
Platforms Linux in the release. A macOS gate on Endpoint Security is in the repository, unreleased: it needs Apple's entitlement and runs only in development mode for now. Linux with full enforcement. Windows through WSL2 and macOS through a Lima VM run the Linux build. Native macOS (ESF+NE) scores 90% in their table and their README calls it alpha; native Windows scores 85% and waits for driver signing. docs: platform supportREADME
Maturity and packaging A prototype in its first release, by one maintainer, with no independent security audit. One install script and release archives on GitHub. v0.20.5, Apache-2.0. Packages: .deb, .rpm, .apk, Arch, musl tarballs, a Homebrew cask for macOS. Starter policies, and an SDK (@agentsh/secure-sandbox) with adapters for hosted sandbox providers. release v0.20.5READMEdocs: starter policiesdocs: secure-sandbox
Fleet management None. One wardend per machine, configured on that machine. Watchtower, a separate Canyon Road product: central policies, approval routing to Slack, email and SMS, SIEM export, a kill switch. agentsh itself works standalone. We have not checked Watchtower's terms. docs: scaling with Canyon Road
Where a human approves The project's own phone app (Android, iOS): a push wakes it, and before it signs an allow for a dangerous or root command it asks for biometrics or the device passcode. Or wardenctl in a terminal. Approval modes, quoted from their docs: "local_tty - Terminal prompt (default)", "totp - Authenticator app codes", "webauthn - Hardware security keys (YubiKey)", "api - Remote approval via REST". Routing to Slack, email and SMS is Watchtower. docs: authenticationdocs: scaling with Canyon Road
What an approval is An Ed25519 signature made by a key stored on the phone, over the sha256 digest of the exact command envelope, with a single-use nonce and a ±60 s window. wardend verifies it before the kernel continues the exec. A rule with decision: approve pauses the operation until a person answers; a timeout denies by default. Their docs do not describe what a TOTP code or a WebAuthn assertion is bound to, and we have not verified it. docs: policy modeldocs: authentication
Audit log Hash-chained journal, each record signed with the supervisor's Ed25519 key, so a third party checks it with the public key alone. Known gap: records cut from the end pass wardend verify-journal. "Audit logs can be chained with HMAC signatures for tamper detection": HMAC-SHA256 or SHA512, verified with agentsh audit verify and the HMAC key, which can live in a KMS. Events export through OpenTelemetry. docs: audit log integrity

Where agentsh is ahead. Scope, platforms, packaging and age. If the agent's danger is a file it may overwrite or a host it may call from inside an allowed process, WardenClaw does not see it and agentsh does. agentsh can also redirect an operation instead of refusing it, runs outside Linux, and has a control plane for many machines.

Where WardenClaw differs. The approval is a signature from a key on your phone over the digest of the exact command, checked by the gate, and the journal is signed so that anyone with the public key can verify it. The phone app with push is part of the open-source project. The machine opens no port to the network. The price is a dependency on a relay: when it is unreachable, commands that need a signature are denied.

Which one to pick. You need rules for files and network, policy across a fleet, macOS or Windows, or audit export for compliance: agentsh. You run a self-hosted agent on a headless Linux machine and want a signed yes or no from your phone before a dangerous command starts: WardenClaw. They do not exclude each other. agentsh has a REST approval mode, but no integration between the two exists.

Full table and sources

As of 2026-10-01, agentsh v0.20.5, from their public docs and repository. Something here is wrong or out of date? Open an issue.

Components

Three pieces, one envelope

wardend Go

Supervisor on seccomp user notification. No cgo, no libseccomp, Linux 5.19+; in the recommended install a root system service with the agent as its own user. Tripwire rules with harness packs (claude-cli, OpenClaw) or the older root mode, TOCTOU stop-verify, the relay link and pairing for the phone, a signed journal and wardend replay.

wardend source

WardenClaw app Expo · TypeScript

Pairs with wardend by QR code as a device with its own Ed25519 key in the phone's secure storage. Feed, Mode, Journal and Connection tabs; a risk judge on a model at a URL you set; an append-only journal with a hash chain. Android and iPhone.

WardenClaw app source

wardenctl Go

A terminal approver for Linux and macOS. Pairs with wardend by the same link as the phone, as a device with its own Ed25519 key, shows pending commands and signs allow or deny. It refuses to run next to the agent.

wardenctl source

Status

Prototype, running on a Raspberry Pi 5 and a Pixel 9 Pro

Works today

  • Kernel gate for the whole tree: tripwire rules decide which starts need a signature
  • Signed tickets end to end: phone → wardend → execve, with signed responses
  • TOCTOU stop-verify, fail-closed paths, hash-chained journals
  • Phone app with Manual, Observe and Autopilot; wardenctl as an approver in a terminal

FAQ

Questions people ask first

Why not just use a sandbox?

Keep it. A sandbox limits where any code can reach, including code inside interpreters that tripwire doesn't see. It doesn't decide whether this particular command should run, and its own prompt is answered on the same host. WardenClaw asks about the risky steps inside those limits, with a signature made off the host. The two stack; isolation around the gate (Landlock) is on the roadmap.

What if I lose my phone?

The agent stops; it doesn't run free. Without a signature nothing new executes. On the host, run wardend pair revoke for that device (or remove it from trusted_devices) and pair a new phone. The signing key lives in the phone's secure storage, never on the agent's host.

Do I need root?

The recommended install runs wardend as a root system service and the agent as its own unprivileged user, so the model can't turn the guard off. A single-user trial needs no root, but there the model could stop wardend. The gate itself is no_new_privs plus a seccomp filter with a notification listener: no cgo, no libseccomp, Linux 5.19 or newer.

Does it work on macOS?

Not in the release. The released gate is Linux seccomp user notification. A macOS backend exists in the repository: wardend runs as a LaunchDaemon and gates execve through Endpoint Security (macOS 27, the descendants client, the command waits in the kernel). An Endpoint Security client needs an entitlement from Apple that this project does not hold yet, so today it runs only on a Mac in development mode (SIP off). Details and the honest status: daemon/docs/macos.md.

Won't I drown in prompts?

By default only commands that trip a rule wait for your signature, such as remote execution, package installs, publishing, reading secrets, destructive commands or changes to the agent's settings. Everything else runs and is journaled. How many cards that makes depends on the agent: replaying a busy agent's 25-hour journal gave 819 a day (3,162 in the older root mode). Run your own journal through wardend replay before you enforce, and let Autopilot take the routine.

Is it only for OpenClaw?

No. wardend supervises any Linux process and ships harness packs for claude-cli and OpenClaw. wardend reaches the phone app through a relay over one outbound WebSocket, so the server needs no public address and no open port. Messages are encrypted end to end: the relay can't read or forge them.