---
name: shellpermit
description: Deterministic bash command policy checks with a signed, command-bound execution permit.
---

# ShellPermit

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.

## When to use this

Use `POST https://shellpermit.schemasure.com/v1/guard/shell` when you need: Check a bash command against an execution policy and optionally issue a signed permit.

## How to pay

1. Send the request without payment. You receive HTTP 402 and a base64 `PAYMENT-REQUIRED` header.
2. Decode it, sign one of the `accepts` entries with your wallet locally.
3. Retry the identical request with the `PAYMENT-SIGNATURE` header.
4. A successful response carries a `PAYMENT-RESPONSE` receipt.

Cost: $0.015 in USDC on Base mainnet. Failed calls are free.
Your private key never leaves your process.

## Request

```json
{
  "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
}
```

## 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."
  ]
}
```

## Reading the verdict

- `resolved` / `pass` / `allow` — the service answered and the answer is usable.
- `warn` — usable, but `evidence` contains findings you should act on.
- `block` — the service is telling you not to proceed. Read `risk_codes`.
- `unknown` — the service could not determine the answer. **Do not treat this as safe.**
