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 --git https://github.com/jmcentire/signet.git signet

Set up with Claude Desktop →

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.

Tier 1

Freely Provable

"Are you over 21?" Your agent answers instantly with a cryptographic proof. No data leaves the vault. The answer is yes or no, mathematically guaranteed, with no way to learn anything else.

Age verification, preferences, public profile

Tier 2

Agent-Internal

"What shelves did they order last time?" Your agent knows. It uses that knowledge to reason and act on your behalf. But it never exports the raw data. External services get conclusions, not facts.

Purchase history, browsing context, recommendations

Tier 3

Capability-Gated

Your credit card. Your passport. Your medical records. Your agent literally cannot read them without your explicit, one-time authorization. It knows they exist. It can ask. It cannot proceed without you.

Payment, identity documents, medical data

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.

Nine crates. Four primitives. One install.

Signet is a Rust workspace — nine crates, 1,050 tests, clippy clean. 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 or hosted)
  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, Ed25519 root keypair, HKDF key hierarchy, AES-256-GCM envelope encryption, hash-chained audit log, passkey/FIDO2 hardware-backed keys. No recovery by design.

signet-cred

Credential issuance with authority protocol. SD-JWT VCs for interop, BBS+ for unlinkable selective disclosure, composable decay model (TTL, use count, rate limits, multi-phasic transitions), authority push/accept flow with Ed25519 double-signing, multi-authority chains, revocation.

signet-proof

Typestate proof pipeline. ProofRequest → ProofPlan → ProofBundle → BoundPresentation. 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

LayerStandardWhy
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 generationEd25519 + HKDF256-bit OsRng entropy. No seed phrase. No recovery.

Three commands to sovereignty.

1. Install & Initialize

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

# Create your vault (generates root keypair)
signet init
# Your signet_id: 283iRafkBsTcE1yFuvG4a3WYg3PE
# This is your identity. There is no recovery. Guard the key.

2. Import Authority-Issued Credentials

# Accept a credential pushed by a trusted authority
# Key = (authority, account) -- you see who attested what
signet credential accept \
  --authority "dmv.ca.gov" \
  --review               # inspect before accepting

# Or import a signed token directly
signet credential import < signed_credential.jwt

# The credential is signed by the DMV's Ed25519 key.
# When you prove "age > 21", the verifier checks the DMV's
# signature -- not your word for it.

3. Connect to Claude Desktop

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

Full setup guide →

Issue Capability Tokens

# Scoped, one-time capability derived from vault root
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 against the issuing authority
curl -X POST http://localhost:3000/verify \
  -H "Content-Type: application/json" \
  -d '{"proof": "...", "claim": {"attribute": "age_over_21"}}'

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.

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 Hierarchy

Ed25519 root keypair  (generated once from 256 bits entropy. No mnemonic. No recovery.)
 +-- VaultSealingKey  (HKDF: root + "vault-seal")
 |    +-- Per-record DEKs (HKDF: VSK + record_id)
 +-- CompartmentKeys  (HKDF: root + compartment_id)
 |    +-- Tier 3 DEKs  (NOT derivable from VSK -- structural isolation)
 +-- DeviceKeys        (HKDF: root + device_id)

There is no recovery mechanism. Lose the root key and everything is crypto-erased. That's the point — if it's recoverable, it's stealable. You know your own birthday. Your bank will re-issue credentials. GDPR compliance by mathematics, not by policy.

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

TierKey DerivationLoss ConsequenceUse Case
1HKDF(root + "tier1" + label)Re-derive from rootAuthority-attested proofs, preferences
2HKDF(root + "tier2" + label)Re-derive from rootAgent reasoning context, session data
3HKDF(root + compartment_id)Gone with rootPayment credentials, identity docs, medical

Lose the root key and all tiers are crypto-erased simultaneously. You know your own birthday — the DMV will re-issue the credential. Your credit card is in your wallet. Recovery is the enemy: if it's recoverable, it's stealable.

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.

1,050 tests. Zero unwrap() in library code. Clippy clean.

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