Deterministic policy enforcement for AI agents. Control what your agent can do — spending limits, destructive command blocking, credential gating — without putting an LLM in the decision path.
cargo install signet-eval
1. Install: cargo install signet-eval
2. Hook into Claude Code:
{
"hooks": {
"PreToolUse": [{
"matcher": "",
"hooks": [{"type": "command", "command": "signet-eval", "timeout": 2000}]
}]
}
}
3. Done. Every tool call now passes through policy evaluation.
| Action | Decision |
|---|---|
rm, rmdir | DENY |
git push --force | ASK |
mkfs, format, dd if= | DENY |
curl | sh, wget | sh | DENY |
Write to .env, .pem, .key | DENY |
chmod 777 | ASK |
| Everything else | ALLOW |
# ~/.signet/policy.yaml
version: 1
default_action: ALLOW
rules:
- name: books_limit
tool_pattern: ".*purchase.*"
conditions:
- "param_eq(category, 'books')"
- "spend_plus_amount_gt('books', amount, 200)"
action: DENY
reason: "Books spending limit ($200) exceeded"
- name: block_sudo
tool_pattern: ".*"
conditions: ["param_contains(command, 'sudo')"]
action: ASK
reason: "sudo requires confirmation"
| Function | Description |
|---|---|
contains(parameters, 'X') | Tool input contains string |
any_of(parameters, 'X', 'Y') | Any string present |
param_eq(field, 'value') | Field equals value |
param_ne(field, 'value') | Field not equal |
param_gt(field, N) | Field > number |
param_lt(field, N) | Field < number |
param_contains(field, 'X') | Field contains substring |
matches(field, 'regex') | Field matches regex |
has_credential('name') | Credential exists in vault |
spend_gt('cat', N) | Session spend exceeds limit |
spend_plus_amount_gt('cat', field, N) | Cumulative spend + amount exceeds limit |
not(condition) | Negate any condition |
or(A || B) | Either condition true |
true / false | Literal boolean |
Argon2 + AES-256-GCM. Three tiers: public ledger, session-encrypted state, compartment-encrypted credentials. Your CC number is stored where the agent can't read it.
Track cumulative spend per category. "Don't spend more than $200 on books" just works — the vault ledger enforces it across every tool call.
Manage policies by talking to Claude. "Add a $50 limit for amazon orders." 12 MCP tools for rules, credentials, status, and testing.
Wrap upstream MCP servers with enforcement. The agent connects to the proxy, not directly to servers. No bypass possible.
signet-eval test '{"tool_name":"Bash","tool_input":{"command":"rm foo"}}' — test rules without running as a hook.
44 tests including Goodhart tests: unicode homoglyphs, null bytes, 1MB inputs, SQL injection in conditions, 1000-rule performance bounds.
Part of the Signet personal sovereign agent stack. The core principle: the authorization layer must not be an LLM. It processes structured data only. No natural language, no context window, no persuasion surface. A rule either matches or it doesn't.
Agent proposes action -> signet-eval evaluates policy -> allow / deny / ask
(deterministic, 5ms, no NLP)
| Command | Purpose |
|---|---|
signet-eval | Hook evaluation (default, 5ms) |
signet-eval init | Write default policy file |
signet-eval rules | Show current rules |
signet-eval validate | Check policy for errors |
signet-eval test '<json>' | Test a tool call |
signet-eval setup | Create encrypted vault |
signet-eval unlock | Refresh vault session |
signet-eval status | Vault status and spending |
signet-eval store <n> <v> | Store Tier 3 credential |
signet-eval log | Recent action log |
signet-eval serve | MCP management server |
signet-eval proxy | MCP proxy |