Try it in 5 minutes
Time: 5 minutes · Needs: Linux 5.19 or newer (arm64 or x86_64), ssh installed, no root · Result: a command waits in the kernel and runs only after a signed approval
The quickest honest look at the gate. There is no agent and no phone here: wardend supervises a small shell command, and a second terminal plays the phone with a test key. Nothing on this page protects a real agent; for that, use the hardened install.
1. Install for your own user
curl -fsSL https://wardenclaw.dev/install.sh | sh -s -- --single-user
The script checks the release signature, asks for a confirmation and puts wardend into ~/.local/bin, the reference files and uninstall.sh into ~/.local/share/wardend, and an example config into ~/.wardend/config.json. It warns when ~/.local/bin is not in your PATH.
Check: wardend --help prints the usage and exits with code 0.
2. Watch a command in observe
$ wardend run --mode observe --gateway-db off -- sh -c 'ls -d /tmp; git --version'
wardend: mode=observe policy=tripwire pid=767159 child=767168 socket=/home/me/.wardend/wardend.sock journal=/home/me/.wardend/journal.jsonl
/tmp
git version 2.47.3
wardend: mode=observe execs=3 denied=0 latency p50=433us p95=518us max=518us exit=0
Everything runs. wardend counted the execs (execs=3) and wrote to the journal what each would need in ticket mode.
3. Make a command wait for a signature
In the first terminal, create a test device and run a command in ticket mode that trusts it:
(umask 077; wardend keygen > device.txt) # test device; the seed in it is a secret
DEV=$(sed -n 's/^deviceId=//p' device.txt); PUB=$(sed -n 's/^pubkey=//p' device.txt)
wardend run --mode ticket --gateway-db off --trust "$DEV:$PUB" --ttl 30s --quiet \
-- sh -c 'ls -d /etc; ssh -V; echo "ssh rc=$?"'
ls prints /etc at once. ssh is remote execution, one of the rules of the default tripwire policy, so it now waits in the kernel, for 30 seconds at most (--ttl).
Within those 30 seconds, in a second terminal in the same directory, sign it with the test key:
$ wardend approve --key "$(sed -n 's/^seed=//p' device.txt)" --count 1 --timeout 10s
allow wd-805763d1887fcfb8a26269e7d38f1db9 argv=[ssh -V] -> map[decision:allow id:wd-805763d1887fcfb8a26269e7d38f1db9 ok:true]
The first terminal prints the OpenSSH version and ssh rc=0. wardend approve is a “device in a terminal”: it reads the waiting request from the socket, recomputes its digest from the envelope as the app does and signs the decision.
4. Deny it
Run the same wardend run command again, and in the second terminal sign a deny:
wardend approve --key "$(sed -n 's/^seed=//p' device.txt)" --deny --count 1 --timeout 10s
The first terminal prints:
/etc
sh: 1: ssh: Operation not permitted
ssh rc=126
The same happens when no answer comes within the TTL: without a signature the command does not run.
5. Check the journal
Every exec and every decision lands in an append-only journal. Each record is hashed into a chain and signed by the supervisor’s key:
wardend verify-journal ~/.wardend/journal.jsonl
On a valid chain it exits with code 0 and warns that the key came from the journal itself. To check authorship too, pass the supervisor’s public key with --pubkey: wardend verify-journal.
6. Clean up
rm device.txt # the test seed
~/.local/share/wardend/uninstall.sh --single-user
Details: Uninstall the trial install.
What you saw, and what you did not
- The kernel held
sshuntil a signed decision came, andlsran at once. In the defaulttripwirepolicy mode only the execs that trip a rule wait: remote execution, leaving the gate, package installs, publishing, secrets, destructive commands. See Policy modes. - The test key lay next to wardend, in
device.txt. In real use the key lives on your phone, or laptop and never on the server;keygenandapproveexist for demos and tests. - In this trial install a model running as the same user could turn wardend off. The hardened install closes that: Why the model can’t turn it off.
Next
- Install wardend on the server for real.
- Get the app and connect the phone.