Your AI agent knows everything about you.
Who controls what it shares?

Signet is a cryptographic vault that sits between you and the world. Your agent proves things about you without revealing you. No passwords handed over. No data copied. No trust required.

cargo install signet
For Everyone

You shouldn't have to give away your secrets to use the internet.

The Problem

Every time you use an AI agent, buy something online, or prove your age, you hand over real data. Your name. Your address. Your card number. Your medical history. That data gets copied, stored, breached, sold, and correlated.

You are not the customer. You are the product. And your data outlives every company that collects it.

The Signet Answer

What if you could prove you're over 21 without showing your ID? Pay for something without giving a merchant your card number? Let your AI agent book a flight without it knowing your passport number?

Signet makes this real. Your vault holds your secrets. Your agent carries proofs. The outside world verifies the proof and never sees the original.

A signet was a seal carried by a trusted proxy to sign documents on behalf of a lord — in their absence, with their full authority. The vault is the matrix (the original, never leaves you). The agent is the proxy carrying the seal. The proof is the impression — proves authority without revealing the ring.

Data flows one direction. Always.

Vault
Agent
Service

Never reverse. The service cannot reach into your vault. Your agent cannot send data upstream. Every disclosure is logged, scoped, and revocable.

For Builders

Nine crates. Four primitives. One install.

Signet is a Rust workspace — 30,000 lines, 473 tests, nine crates that compose into a complete personal sovereignty stack. It integrates with AI agents via the Model Context Protocol (MCP), meaning it works with Claude today.

The trust hierarchy is simple:

  1. User holds an Ed25519 root keypair
  2. Vault encrypts and stores everything locally
  3. Agent is credentialed by the vault to act on the user's behalf
  4. External services receive proofs, never raw data
User (Ed25519 root) +-- Vault (encrypted, never reachable) +-- Agent (credentialed steward) +-- Services (petitioners)

The Crates

signet-core

Shared types and traits. Signer, StorageBackend, AuditChainWriter. The interfaces everything else implements.

signet-vault

Root of trust. BlindDB storage, BIP39 mnemonics, SLIP-0010 Ed25519 derivation, AES-256-GCM envelope encryption, hash-chained audit log.

signet-cred

Credential issuance. SD-JWT VCs for interop, BBS+ for unlinkable selective disclosure, Pedersen commitments for numeric proofs, PASETO v4 capability tokens.

signet-proof

Typestate proof pipeline. ProofRequestProofPlanProofBundleBoundPresentation. Compile-time guarantees that you can't skip steps.

signet-policy

XACML-for-individuals. Three-way PERMIT / DENY / ANOMALY decisions. Role hierarchy with deny-override combining. Pattern detection with MAC protection.

signet-notify

Authorization channel. HMAC-SHA256 webhook signatures, challenge-response, circuit breaker, scope subset validation to prevent privilege escalation.

signet-mcp

MCP server with middleware pipeline. Session validation, tier classification, policy evaluation, tool execution, audit recording. Seven MCP tools out of the box.

signet-sdk

Four primitives: verify, requestCapability, checkAuthority, parseCredential. Everything a service needs to accept Signet proofs.

Integration is Four Lines

Verify a proof

use signet_sdk::verify;

let result = verify(proof_token, "age_over_21", "shop.example.com");
// result.valid, result.expires, result.scope

Request a capability

use signet_sdk::request_capability;

let cap = request_capability(CapabilitySpec {
    kind: "payment",
    max_amount: 150,
    domain: "amazon.com",
    one_time: true,
});

Standards, Not Inventions

Layer Standard Why
IdentityEd25519 fingerprintSelf-certifying. No DID. No registry.
CredentialsSD-JWT VC (RFC 9901)IETF standard, EU wallet compatible
PrivacyBBS+ SignaturesUnlinkable selective disclosure
Range proofsBulletproofsNo trusted setup required
Agent protocolMCPNative Claude integration
TokensPASETO v4Misuse-resistant, no algorithm confusion
Key derivationBIP39 + SLIP-0010Deterministic, recoverable
Policy Enforcement

Your AI agent can't rm -rf if you don't let it.

Deterministic policy enforcement for AI agent tool calls. Single Rust binary, zero runtime dependencies. Evaluates in ~2µs.

policy.yaml
Simulate Tool Call

Try these:

Client-side simulation. Real signet-eval is a compiled Rust binary evaluating in ~2 microseconds.

$ cargo install signet-eval $ signet-eval init # creates policy.yaml $ signet-eval rules # show active rules
15 condition types
128 tests
Claude Code hook integration. View on GitHub
Authorization Language

Authorization in 2 microseconds.

Safe Policy Language (SPL) — token-embedded authorization. Policy travels with the token, not stored on a server.

TypeScriptGoPythonRustJavaC#

Ed25519 Signing

Every token is cryptographically signed. Tampering is detectable. No trust assumptions.

Merkle Proofs

Selective disclosure of policy clauses. Verifier sees only the relevant subset.

Offline Budgets

Hash-chain spending limits that work without server round-trips.

// Capability token with embedded SPL policy
{
  "sub": "agent:7f3a2b",
  "iss": "vault:ed25519:abc123",
  "aud": "amazon.com",
  "exp": 1711756800,
  "spl": {
    "permissions": ["purchase"],
    "max_amount": 150,
    "currency": "USD",
    "one_time": true,
    "budget_chain": "sha256:9f86d0..."
  },
  "sig": "ed25519:..."
}
Get Started

Three commands to sovereignty.

1. Install & Initialize

# Install from source
cargo install --git https://github.com/jmcentire/signet.git signet

# Create your vault (generates keypair, stores mnemonic)
signet init

# Store some data
signet store --tier 1 --label "age" --value "29"
signet store --tier 1 --label "name" --value "Alice Nakamoto"
signet store --tier 3 --label "credit_card" --value "4111-1111-1111-1111"
signet list

2. Connect to Claude Desktop

# Add to ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "signet": {
      "command": "signet",
      "args": ["serve"]
    }
  }
}

3. Issue Capability Tokens

# SPL token with embedded policy, Ed25519-signed
signet capability \
  --domain "amazon.com" \
  --max-amount 150 \
  --purpose "purchase" \
  --one-time

HTTP Server for Verification

# Start the verification server
signet serve --transport http --port 3000

# Verify a proof
curl -X POST http://localhost:3000/verify \
  -H "Content-Type: application/json" \
  -d '{"proof": "...", "claim": {"attribute": "age_over_21", "value": true}}'
For Security Engineers

Information = records + relationships.
We destroy the relationships.

Signet's storage layer implements the BlindDB model from The Ephemeral Internet (McEntire, 2026). The core insight: in most breaches, the relationships between records are more valuable than the records themselves. A credit card number is dangerous. A credit card number linked to a name, address, email, and purchase history is an identity.

BlindDB doesn't just encrypt your data. It makes relationships between records uncomputable by anyone without the client-side master secret.

Try It

What you see
MASTER SECRET (client-side only)a7f2b9c1d8e4f6a3b5c7d9e1f3a5b7c9
What the server sees
RECORD IDtype a label...
ENCRYPTED DATAtype a value...

Server cannot determine:

  • ?What "email" means
  • ?Who this record belongs to
  • ?Which other records are related
  • ?Whether this is real or seed data

SHA-256 via Web Crypto API. Record ID = SHA-256(master_secret || label || index). Real Signet uses AES-256-GCM envelope encryption.

Five Defense Layers

1

Relational Opacity Primary

Record IDs are SHA-256(master_secret || label || index). The server stores a flat pile of opaque hashes. No user table. No foreign keys. No joins. No way to determine which records belong to the same user, which form a collection, or what any record represents.

This is the defense that matters most. Even if every other layer fails, an attacker with full database access sees a pile of unrelated blobs.

2

Tamper Evidence

Hash-chained audit log. Every vault operation is signed and appended. Chain breaks are detectable. You know if someone modified the record store.

3

Provenance & Ordering

Hash chains provide causal ordering. You can prove a record existed before another. You can prove a sequence of operations happened in order. The server cannot reorder history.

4

Encryption

AES-256-GCM per-record envelope encryption. Per-record DEKs derived from the master secret and record ID: enc_key = SHA-256(master_secret || record_id || "encrypt"). For data that has independent value (credit cards, SSNs), encryption is the last line.

5

Plausible Deniability

Seed data is cryptographically indistinguishable from real data. An attacker cannot determine whether a record is genuine or injected noise. The total record count reveals nothing about the number of users or records per user.

What the Attacker Sees

Three users store emails, addresses, payment cards, medical records, video watch histories, and credential statuses. Here is the server's complete database:

SELECT * FROM records;

 #  record_id                           data
--- ----------------------------------- -------------------------
 1  0a3f8b2c...e771c921                 <encrypted 44 bytes>
 2  1b8e4d7a...f9823d44                 <encrypted 68 bytes>
 3  2c7a91e5...a4f08812                 <encrypted 52 bytes>
 4  3d1f6c88...b8e22a97                 <encrypted 40 bytes>
 5  4e2a7d99...c7f33b06                 <encrypted 88 bytes>
 6  5f3b8eaa...d6044c15                 <encrypted 36 bytes>
 7  6a4c9fbb...e5155d24                 <encrypted 48 bytes>
 8  7b5da0cc...f4266e33                 <encrypted 72 bytes>
 9  8c6eb1dd...03377f42                 <encrypted 44 bytes>
10  9d7fc2ee...12488051                 <encrypted 56 bytes>
11  ae80d3ff...21599160                 <encrypted 40 bytes>
12  bf91e400...306aa27f                 <encrypted 64 bytes>
13  c0a2f511...4f7bb38e                 <encrypted 48 bytes>

Questions the attacker cannot answer:

  • ? Which records belong to Alice? Bob? Carol?
  • ? Which email goes with which address?
  • ? Who has the credit card? The SSN? The medical record?
  • ? How many users are there? (3? 30? 300?)
  • ? Which records form a collection?
  • ? Is record #5 an email, an address, or a video title?
  • ? Are any of these records fake (seed data)?

Run it yourself: cargo test --package signet-vault --test show_db -- --nocapture

Key Derivation

BIP39 Mnemonic (24 words, 256 bits entropy)
 +-- SLIP-0010 Ed25519 master key
      +-- VaultSealingKey  (HKDF: master + "vault-seal")
      |    +-- Per-record DEKs (HKDF: VSK + record_id)
      +-- CompartmentKeys  (HKDF: master + compartment_id)
      |    +-- Tier 3 DEKs  (NOT derivable from VSK -- structural isolation)
      +-- DeviceKeys        (HKDF: master + device_id)

Tier 3 compartment keys are structurally isolated from the vault sealing key. An agent session that holds the VSK cannot derive compartment keys. This is enforced by the key hierarchy, not by access control.

Tiered Key Inputs

Tier Key Input Survives Password Reset Use Case
1SHA-256(username + server_salt)YesPreferences, age proofs, public posts
2SHA-256(username + password + "master")NoAgent reasoning context, session data
3random_key() (OsRng, 256-bit)N/A (unrecoverable)Payment credentials, identity docs, medical

Crypto-erasure: discard the master secret and all record IDs become uncomputable. GDPR compliance by mathematics, not by policy.

Implementation Rigor

Constant-Time Comparisons

All CAS operations and authentication checks use subtle::ConstantTimeEq. No timing side-channels on secret-dependent branches.

OS-Level Entropy

rand::rngs::OsRng for every cryptographic operation. No userspace PRNGs in security paths. Verified across all 9 crates.

Memory Zeroization

All secret key material wrapped in Zeroizing<>. Secrets are zeroed from memory on drop. No residual key material.

No Plaintext on Server

The BlindStorageWrapper is a transparent layer that blinds record IDs (SHA-256) and encrypts data (AES-256-GCM) before any backend call. The server never sees labels, plaintext, or semantic content.

Audit Chain Integrity

Hash-chained append-only log. Each entry includes the hash of the previous entry. Tampering breaks the chain. Independently verifiable.

Structural Tier Isolation

Tier 3 keys are not derivable from the vault sealing key. This is a property of the key hierarchy, not a policy check. A compromised agent session cannot access Tier 3 data.

473 tests. Zero unwrap() in library code. Clippy clean.

Read the code. Run the tests. Break the assumptions.

Self-Validating Documents

Documents that validate themselves.

Tessera produces executable documents that carry their own verification. Receipts, contracts, proofs — the document IS the proof of its own authenticity.

Digital Receipts

Receipts that cryptographically prove the purchase happened, signed by both parties.

Verifiable Contracts

Contracts that verify every signer's identity without a third-party notary.

Credential Bundles

Portable credential packages that validate against the issuer's public key on open.

View on GitHub
Ephemeral Messaging

Messages that exist only in transit.

Decentralized peer-to-peer messaging. No servers, no persistence, no metadata. Ed25519 signing with NaCl encryption. When the recipient reads it, it's gone.

Research

Built on research, not assumptions.

Read all papers
Ecosystem

Signet is the trust layer of the Exemplar stack.