Connect the phone
Time: 5 minutes · Needs: wardend installed, a device with the app, internet on the server and on the phone · Result: the app shows “Connected” and the server lists it as a trusted device
wardend listens on no network port. It keeps one outbound WebSocket to the relay (relay_url, by default wss://relay.wardenclaw.dev), and the app connects to the same relay. You need no tunnel, no public hostname and no open port: the server only has to reach the relay over outbound HTTPS.
Trust does not depend on the relay. Messages between wardend and a device are end-to-end encrypted (X25519 + XChaCha20-Poly1305), so the relay sees ciphertext. Every ticket is signed with the device key and bound to the digest of the command, and every card is signed with the supervisor key the phone pinned from the QR code. The relay can delay or drop a message, but it cannot read a card, forge one, or approve anything.
The commands below are for the hardened install. In the single-user trial install drop sudo, and the config is ~/.wardend/config.json.
1. Pair
Pair from your own terminal on the server, never from a chat with the agent. pair start, approve, reject and revoke refuse to run under wardend’s filter, so the agent can’t pair a device for itself.
sudo wardend pair start
It prints a QR code and waits. In the app open the Connect tab and tap Scan QR. The app shows the device fingerprint and waits for approval. On the server pair start shows the device’s name and the same fingerprint and asks Approve this device? [y/N]: compare the fingerprint with the phone screen, then answer y. Anything else rejects the request.
Without a terminal (a script) or with --no-wait, pair start does not ask. Approve the request by its id:
sudo wardend pair list
sudo wardend pair approve <id>
A pairing request expires after 10 minutes. For wardenctl pass the wardenclaw://pair?… link that pair start prints: wardenctl pair '<link>'.
2. Check the connection
- The app shows Connected.
sudo wardend pair listlists the device among the trusted devices. If wardend has no connection to the relay, it adds the lineNot connected to the relay ….sudo wardend status | jq .relayshows the relay state:url,enabled,connected,devices(the number of devices wardend serves through the relay) anderror, if the relay could not be started.
There is no test card. The first cards come as soon as the agent launches something after the pairing: every launch outside an approved subtree is a card, and before the pairing they all expired into EPERM. With the app in observe mode it signs them automatically, so the feed fills up while nothing waits for you (install, step 5). An empty feed with a working agent means the agent hasn’t launched anything yet, not a broken connection. Keep the phone paired and online: a card nobody signs waits for the TTL and fails.
A spare device keeps the agent going when the phone is away: right after the phone, pair wardenctl on a laptop with a link from another pair start.
If the phone is lost
The lost phone holds a device key that can approve commands: revoke it right away. Pairing a new phone needs no second device, only your terminal on the server:
sudo wardend pair list
sudo wardend pair revoke <deviceId prefix>
sudo wardend pair start # scan the QR code with the new phone, compare the fingerprint, answer y
Until a new device is paired, nothing the agent launches will run: every card waits for the TTL and fails, the harness’s own workers included. The daemon has no mode that asks nobody; a spare approver such as wardenctl on a laptop closes the gap. More in Too many cards, or the phone is gone.
If it does not connect
pair listsaysNot connected to the relay, orstatusshows"connected": false. The server can’t reach the relay. Check outbound HTTPS from the server to the host inrelay_url(a firewall, a proxy, DNS). wardend retries by itself, with a pause that grows from 1 to 60 seconds; no restart is needed once the network is back.statusshows"enabled": false.relay_urlisoffin the config: no device can reach this wardend. Remove the key (the default relay) or set your relay’s address, check the config withwardend config-checkand restart wardend. The restart also restarts the agent.- A relay of your own.
relay_urltakes the base address,wss://host[:port], without/v1/ws. The app takes the relay address from the pairing QR code, so pair again after you change it. How to deploy the relay: relay/README.md. - The app does not accept the QR code. The code is one-time and lives 5 minutes (
pair_code_ttl): runwardend pair startagain. - Cards don’t show up on a locked phone. Notifications on a locked phone.