@signet-labs/signet-guardian
v0.1.9
Published
Payment guard middleware for OpenClaw: policy (payments on/off, per-transaction and monthly limits) for AI agent payments.
Maintainers
Readme
Signet Guardian
Payment guard middleware for OpenClaw. Enforces a single policy layer (payments on/off, per-transaction limit, monthly cap) so payment-capable skills route through it before and after spending.
- Preflight — Check if a payment is allowed (ALLOW / DENY / CONFIRM_REQUIRED).
- Record — Append completed payments to the ledger (enforces monthly cap under lock).
- Report — View spending for today or month.
- Policy — Show or edit limits and rules.
Full behaviour and agent contract: SKILL.md.
Table of contents
- Requirements
- Install
- Secure Setup (recommended)
- Production hardening
- Configuration
- Dashboard
- Usage
- Testing
- License
Documentation
| Doc | Description | |-----|-------------| | docs/PRODUCTION_HARDENING.md | Production hardening, integrity manifest, safe upgrade workflow | | docs/TAMPER_RESISTANCE.md | Policy tamper-resistance (OTP, admin-only, audit) | | docs/TRANSACTION_AUDIT.md | Transaction audit trail (JSONL, event types, commands) | | docs/TELEGRAM_TX_COMMANDS.md | Telegram transaction commands and privacy rules | | docs/ACCEPTANCE_TESTS.md | Manual acceptance tests (dashboard, secure setup, hardened mode) |
Requirements
- Node.js 18+
- OpenClaw (see openclaw)
Install
From npm (OpenClaw plugin)
openclaw plugins install @signet-labs/signet-guardian
openclaw gateway restartInstall warnings: When installing (e.g. openclaw plugins update or npm install -g), you may see deprecation warnings such as npm warn deprecated npmlog@... or glob@.... These come from npm’s own dependency tree, not from Signet Guardian. They do not affect the plugin or the CLI and can be safely ignored. Updating them is handled by the npm ecosystem.
Development (from repo)
git clone <repo-url>
cd signet-guardian
pnpm install
pnpm run buildSecure Setup (recommended)
You install the package, then run the setup command once. No manual file copying or script running — the setup command creates /etc/signet/policy.json, sets permissions, and configures OpenClaw to use it. After that, policy is read only from that file and the agent cannot change it.
After install (ensure hardening): run sudo signet setup (or sudo npx @signet-labs/signet-guardian setup), then signet doctor — all checks should show PASS. Optional full host lock: sudo signet harden-host.
1. Install the package
openclaw plugins install @signet-labs/signet-guardian
openclaw gateway restart2. Harden policy (one-time, requires sudo)
sudo npx @signet-labs/signet-guardian setupIf you installed the CLI globally: sudo signet setup.
3. Verify hardening
npx @signet-labs/signet-guardian doctor
# or, if global: signet doctorAll checks should show PASS. If any fail, follow the remediation (e.g. run sudo signet setup again). In hardened mode, policy is managed by /etc/signet/policy.json; dashboard policy edits are ignored. To change policy later: sudo npx @signet-labs/signet-guardian setup --edit-policy (or sudo signet setup --edit-policy when global).
Hardened mode (default): With no extra config, Signet uses only /etc/signet/policy.json. If that file is missing or invalid, all payments are DENY (fail-closed). Use SIGNET_DEV_MODE=true only for local development to allow config/file fallbacks.
Optional — global CLI: To have signet in your PATH and avoid the npx prompt each time: npm install -g @signet-labs/signet-guardian, then use signet doctor, signet setup, etc.
Optional — manual hardening: If you cannot use the setup command (e.g. no npm/npx), you can create and secure the policy file by hand:
sudo mkdir -p /etc/signet
sudo cp ./references/policy.json /etc/signet/policy.json
sudo chown root:root /etc/signet/policy.json
sudo chmod 644 /etc/signet/policy.json
npx @signet-labs/signet-guardian doctorProduction hardening (code + config tampering)
For stricter protection — runtime user cannot modify policy, plugin code, or OpenClaw config — run the host hardening script once (as root). It locks ownership/permissions and creates an integrity manifest. Optional: run a periodic integrity check via systemd.
1. Run once (as root)
After installing the package, you can run hardening via the CLI (no need to find the script path):
sudo signet harden-host
# or: sudo npx @signet-labs/signet-guardian harden-hostFrom the repo you can instead run:
sudo bash scripts/harden-signet-host.sh
# or: pnpm run harden:hostDefaults: RUNTIME_USER=clawdbot, PLUGIN_DIR=/home/clawdbot/.openclaw/extensions/signet-guardian, CONFIG_FILE=/home/clawdbot/.openclaw/openclaw.json, POLICY_FILE=/etc/signet/policy.json. Override with env vars if needed.
2. Verify
sudo bash scripts/check-signet-integrity.sh
npx @signet-labs/signet-guardian doctorIntegrity check must pass; doctor should report PASS for policy, config, plugin dir, and manifest.
3. Optional: periodic integrity check (systemd)
Copy the timer and service, install the check script, then enable the timer:
sudo cp scripts/systemd/signet-integrity.service scripts/systemd/signet-integrity.timer /etc/systemd/system/
sudo cp scripts/check-signet-integrity.sh /usr/local/bin/
sudo systemctl daemon-reload
sudo systemctl enable --now signet-integrity.timerOn failure the check script logs SIGNET_INTEGRITY_FAIL to syslog and exits non-zero. Use --json for machine-readable output.
Safe upgrade (after hardening)
Updates require a temporary unlock: disable the timer, restore ownership/perms for the plugin (and config if needed), update the plugin, re-run the hardening script to regenerate the manifest, then re-enable the timer. See docs/PRODUCTION_HARDENING.md.
Configuration
Source of truth (dev only): When SIGNET_DEV_MODE=true, the CLI reads policy from OpenClaw config first (plugins.entries.signet-guardian.config.policy in ~/.openclaw/openclaw.json), then legacy signet.policy, then references/policy.json. You can edit policy in the Control UI (Dashboard) when the extension is installed; see openclaw-extension/README.md.
Policy shape (config or file):
{
"paymentsEnabled": true,
"maxPerTransaction": 20,
"maxPerMonth": 500,
"currency": "GBP",
"requireConfirmationAbove": 5,
"blockedMerchants": [],
"allowedMerchants": []
}Tamper resistance: Policy changes are admin-only and OTP-gated. Set SIGNET_ADMIN_TOTP_SECRET (base32) and use signet-policy-set --otp <6-digit> --reason "...". The payment path (preflight/record) cannot mutate policy. See docs/TAMPER_RESISTANCE.md.
Dashboard
Install from GitHub (manual)
If you cloned this repo, the dashboard shows Signet only after the plugin is in OpenClaw’s extensions path.
Open the dashboard:
openclaw dashboard(or visit http://127.0.0.1:18789/).Copy the plugin into the extensions path:
mkdir -p ~/.openclaw/workspace/.openclaw/extensions cp -r "$PWD/openclaw-extension/signet-guardian" ~/.openclaw/workspace/.openclaw/extensions/Restart:
openclaw gateway restart.In the dashboard, go to Settings → Config and look under
plugins.entries.signet-guardian.config.policy.
Install via plugin (published)
When using the published package:
openclaw plugins install @signet-labs/signet-guardian
openclaw gateway restart
openclaw dashboardThe plugin is installed under ~/.openclaw/extensions/ and enabled automatically.
Usage
Set the skill directory so the CLI uses the project’s references/:
export OPENCLAW_SKILL_DIR="$PWD"| Command | Description |
|---------|-------------|
| signet setup | (After install, with sudo.) Create and harden /etc/signet/policy.json |
| signet harden-host | (Optional, with sudo.) Full host hardening: lock plugin/config, create integrity manifest |
| signet policy --show | Print current policy |
| signet policy --edit | Edit policy file in $EDITOR |
| signet policy --wizard | Interactive policy setup |
| signet policy --migrate-file-to-config | Copy file policy into OpenClaw config |
| signet status | Human summary (Telegram-friendly) |
| signet remaining [--json] | Remaining this month |
| signet policy-get [--key <key>] | Read policy or one key |
| signet policy-set --key <k> --value <v> --otp <6-digit> --reason "..." | Admin-only. Update one policy field. |
| signet policy-audit [--tail N] | Last N policy audit entries |
| signet doctor [--json] | Check hardened policy (PASS/FAIL + remediation) |
| signet spend --period today\|month\|last30d | Spending summary |
| signet transactions [--limit N] [--status completed\|denied] | Recent transactions |
| signet preflight --amount 10 --currency GBP --payee "..." --purpose "..." | Check if payment is allowed |
| signet record --amount 10 --currency GBP --payee "..." --purpose "..." [--tx <txId>] [--idempotency-key "..."] | Record a completed payment (emits payment_attempted / payment_result / tx_closed to audit) |
| signet report --period month | Spending for the month |
| signet tx-event --tx <txId> --type <type> [--payload <JSON>] | Append an event to the transaction audit (intent_received, research_started, option_evaluated, recommendation_made, user_confirmation, etc.) |
| signet tx-show --tx <txId> [--json] | Show all events for a transaction |
| signet tx-list [--limit 20] [--json] | List recent tx (time, status, total, item/purpose, vendor) |
| signet tx-explain --tx <txId> | Plain-language timeline (“what happened and why”) |
| signet tx-latest [--json] | Short summary of most recent transaction |
| signet tx-breakdown --tx <txId> [--json] | Cost breakdown only (subtotal, shipping, tax, fees, total) |
| signet tx-alternatives --tx <txId> [--json] | Options considered + reasons + chosen |
| signet tx-export --format csv\|json --from <ISO> --to <ISO> [--limit N] | Export summary rows for date range (dashboard/reporting) |
Transaction audit trail: One append-only JSONL log (default /var/log/signet/transaction-audit.jsonl, or references/transaction-audit.jsonl if not writable). Every event has txId, ts, actor, eventType. No raw card/bank secrets. Viewing layers: (1) Telegram — primary; use signet tx latest, signet tx list, signet tx show <id>, signet tx explain, signet tx breakdown, signet tx alternatives; see docs/TELEGRAM_TX_COMMANDS.md. (2) Dashboard — “Recent Transactions” widget + filters + export (OpenClaw UI). (3) CLI — above commands; power users. (4) Raw audit file — forensics only. See docs/TRANSACTION_AUDIT.md.
Preflight returns JSON: {"result":"ALLOW","reason":"..."} or "DENY" / "CONFIRM_REQUIRED". Exit code 0 for ALLOW/CONFIRM_REQUIRED, 1 for DENY.
When running from the repo without the global CLI: npx tsx scripts/signet-cli.ts <command> ... (e.g. npx tsx scripts/signet-cli.ts doctor).
Testing
From the repo root:
./test-guardian.shUses references/ and exercises preflight, record, and report. To test the package as installed from npm: ./scripts/test-install.sh. Manual acceptance checklists (dashboard, Telegram, secure setup, hardened mode): docs/ACCEPTANCE_TESTS.md.
License
See repository.
