# ShellPermit Deterministic bash command policy checks with a signed, command-bound execution permit. ShellPermit tokenizes a candidate bash command — quoting, escaping, pipelines, command and process substitution, heredocs, redirections — walks the result, and reports whether it complies with the policy you supply: allowed roots, network egress, destructive operations, privilege escalation, command allow and deny lists. Every segment of a chain is evaluated and the verdict is the worst across them. Detection is structural, so bundled flags, $IFS, base64, unicode look-alikes and quoting games cannot hide a construct from it. On a compliant command it can issue a signed Ed25519 permit, valid for 60 seconds, bound to the sha256 of the canonical command — which collapses quoting and flag order but preserves every operand, so a permit for `rm -rf /tmp/build` can never authorise `rm -rf /`. What it cannot do: it never runs anything and never sees your filesystem, so it cannot resolve a symlink, cannot know which files exist, and cannot see your aliases, shell functions, or PATH. It is defence in depth alongside a sandbox and a least-privilege user, not a replacement for either. ## Payment - Protocol: x402 V2, scheme `exact`, network `eip155:8453` (Base mainnet) - Asset: USDC `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` - No accounts, no API keys, no subscriptions. - Failed calls are not charged. Only a successful, usable result settles. - Payment authorization window: 60s ## Endpoints ### `POST /v1/guard/shell` — $0.015 per successful call Decide whether an agent-authored bash command complies with an execution policy, using a real shell tokenizer rather than pattern matching. Catches recursive deletes, force pushes, cluster and infrastructure teardown, raw device writes, path escapes, privilege escalation, and curl-piped-to-shell through pipelines, substitutions, quoting games and base64. Returns reason codes with spans and an optional short-lived permit bound to the exact canonical command. Never executes anything. Unpaid request returns HTTP 402 with the challenge in the `PAYMENT-REQUIRED` header: ```bash curl -i -sS -X POST https://shellpermit.schemasure.com/v1/guard/shell \ -H 'content-type: application/json' \ -d '{"shell":"bash","command":"rm -rf ./dist && npm run build","policy":{"allowed_roots":["/srv/app"],"cwd":"/srv/app","allow_destructive":true,"allow_network_egress":false},"audience":"executor:acme-prod-01","issue_permit":true}' ``` Example successful response: ```json { "ok": true, "verdict": "pass", "confidence": 1, "risk_codes": [], "evidence": [ { "code": "RECURSIVE_FORCED_DELETE", "severity": "critical", "disposition": "info", "detail": "\"rm\" deletes /srv/app/dist, recursively, without prompting. The policy permits destructive operations.", "source": "shellpermit/detect", "span": { "start": 0, "end": 13 } } ], "result": { "shell": "bash", "command_count": 2, "segment_count": 2, "commands": [ "npm", "rm" ], "touched_paths": [ "/srv/app/dist" ], "destructive": true, "network": false, "findings": [ { "code": "RECURSIVE_FORCED_DELETE", "severity": "critical", "disposition": "info", "detail": "\"rm\" deletes /srv/app/dist, recursively, without prompting. The policy permits destructive operations.", "source": "shellpermit/detect", "span": { "start": 0, "end": 13 }, "data": { "targets": [ "/srv/app/dist" ], "recursive": true, "forced": true } } ], "canonical_command": "rm -f -r ./dist && npm run build", "cmd_hash": "sha256:dbf92266aa4df1527e417b2750b330d560e6bce2b9c6962ce1008b5a5ba13ba7", "cmd_fingerprint": "bccaa66b5ba1bae6", "policy_hash": "sha256:d68a66fd0b6027805655642be61c913ecca490ae8e3c30eef350ee5992a6e2d9", "grammar": "bash/shellpermit-lexer@1.0.0", "obligations": { "allowed_roots": [ "/srv/app" ], "cwd": "/srv/app", "network_egress_allowed": false, "destructive_allowed": true, "timeout_ms": 120000 }, "permit": "eyJhbGciOiJFZDI1NTE5Iiwia2lkIjoi…", "permit_expires_at": "2026-09-19T12:01:00.000Z", "permit_kid": "uGzLTTwi4LTsOiBLgwf2wMU7ILTecj18Y_71Y37bVD8" }, "policy_version": "shellpermit-policy-1.0.0", "request_hash": "sha256:1c2d0f4c1d8e2b7a9c5d3e6f8a1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b", "data_versions": { "grammar": "bash/shellpermit-lexer@1.0.0", "shell": "bash", "lexer": "shellpermit-lexer@1.0.0" }, "warnings": [ "cmd_fingerprint is ADVISORY and must not be used for authorization: it discards every operand, so `rm -f -r /tmp/build` and `rm -f -r /` share one fingerprint. cmd_hash is the binding value." ] } ``` ## Result contract Every response is the shared portfolio envelope: `ok`, `verdict`, `confidence`, `risk_codes`, `evidence`, `result`, `policy_version`, `request_hash`, `data_versions`, `warnings`. `verdict: "unknown"` is a real answer, not a failure. It means the service could not determine the result and says why in `evidence`. It is never silently reported as a safe or clean outcome. ## Service level - Target P50: 50 ms - Target P95: 150 ms ## Data handling - Caller content is processed transiently and never retained. - No training on customer content. - No subprocessors see caller content. ## Machine-readable surfaces - https://shellpermit.schemasure.com/openapi.json - https://shellpermit.schemasure.com/.well-known/x402.json - https://shellpermit.schemasure.com/.well-known/pricing.json - https://shellpermit.schemasure.com/.well-known/benchmarks.json - https://shellpermit.schemasure.com/.well-known/data-handling.json - https://shellpermit.schemasure.com/apis.json - https://shellpermit.schemasure.com/SKILL.md