One SSH command
curl … | sh asks you to trust whatever the server sends at that moment. This install verifies first, on your own machine, and only then runs on the server.
1. Download and verify on your machine
Section titled “1. Download and verify on your machine”V=1.0.0curl -fsSLO https://github.com/zunderlabs/zunder-guard/releases/download/v$V/install.shcurl -fsSLO https://github.com/zunderlabs/zunder-guard/releases/download/v$V/install.sh.sigstore.json
cosign verify-blob install.sh \ --bundle install.sh.sigstore.json \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --certificate-identity "https://github.com/zunderlabs/zunder-guard/.github/workflows/release.yml@refs/tags/v$V"Verified OK means the file was signed by Guard’s release workflow on GitHub, for that tag. Then read install.sh. It is short on purpose.
2. Run it on the server
Section titled “2. Run it on the server”ssh you@your-server 'sudo bash -s -- --version 1.0.0 --network paper --rules zr1_eyJ2IjoxLCJtYXhMZXZlcmFnZSI6NSwibWF4TG9zc0F0U3RvcFBjdCI6Miwic3RvcFBvbGljeSI6ImF0dGFjaCIsImRlZmF1bHRTdG9wRGlzdGFuY2VQY3QiOjIsIm1pbkxpcURpc3RhbmNlUGN0IjoxMCwibWF4UG9zaXRpb25QY3QiOjIwMCwibWF4T3BlblJpc2tQY3QiOjYsImRhaWx5TG9zc1N0b3BQY3QiOjYsImRyYXdkb3duSGFsdFBjdCI6MjUsIm1hcmtldHMiOlsiKiJdfQ' < install.shfilled in from your settings ·
The script you verified is what runs: it is sent over your SSH connection, not fetched again by the server.
What the session looks like
Section titled “What the session looks like”The installer asks for the few things it needs and types nothing secret into your shell history. Planned for Guard 1.0; the values shown are the default rules.
✓ installer signature verified (Sigstore · zunderlabs/zunder-guard)✓ zunder-guard 1.0.0 installed to /usr/local/bin Your rules from zunderlabs.com max leverage 5× · loss at stop 2% · no stop: Guard sets one 2% away liquidation ≥ 10% · size ≤ 200% · open risk ≤ 6% daily loss stop 6% · drawdown halt 25% · markets: allKeep these rules? [Y/edit] › Y Hyperliquid account address › 0x8c41…a90fAPI wallet key (hidden, never stored in plain text) › ••••••••••••••••✓ key belongs to an API wallet of 0x8c41…a90f · it cannot withdrawMode [paper/testnet/mainnet] › paper ✓ Guard is running (systemd: zunder-guard) · listening on 127.0.0.1:8547Client key for your bot (shown once): zc_7Hq2…Lm9xNext: point your bot at http://127.0.0.1:8547
What the script does
Section titled “What the script does”- Downloads the release archive for the server’s architecture (x86-64 or ARM64) and its checksum file.
- Checks the archive’s SHA-256 against the checksum file, and the checksum file’s Sigstore signature, and stops on any mismatch.
- Creates a system user
zunder-guardwith no login shell and a state directory readable only by that user. - Installs the binary, writes the config in paper mode, and installs a systemd unit that binds Guard to
127.0.0.1:8547. - Prints the client key for your bot and the firewall rule for this server.
It does not open a port, does not ask for your API wallet key, and does not start trading.