Verified Prompt Envelope Protocol & AI Agent Security.
Seal replaces linguistic injection detection with cryptographic provenance verification for AI agent prompts. Every prompt gets an Ed25519-signed envelope that proves who authorized it, what scope it has, and that it hasn't been tampered with.
- VPE Core — Sign/verify prompts with Ed25519 or HMAC-SHA256, N-of-M multi-signature, hierarchical issuer cert chains, and hardware (HSM/TPM/Secure Enclave) signing
- EPD Scanner — Pre-LLM injection detection: regex + LLM fallback, plus Unicode-smuggling defense (invisible tag-block / variation-selector payloads) and an adversarial fuzzer
- Secrets Broker — Keep credentials out of model context (
{SECRET:label}proxy, Fernet-encrypted store, access audit) - Key lifecycle — SQLite-backed key registry, rotation daemon, persistent nonce/counter replay protection
- CLI — 18 commands:
sign,verify,genkey,secrets,key {rotate,revoke,daemon,…},audit,rollback,hardware,fuzz,status - Integration — MCP middleware for Hermes + Division audit trail, with one-toggle rollback
- Tested — 569 tests across core, EPD, crypto-bypass, key lifecycle, hardware, federation, and e2e suites
# Install (one command). `pip install seal-vpe` is planned but NOT yet on PyPI.
pip install git+https://github.com/rezearcher/seal.git
# or from a clone: pip install -e ".[dev]"
# See it all end-to-end in one shot
seal quickstart
# Generate a key pair
seal genkey
# Sign a prompt
seal sign "search the database for customer X" \
--scope '{"allowed_tools": ["search"]}' \
--issuer "user:rez"
# Verify an envelope
echo '<envelope>' | seal verifyfrom seal import generate_key_pair, vpe_sign, vpe_verify
keys = generate_key_pair()
envelope = vpe_sign(
prompt="search the database for customer X",
scope={"allowed_tools": ["search"]},
issuer="user:rez",
audience="agent:hermes-default",
ttl_seconds=300,
private_key=keys["private_key"],
)
result = vpe_verify(envelope, public_key=keys["public_key"])
assert result["valid"] is TrueSeal has three subsystems:
┌─────────────────────────────────────────────────────────────┐
│ Seal │
├─────────────┬──────────────────────┬────────────────────────┤
│ VPE Core │ EPD Scanner │ Secrets Broker │
│ │ │ │
│ Ed25519 / │ Regex patterns + │ Encrypted store + │
│ HMAC-SHA256 │ LLM fallback for │ {SECRET:label} proxy │
│ signing & │ injection detection │ for tool calls │
│ verification│ │ │
└─────────────┴──────────────────────┴────────────────────────┘
| Component | Description | Module |
|---|---|---|
| VPE Core | Ed25519/HMAC sign/verify, multi-sig, cert chains, hardware signing, canonical JSON | seal/core.py, seal/vpe.py |
| EPD Scanner | Two-pass regex (91%+) + LLM, Unicode-smuggling defense (T11), fuzzer | seal/epd/ |
| Secrets Broker | Fernet-encrypted credential store (seal/credential_store.py), placeholder resolution, audit log. Note: seal/secrets_broker.py is a legacy plaintext path — see Security notes below. |
seal/broker.py, seal/credential_store.py |
| Key lifecycle | SQLite key registry, rotation daemon, persistent nonce/counter stores | seal/key_manager.py, seal/key_store.py, seal/store.py |
| Hardware / Federation / Rollback | HSM signing; cross-agent trust; one-toggle rollback | seal/hardware.py, seal/federation.py, seal/rollback.py |
| CLI | 18 commands: genkey, sign, verify, secrets, key, audit, rollback, hardware, fuzz, status |
seal/cli.py |
| Integrations | Hermes MCP middleware, Division memory signing + audit trail | seal/integration/ |
Full module inventory & per-phase build status:
ARCHITECTURE.md.
{
"vpe_version": "1.0",
"prompt": "search the database...",
"scope": {"allowed_tools": ["search"]},
"issuer": "user:rez",
"audience": "agent:hermes-default",
"doc_sha256": "abc123...",
"ttl_seconds": 300,
"nonce": "a1b2c3d4",
"counter": 42,
"signature": "ed25519_sig_hex..."
}| Problem | Current Practice | VPE Fix |
|---|---|---|
| Prompt injection | Linguistic filtering (~91% catch) | Cryptographic provenance |
| Scope escalation | No enforcement at prompt level | Envelope carries signed scope |
| Replay attacks | No protection | Nonce + counter per envelope |
| Credential leakage | Keys in prompt context | Secrets Broker proxy |
| Audit | None / manual log review | Signed, tamper-evident audit trail |
Phase 1-4 complete. Full architecture & roadmap.
- Phase 1 — VPE Spec & Reference Implementation ✓
- Phase 2 — EPD Scanner ✓
- Phase 3 — Secrets Broker ✓
- Phase 4 — Hermes/Division Integration ✓ |- Phase 5 — Performance & Production Hardening (in progress)
# Not yet on PyPI — `pip install seal-vpe` is planned, not live. Install from source:
pip install git+https://github.com/rezearcher/seal.gitSee Quickstart and As a library above for usage.
cd vpe-go/
go test ./vpe/...import "github.com/seal/vpe-go/vpe"
priv, pub, _ := vpe.GenerateKeyPair()
env, _ := vpe.VpeSign("prompt", nil, "user:rez", "agent:hermes",
"", 300, "", nil, priv, false)
result := vpe.VpeVerify(env, pub, nil, 0, 0, nil)
// result.Valid == truecd vpe-rust/
cargo testuse vpe_rust::{vpe_sign, vpe_verify, generate_key_pair};
let kp = generate_key_pair();
let env = vpe_sign("prompt", None, "", "", "", 300, None, None, &kp.private_key, false);
let result = vpe_verify(&env, &kp.public_key, None, 0, 0, None);
// result.valid == truecd vpe-ts/
npm install
npm testimport { generateKeyPair, vpeSign, vpeVerify } from './src/index';
const kp = generateKeyPair();
const env = vpeSign('prompt', { privateKey: kp.privateKey });
const result = vpeVerify(env, { publicKey: kp.publicKey });
// result.valid == trueAll ports use the same canonical JSON serialization and Ed25519 signing. Envelopes signed in any language can be verified by any other language:
Sign in Python → Verify in Go / Rust / TypeScript
Sign in Go → Verify in Python / Rust / TypeScript
Sign in Rust → Verify in Python / Go / TypeScript
Sign in TS → Verify in Python / Go / Rust
- Private keys unencrypted at rest: Private keys stored in the key manager (
~/.seal/keys.dbviaseal/key_manager.py) are currently stored raw (unencrypted) in SQLite. Encryption-at-rest for the key store is planned but not yet implemented. Protect~/.seal/keys.dbwith appropriate filesystem permissions. - TTL enforcement requires
iat: TTL expiry is only enforced when theiat(issued-at) field is present in the envelope. Envelopes created byvpe_signalways includeiat; legacy envelopes withoutiatare treated as having no expiry. - Two credential store paths exist — only one is encrypted:
seal/credential_store.py(seal.credential_store.CredentialStore) uses Fernet encryption at rest and is the recommended path.seal/secrets_broker.pycontains a legacyCredentialStorethat stores credentials as plaintext JSON at~/.hermes/secrets.json— it is deprecated and will emit aDeprecationWarningon import. Useseal.brokerandseal.credential_storefor new code.
# Clone and install
git clone https://github.com/nousresearch/seal.git
cd seal
# Set up with uv
uv venv
uv pip install -e ".[dev]"
# Run tests
uv run pytest
# Lint
uv run ruff check .MIT — see LICENSE.
See SECURITY.md for reporting vulnerabilities.