Capability-based safety gates for LLM agents. The model proposes; signet authorizes.
Project description
signet
Capability-based safety gates for LLM agents. The model proposes; signet authorizes.
signet sits between an LLM and any system that can execute its outputs. It is a small set of programmatic checks — owner resolution, classification gating, dual-judge dissent, sandbox preview, HMAC-chained audit — that decide whether the model's proposed action is allowed to actually run.
The model never holds commit authority. Same shape as a junior employee who can fill out a purchase order but cannot sign the check.
Why this exists
LLM agents that "wait for human input" rely on the model itself to comply with the instruction. Sufficiently capable models ignore the instruction whenever their objective gradient outweighs it. No prompt fixes that.
signet takes a different path: separate deciding what to do from being allowed to do it. The model decides; signet decides whether the decision can fire. The model's compliance is no longer load-bearing for the gate.
Install
pip install signet-sign
(The PyPI namespace signet was claimed by an unrelated abandoned project in 2014; the import name in code is still import signet.)
Quickstart — drop-in OpenAI-compatible proxy
Scaffold a starter project and run the proxy in front of any OpenAI-compatible upstream:
signet init my-gate/
cd my-gate
signet serve \
--upstream https://api.openai.com/v1 \
--config pipeline.py \
--audit-log audit.jsonl \
--allow-ephemeral-key
(Drop --allow-ephemeral-key and set SIGNET_HMAC_SECRET=$(openssl rand -hex 32) for production.)
Point your client at http://localhost:8443/v1 and add an owner header:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8443/v1",
default_headers={"X-Commit-Owner": "human:alice@example.com"},
)
client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "hello"}],
)
Without X-Commit-Owner (or X-Agent-Id: agent:<id>, or a configured trusted-network fallback), the proxy returns 403 with a refusal payload and writes an audit row.
Architecture in one paragraph
A Pipeline runs an ordered list of Check objects against every request. Each check can pre_request (block before forward), inspect_response_chunk (abort mid-stream), inspect_tool_call (block tool execution), or post_complete (audit). All decisions are written to an HMAC-chained, tamper-evident audit log designed to align with NIST 800-53 AU-3 / AU-9 audit-content and integrity requirements (verify against your own auditor — signet does not authenticate the owner identity it records).
See docs/architecture.md for the full design and SECURITY.md for the threat model and what's explicitly out of scope.
Endpoint coverage in v0.1. Only POST /v1/chat/completions is gated. Other OpenAI surfaces (/v1/embeddings, /v1/completions, /v1/audio/*, /v1/images/*) are not yet proxied. Calls to those endpoints will not reach signet's pipeline and will return 404 from the proxy.
Built-in checks
| Check | What it does |
|---|---|
owner_resolution |
Refuse requests without resolvable commit owner |
hmac_audit |
Append every decision to the tamper-evident chain |
rate_limit |
Token-bucket per owner |
regex_content |
Block / redact patterns in input or output |
classification_gate |
5-level architectural enforcement (UNCLASS → TS/SCI) |
prompt_injection |
Pattern + heuristic scan |
tool_call_inspector |
Inspect tool calls before forwarding |
token_budget |
Per-owner token quotas |
loopback_trust |
Auto-resolve owner for trusted internal IPs |
Bring your own via the plugin interface — docs/plugin_dev.md.
License
Apache-2.0. See LICENSE.
Provenance
Built by Jesse Morgan in tandem with Thornveil. Thornveil makes no IP claim on this open-source release; it is contributed under Apache-2.0 for community use. The proprietary Pyros engine and Mycelium proof-of-inference layer remain separate; signet is the publishable subset of the architectural pattern.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file signet_sign-0.1.0.tar.gz.
File metadata
- Download URL: signet_sign-0.1.0.tar.gz
- Upload date:
- Size: 101.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b311ce263ca6a85f188f1b0698d76d24c23686ef532816fac68905938c082fdb
|
|
| MD5 |
93aa705eeb52d538d5e5be8a9d84a19b
|
|
| BLAKE2b-256 |
d80ac2c38cc8fc226fe740f1376381cf1e3d33662a45814bf682504470697bbe
|
File details
Details for the file signet_sign-0.1.0-py3-none-any.whl.
File metadata
- Download URL: signet_sign-0.1.0-py3-none-any.whl
- Upload date:
- Size: 94.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8e14d075ff5fbaf3e853a877a4b3668d593947df59224982f1247bb75e396c7
|
|
| MD5 |
de5e1f1015c24553e74805c4bc8f5570
|
|
| BLAKE2b-256 |
2c9b2613319a8d4d5d15369b1d3d099cc1dee2054d8f250777e0366d91440eb2
|