Loading...
private.me Docs
Get xTrust
PRIVATE.ME PLATFORM

xTrust: Trust Registry & Key Verification

Trust-on-first-use, mutual key verification ceremonies, append-only transparency logs, and continuity-proven key rotation. xTrust makes identity binding automatic, auditable, and tamper-evident.

Identity & Trust AVAILABLE NOW XorIDA Powered
Section 01

The Problem

Every secure channel starts with one question: whose key is this? Get the answer wrong and nothing that follows matters — encryption protects the wrong conversation.

Conventional PKI solves identity binding with certificate authorities. But CAs are centralized trust anchors. One compromised CA invalidates every certificate it ever issued. The 2011 DigiNotar breach, the 2015 CNNIC incident, and the ongoing Let's Encrypt phishing certificate problem all demonstrate the same structural failure: delegated trust collapses at scale.

PGP's Web of Trust tried to decentralize the problem but created its own: key signing parties, manual fingerprint comparison, incomprehensible trust paths, and a UX so hostile that even security researchers get it wrong. After three decades, PGP adoption among non-specialists remains negligible.

Modern messengers like Signal improved the UX with safety numbers, but the verification model is still manual, optional, and per-conversation. Most users never verify. When a contact changes devices, Signal silently accepts the new key with a small notification that most users dismiss.

Key rotation makes everything worse. When a user gets a new phone, their old key pair is gone. Every contact must re-verify. Most systems handle this by silently accepting the new key — the exact behavior an attacker would exploit. Without cryptographic continuity proofs, there is no way to distinguish a legitimate device change from a man-in-the-middle attack.

The Old Way

Contact Key Accept blindly No verification CENTRAL CA Single trust root Compromise = total loss MITM Undetected
Section 02

The PRIVATE.ME Solution

xTrust replaces centralized certificate authorities with a four-layer trust stack: automatic TOFU registration, mutual SAS verification ceremonies, append-only transparency logs, and continuity-proven key rotation.

When a contact's public key is first encountered, xTrust accepts it automatically with TOFU (Trust on First Use) trust level and records the event in a SHA-256 hash-chained transparency log. If the key is seen again, it matches. If a different key appears for the same identity, xTrust raises a FINGERPRINT_CONFLICT warning — the cryptographic equivalent of "this person's identity has changed."

Trust can be upgraded from tofu to verified via a mutual key verification ceremony. Both parties derive a 6-word Short Authentication String (SAS) from their fingerprints using HMAC-SHA256. They compare the SAS over a separate channel (in person, phone, video). If the words match, the key binding is cryptographically confirmed.

When keys rotate (new device, scheduled rotation, key compromise), the old private key signs the new public key to create a continuity proof. Contacts can verify the rotation was authorized by the key holder, not a MITM attacker. A configurable grace period (default 7 days) accepts both old and new keys during transition.

Every trust-relevant event — key registration, SAS verification, rotation, revocation — is recorded in an append-only transparency log where each entry is SHA-256 hash-chained to the previous. Tampering with any entry breaks the chain. Auditors can verify the complete key history for any contact without accessing message content or key material.

The New Way

First Contact TOFU accept Log Entry SHA-256 chain SAS Verify 6-word phrase Verified Tamper-evident
Section 03

Architecture

Four modules, each handling one dimension of trust. They compose together but each works independently.

Module 1: TofuManager

Manages trust-on-first-use for contacts. When processKey(email, fingerprint) is called, TofuManager checks its in-memory contact map. New keys are accepted with tofu trust level. Matching keys return the existing trust state. Changed keys return FINGERPRINT_CONFLICT — the application decides whether to warn the user or auto-reject. Trust can be upgraded to verified via upgradeTrust(email, fingerprint) after a successful verification ceremony.

Module 2: Key Verification Ceremony

Implements QR code + Short Authentication String (SAS) verification for mutual key confirmation. Both parties' public key fingerprints are computed via SHA-256, then fed into HMAC-SHA256 to derive a 6-word human-readable SAS from a 256-word PGP-style wordlist. A challenge is created with a 15-minute TTL, a unique ID from crypto.getRandomValues(), and QR data encoding both fingerprints. Both parties compare the SAS phrase over a separate channel. If they match, the key binding is confirmed.

The SAS wordlist uses a PGP-style approach where each byte maps to one of 256 words (e.g., "aardvark", "arctic", "beacon", "cipher", "glacier"). Six words provide 48 bits of entropy — enough for a human to compare in under 10 seconds. The probability of a MITM attacker guessing the correct SAS is 1 in 281 trillion.

Module 3: KeyTransparencyLog

Append-only cryptographic log where every key event (registration, rotation, verification, revocation) is recorded with a SHA-256 hash chain linking each entry to the previous one. Each entry contains the contact email, public key fingerprint, action type, timestamp, and optional metadata. verifyChain(contactEmail) walks the chain and confirms every previousEntryHash is correct. If any entry has been tampered with, the chain breaks.

Module 4: KeyRotationManager

Handles key rotation with continuity proofs. When a contact rotates their key pair, the old private key signs the new public key using ML-DSA-65 (FIPS 204 post-quantum signature). The initiateRotation() method verifies the continuity proof, computes fingerprints for both keys, logs the event to the transparency log, and starts a configurable grace period (default 7 days). During the grace period, both the old and new fingerprints are accepted by isAccepted().

TofuManager unknown → tofu → verified Key Verification SAS + QR ceremony TransparencyLog SHA-256 hash chain KeyRotationManager Continuity proof + grace Trust Registry Composable modules xBind Agent SDK Channel auth xFuse Pipeline Identity fusion xID Wallet DID binding
Key Security Properties
SHA-256 fingerprints for key identity. HMAC-SHA256 for SAS derivation and log chaining. ML-DSA-65 (FIPS 204) continuity proofs for key rotation. crypto.getRandomValues() for all random data. Result<T, E> pattern for typed error handling. No exceptions thrown in library code.
Section 04

Competitive Failure Analysis

Every trust model makes tradeoffs. Here is where each one fails — and how xTrust avoids the same failure modes.

SystemTrust ModelKey RotationTransparencyUX BurdenFailure Mode
PGP Web of Trust Transitive signatures Manual revocation × None Key signing parties Unusable for non-experts
Signal Protocol TOFU + safety numbers Silent accept × None Manual QR scan (optional) Key changes silently accepted
Matrix / Vodozemac Cross-signing + TOFU Device-level × None Emoji verification Complex device trust graph
X.509 / PKI Centralized CA hierarchy Certificate renewal CT logs None (delegated) CA compromise = total breach
Certificate Transparency Append-only CA logs N/A (audit only) Merkle tree Monitor-only Detects but does not prevent
xTrust TOFU + SAS + transparency Continuity proof + grace SHA-256 chain 6-word phrase (optional) See Limitations section
Why It Matters
PGP requires users to understand trust graphs. Signal accepts key changes silently. X.509 centralizes failure. Certificate Transparency detects but cannot prevent. xTrust combines automatic TOFU (zero-friction onboarding), optional SAS verification (when you need certainty), append-only transparency (tamper detection), and continuity-proven rotation (safe key changes). The user never needs to understand PKI — the system handles the hard part.
Section 05

Benchmarks

Trust operations are fast enough to be invisible. Key lookups are sub-microsecond. Verification ceremonies complete in milliseconds. Transparency log audits scale linearly with chain length.

OperationLatencyNotes
TOFU key lookup< 0.1 msIn-memory Map<string, ContactTrust>
TOFU key registration< 1 msMap insert + transparency log append
SHA-256 fingerprint~50 µsWeb Crypto exportKey + digest
SAS derivation (HMAC-SHA256)~80 µsHMAC of concatenated fingerprints
Challenge creation~200 µs2 fingerprints + SAS + QR data
Transparency log append~100 µsSHA-256 hash chain link
Chain verification (100 entries)~10 msLinear scan with hash recomputation
Chain verification (1,000 entries)~95 msOne SHA-256 per entry
ML-DSA-65 continuity sign~2 msOld key signs new key SPKI
ML-DSA-65 continuity verify~0.5 msVerify signature on new key SPKI
Key rotation initiation~3 msVerify + fingerprint + log + record
Grace period check< 0.1 msIn-memory array scan + Date.now()

Measured on commodity hardware (4-core, 3.2 GHz). Web Crypto API for SHA-256 and HMAC. ML-DSA-65 via mldsa-wasm. All operations single-threaded.

< 0.1 ms
Trust lookup
~80 µs
SAS derivation
~10 ms
100-entry audit
~3 ms
Key rotation
Section 06

ACI Surface

Eight core functions organized into four modules. Every function returns Result<T, TrustError> or a simple value — no exceptions thrown.

TofuManager

processKey(email: string, fingerprint: string): Promise<Result<ContactTrust, TrustError>>
Accept a contact's key on first encounter (TOFU), confirm match on subsequent encounters, or raise FINGERPRINT_CONFLICT if the key has changed.
upgradeTrust(email: string, fingerprint: string): Promise<Result<ContactTrust, TrustError>>
Promote a contact from tofu to verified trust level after a successful SAS verification ceremony. Logs the event to the transparency log.

Key Verification

computeFingerprint(publicKey: CryptoKey): Promise<string>
Compute the SHA-256 fingerprint of a public key by exporting its SPKI representation and hashing the raw bytes. Returns a hex string.
deriveSas(fingerprintA: string, fingerprintB: string): Promise<string>
Derive a 6-word Short Authentication String from two fingerprints via HMAC-SHA256. Each byte maps to a word from the 256-word PGP-style wordlist.
createChallenge(initiatorEmail, responderEmail, initiatorKey, responderKey): Promise<Result<VerificationChallenge, TrustError>>
Create a verification challenge with SAS phrase, QR data, fingerprints, and a 15-minute TTL. Challenge ID generated via crypto.getRandomValues().

Transparency Log

KeyTransparencyLog.append(contactEmail, fingerprint, action, metadata?): Promise<Result<KeyTransparencyEntry, TrustError>>
Append a key event to the hash-chained transparency log. Each entry's SHA-256 hash links to the previous entry for the same contact. Actions: key_registered, key_rotated, key_verified, key_revoked.
KeyTransparencyLog.verifyChain(contactEmail): Promise<Result<true, TrustError>>
Walk the hash chain for a contact and verify every previousEntryHash matches the recomputed SHA-256 of the prior entry. Returns LOG_CORRUPTED if any link is broken.

Key Rotation

KeyRotationManager.initiateRotation(contactEmail, oldPublicKey, newPublicKey, continuitySignature): Promise<Result<KeyRotationRecord, TrustError>>
Verify an ML-DSA-65 continuity proof (old key signed new key), compute fingerprints, log the rotation event, and start a 7-day grace period where both keys are accepted.
Section 07

Use Cases

🔐
Secure Messaging
Contact Key Verification

Automatically register contact keys on first encounter. Upgrade to verified trust via in-person SAS comparison. Detect key changes that could indicate MITM attacks.

TOFU + SAS
🗄
Audit & Compliance
Key History Audit Trail

Every key event is recorded in a tamper-evident transparency log. Auditors can verify the complete key history for any contact without accessing message content.

Transparency Log
🔄
Key Management
Safe Key Rotation

Rotate keys with cryptographic continuity proofs. The old key signs the new key, proving the rotation is authorized. Grace periods prevent message loss during transition.

Continuity Proof
🤖
Machine-to-Machine
Service Identity Binding

Bind DID-based service identities to their signing keys. TOFU accepts the first key per DID, transparency logs record every rotation, and automated SAS can be verified programmatically.

M2M Trust
Legal
Evidence Chain of Custody

Prove that encryption keys used for legal holds were the correct keys for the stated identities. Transparency logs provide an immutable record of key provenance.

Legal Hold
🏥
Healthcare
Provider Identity Verification

Verify that the public key used to encrypt patient data belongs to the stated healthcare provider. SAS ceremonies can be conducted during onboarding. Key rotation is logged for HIPAA audits.

HIPAA Audit
Section 08

Regulatory Alignment

xTrust addresses key management requirements across major compliance frameworks. The transparency log provides the audit trail that regulators demand.

FrameworkRequirementxTrust Control
eIDAS 2.0 Qualified trust service provider key management TOFU + SAS verification ceremony. Hash-chained transparency log for key lifecycle audit.
NIST SP 800-57 Key management lifecycle (generation, distribution, rotation, destruction) Full lifecycle coverage: registration (processKey), verification (SAS), rotation (continuity proof), revocation (transparency log action).
NIST SP 800-63 Digital identity assurance levels (IAL/AAL/FAL) TOFU provides IAL1. SAS verification provides IAL2-equivalent out-of-band confirmation. Continuity proofs maintain assurance across key rotation.
DORA (EU) ICT risk management: cryptographic key controls and audit trails Append-only transparency log with SHA-256 chain. verifyChain() for integrity audit. All key events timestamped and immutable.
SOC 2 Type II CC6.1 Logical access controls, CC6.6 External threats Key verification ceremony for access binding. FINGERPRINT_CONFLICT detection for threat alerting. Grace period rotation for continuity.
ISO 27001 A.10 Cryptographic controls, A.14 System acquisition Web Crypto API for SHA-256 and HMAC-SHA256. ML-DSA-65 (FIPS 204) via mldsa-wasm for continuity proofs. No custom primitives.
HIPAA 164.312(a) Access control, 164.312(e) Transmission security Key identity verification before encrypted data exchange. Transparency log provides audit trail for key provenance.
Section 09

Cross-ACI Integration

xTrust is the identity binding layer that other ACIs depend on. When an ACI needs to know whose key it is talking to, xTrust provides the answer.

xBind (Agent SDK)

Every xBind channel begins with a DID handshake. xTrust's TofuManager registers the remote DID's signing key on first connection. Subsequent connections verify the key matches. If the remote agent rotates their key, the continuity proof is verified before the channel is established. The transparency log records every key event for every xBind peer.

xFuse (Threshold Identity Fusion)

xFuse's verify step in the 5-stage pipeline calls xTrust to confirm that each signal provider's key is trusted before accepting their identity signals. A FINGERPRINT_CONFLICT from xTrust halts the pipeline — the system will not fuse identity signals from an unverified source.

xID (Digital Identity)

xID's ephemeral DIDs are derived from a master seed, but verifiers need to confirm the DID belongs to the claimed identity. xTrust's transparency log records the binding between each DID and the master public key. When a DID rotates (epoch-based), the continuity proof is logged and the grace period prevents verification failures during transition.

xGate (Rate Limiting)

xGate's PerDidLimiter uses DID identifiers as rate limit keys. xTrust resolves whether a DID is trusted, verified, or unknown — enabling different rate limits per trust level. Verified contacts might get higher limits while TOFU contacts get stricter throttling.

xLock (Push Authentication)

xLock's push-based 1-tap authentication relies on device key binding. xTrust's TOFU registration accepts the device key on first setup. When a user gets a new device, the old device signs the new device's key via xTrust's continuity proof, allowing a seamless device transition without requiring the user to re-verify on every service.

Cross-ACI: xBind + xTrust
import { TofuManager, KeyTransparencyLog } from '@private.me/xtrust';
import { Agent } from '@private.me/xbind';

// Initialize trust registry
const log = new KeyTransparencyLog();
const tofu = new TofuManager(log);

// On xBind channel open, verify remote agent's key
const result = await tofu.processKey(
  remoteDid,
  remoteFingerprint
);

if (!result.ok) {
  // FINGERPRINT_CONFLICT: key changed unexpectedly
  throw new Error(`Trust violation: ${result.error.message}`);
}
Section 10

Security Properties

PropertyMechanismGuarantee
Key identitySHA-256 fingerprint (SPKI export) Collision-resistant binding
Mutual verificationHMAC-SHA256 SAS (6-word phrase) Out-of-band confirmation
Tamper detectionSHA-256 hash chain Any modification breaks chain
Rotation continuityML-DSA-65 signature (FIPS 204, post-quantum) Old key authorizes new key
Random generationcrypto.getRandomValues() CSPRNG for IDs and challenges
Key change detectionFINGERPRINT_CONFLICT error MITM warning on key swap
Challenge expiration15-minute TTL Time-bounded verification
Error handlingResult<T, TrustError> No thrown exceptions in library
SHA-256
Fingerprint + chain
HMAC
SAS derivation
ML-DSA-65
Continuity proof
15 min
Challenge TTL
Threat Model
xTrust assumes the attacker can intercept and modify network traffic (active MITM). TOFU provides protection on first contact (SSH-like). SAS verification defeats active MITM by using a separate channel. The transparency log detects retroactive tampering. Continuity proofs prevent unauthorized key rotation. The system does not protect against a compromised local device — if the attacker controls the machine running xTrust, they can bypass all protections.
VERIFIABLE WITHOUT CODE EXPOSURE

Ship Proofs, Not Source

xTrust generates cryptographic proofs of correct execution without exposing proprietary algorithms. Verify integrity using zero-knowledge proofs — no source code required.

XPROVE CRYPTOGRAPHIC PROOF
Download proofs:

Verify proofs online →

Use Cases

REGULATORY
FDA / SEC Submissions
Prove algorithm correctness for distributed systems without exposing trade secrets or IP.
Zero IP Exposure
FINANCIAL
Audit Without Access
External auditors verify secure operations without accessing source code or production systems.
FINRA / SOX Compliant
DEFENSE
Classified Verification
Security clearance holders verify distributed systems correctness without clearance for source code.
CMMC / NIST Ready
ENTERPRISE
Procurement Due Diligence
Prove security + correctness during RFP evaluation without NDA or code escrow.
No NDA Required
Section 11

Honest Limitations

xTrust is a trust registry, not a replacement for all PKI. Understanding its boundaries helps you deploy it correctly.

LimitationDetailMitigation
In-memory storage TofuManager, KeyTransparencyLog, and KeyRotationManager all use in-memory data structures (Map, arrays). Data is lost on process restart. Enterprise CLI (trust-cli) provides persistent JSONL storage with replay-on-init. Client applications should serialize to encrypted storage.
No federation The transparency log is local. There is no protocol for federating logs across organizations or comparing independent logs for the same contact. Future: gossip protocol for cross-organization log comparison. Today: export via getAllEntries() and manual comparison.
Discrete trust levels Trust is binary: tofu or verified. There is no continuous trust score, no decay over time, and no partial trust. Pair with xFuse for continuous trust scoring (IAL1/IAL2/IAL3) based on multiple identity signals.
SAS requires OOB channel Upgrading from TOFU to verified requires both parties to compare a 6-word phrase over a separate channel (phone, in-person, video). This requires coordination. TOFU is sufficient for most use cases. SAS verification is needed only when MITM protection is critical. Automated SAS is possible for M2M via secondary authenticated channels.
Log growth The transparency log grows linearly with key events. For contacts with frequent key rotations, the log can become large. verifyChain() scans every entry. Prune completed chains to summary checkpoints. Archive old entries. trust-cli provides JSONL compaction on rotation.
Signature scheme agility Continuity proofs use ML-DSA-65 (FIPS 204). The signing module is isolated behind a typed interface, so the scheme can be swapped (for example to ML-DSA-87) without changing the registry format. Future migration runs as a module swap: log entries change, transparency log format does not.
No revocation broadcast When a key is revoked (logged as key_revoked), remote parties are not automatically notified. They will only discover the revocation on next contact. Pair with xBind for real-time revocation notification via signed DID messages to all known peers.
Section 12

Enterprise HTTP Server

A turn-key HTTP server that wraps the xTrust core for organizations needing a managed, multi-team trust registry. One binary launches the listener, replays state from append-only JSONL stores, enforces three RBAC roles, and exposes the full xTrust capability surface as REST — with a hash-chained transparency log behind every endpoint.

The SDK described above is exactly right inside one application. It is exactly the wrong shape when an entire enterprise needs to share one canonical key registry. Multi-team deployments break the in-memory model: contact A's TOFU registration in the trading-desk app is invisible to the compliance app two floors down, library calls cannot be audited from the outside, and key history disappears on process restart. The Enterprise HTTP Server solves all three by lifting @private.me/xtrust into a single long-running process with persistent storage, RBAC, and an HTTP query surface auditors can point at.

When to choose Server vs SDK
Pick the SDK (@private.me/xtrust) when trust state lives inside one application's process. Pick the Server when multiple teams, services, or tenants need to share one canonical key registry — or when auditors require a query surface that survives restarts. Both ship from the same core; the server adds HTTP, RBAC, persistence, and rate limiting.

Architecture

A thin HTTP layer over the xTrust core, backed by five JSONL stores and gated by three RBAC roles. No database. No external dependency. One process. Inbound requests pass through three middleware layers: API-key authentication, role-based authorization, and per-key rate limiting (1000 requests per minute by default). Every endpoint delegates to the underlying library — TofuManager for key registration, KeyTransparencyLog for the append-only audit chain, KeyRotationManager for continuity-proven rotation, and the SAS verification helpers for mutual key confirmation. The server adds nothing to the cryptographic story; it only wraps it.

State persists across restarts via append-only JSONL files. On boot, each file is replayed into an in-memory Map for sub-millisecond reads. On every write, the new record is appended to disk before the in-memory map is updated, so a crash never leaves the maps ahead of the log. The data directory is the database.

HTTP Listener :3700 REST + JSON RBAC Middleware admin / operator / auditor Rate Limiter 1000 req/min per key Audit Log Append-only JSONL xTrust Core TOFU + Log + Rotation keys.jsonl DID + public key api_keys.jsonl SHA-256 hashes + roles transparency.jsonl Merkle log entries rotations.jsonl Old → new key history audit.jsonl Operation audit trail
:3700
Default port
3 roles
admin / operator / auditor
5 stores
JSONL append-only
1000 / min
Per-key rate limit

Technical Highlights

PropertyHow It WorksWhy It Matters
Merkle-tree transparency log Every key event (register, rotate, revoke) is appended to transparency.jsonl with a SHA-256 hash linking to the previous entry. Merkle commitments are computed across batches for compact proofs. An auditor can prove a specific key event was recorded at a specific point in time without scanning the full log.
RBAC with three roles admin (full control), operator (register / rotate / verify), auditor (read-only). API keys are SHA-256 hashed before storage; only the hash hits disk. Compliance teams can hand auditors read-only credentials without exposing operational ability. Bootstrap key is single-use.
Append-only JSONL persistence Five log files: keys, api_keys, transparency, rotations, audit. Every write is an append. Every boot replays the log into memory. No update-in-place anywhere. Logs are forensically clean. Backup is cp -r. Recovery is “start the binary.” Tampering with history requires editing a file with hash chains in it.
Identity-system integration Endpoints accept DIDs (did:key, did:web) as identifiers and base64-encoded public keys as payloads. Existing identity providers register their issued keys via API. The trust registry slots into your existing IAM stack instead of replacing it. SSO, SCIM, and IdM systems remain authoritative for who; the server becomes authoritative for which key.
Post-quantum upgrade path Continuity proofs use ML-DSA-65 (FIPS 204), so xTrust is post-quantum out of the box. The signing module is isolated behind a typed interface, so future schemes (ML-DSA-87, hybrid constructions) can be substituted without changing the registry format. The transparency log itself is hash-based and already PQ-friendly. You do not need to migrate the registry to upgrade the signature scheme — the log entries change, the format does not.

REST Endpoints

Eleven endpoints organized into five capability groups. Every request is authenticated by API key, authorized by role, and rate-limited per key.

Health

GET /health
Liveness probe. Returns { status: "ok" }. Unauthenticated. Useful for load balancers and Kubernetes liveness checks.

Key Registration & Verification

POST /keys · operator+
Register a public key for a DID using TOFU. First registration succeeds; subsequent registrations for the same DID with a different key require a rotation.
GET /keys/:did · auditor+
Look up the current registered public key for a DID. Returns the trust level (tofu or verified) and registration timestamp.
POST /keys/:did/verify · operator+
Promote a contact from tofu to verified after a successful out-of-band SAS comparison. Logs the verification to the transparency log.

Key Rotation

POST /rotations · operator+
Initiate a key rotation with a continuity proof. The old private key signs the new public key; the server verifies the signature, logs the event, and starts a configurable grace period during which both keys are accepted.
GET /rotations · auditor+
List rotation history across all DIDs. Filter by DID, time window, or initiator. Used by compliance teams to reconstruct who rotated which key when.

Transparency Log

GET /transparency · auditor+
Read the full append-only transparency log. Each entry includes the previous-entry hash for chain verification. Pagination via ?after=.
GET /transparency/:did · auditor+
Read every transparency entry for a single DID — the complete key lifecycle. The response is the raw evidence an auditor needs.
GET /transparency/proof/:entryId · auditor+
Return a Merkle inclusion proof for a specific log entry. Lets an auditor confirm an entry was present at a given log size without downloading the full chain.

RBAC Management

POST /api-keys · admin only
Issue a new API key with a specified role. The plaintext key is returned once; only the SHA-256 hash is persisted. Lost keys cannot be recovered — rotate.
GET /api-keys · admin only
List API key metadata (id, role, created timestamp, last-used timestamp). Plaintext keys are never returned. Used to audit who has what level of access.
DELETE /api-keys/:id · admin only
Revoke an API key. Subsequent requests authenticated with the revoked key return 401 UNAUTHORIZED. The revocation is recorded in the audit log.

RBAC Model

Three roles, one bootstrap key, and SHA-256 hashing for every credential at rest. The principle is least privilege by default.

RoleCan doCannot do
admin Issue and revoke API keys, register and rotate keys, read everything Nothing — admin is the root role
operator Register new keys (TOFU), verify keys (SAS), initiate rotations, read transparency log Issue or revoke API keys, modify the audit trail
auditor Read keys, transparency log, rotation history, audit trail Modify any state. All endpoints are GET-only for this role.
Bootstrap flow
On first launch, the server reads TRUST_ADMIN_KEY from the environment, hashes it with SHA-256, and stores only the hash. The plaintext is then discarded by the process. From that point forward, the bootstrap key authenticates as admin until it is rotated through POST /api-keys and DELETE /api-keys/:id. Operator and auditor keys are issued by an admin and never appear in the environment.

Enterprise Use Cases

Enterprise IT
Multi-Team Key Registry

One trust server shared across engineering, security, and compliance teams. Every team queries the same canonical key state. No per-application drift.

Shared Trust Anchor
Regulated Industry
Audit-Grade Key History

Auditors query the transparency log directly through read-only credentials. Every key registration, verification, rotation, and revocation has a timestamp, an actor, and a Merkle inclusion proof.

SOC 2 / DORA / HIPAA
Air-Gapped Deployment
Classified & Restricted Networks

Zero outbound network requirements. Single binary, single port, single data directory. Runs in environments where SaaS trust services are prohibited by policy.

No Egress
Identity Platform
DID Key Directory

Bind every DID issued by your identity platform to its current signing key. Track rotations across the lifetime of the identity. Provide verifiers with one place to look.

DID Authoritative
Service Mesh
Service-to-Service Trust

Service identities (workload DIDs) register their signing keys on first deployment via TOFU. Rotations on redeploy carry continuity proofs. The mesh has one place to ask “is this the right key for service X?”

Workload Identity
Compliance Operations
Read-Only Audit Surface

Hand external auditors an auditor-role API key. They can read the transparency log, rotation history, and audit trail without any ability to alter state. Revoke the key when the engagement ends.

External Audit

Deployment

One binary, one data directory, one port. Container-friendly. Air-gap-friendly.

Environment
# Required
export TRUST_ADMIN_KEY=$(openssl rand -hex 32)

# Optional (defaults shown)
export TRUST_PORT=3700
export TRUST_DATA_DIR=./data
export TRUST_LOG_FORMAT=json
export TRUST_MERKLE_ALGORITHM=sha256
Launch
# Install
pnpm add @private.me/xtrust

# Start the server
xtrust serve --port 3700 --data ./data

# Output
Trust server listening on port 3700
Data directory: ./data
Admin API key configured
Docker (air-gapped)
docker run -d \
  --name xtrust \
  -p 3700:3700 \
  -v /var/data/trust:/app/data \
  -e TRUST_ADMIN_KEY=<bootstrap-key> \
  -e TRUST_LOG_FORMAT=json \
  privateme/xtrust:latest
Register a DID's key
curl -X POST http://localhost:3700/keys \
  -H "Authorization: Bearer $TRUST_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"did":"did:key:z6MkUser","publicKey":"<base64>"}'
Backup & Recovery
Backup is cp -r /var/data/trust /backup/. Recovery is cp -r /backup/trust /var/data/ followed by xtrust serve. The data directory is the database; there is nothing else to back up.

Server Security Properties

PropertyMechanismGuarantee
API key storageSHA-256 hashed before persistence Plaintext never written to disk
Bootstrap admin keyRead from env, hashed on first run, plaintext discarded Single-point credential
Transparency integritySHA-256 hash chain + Merkle commitments Tampering detectable end-to-end
Rate limiting1000 requests / minute per API key Per-credential isolation
AuthorizationThree RBAC roles enforced per endpoint Least privilege by default
Random generationNode.js crypto.randomBytes CSPRNG for IDs and challenges
PersistenceAppend-only JSONL with replay-on-init No update-in-place; forensically clean
Network footprintOne inbound port; zero outbound calls Air-gap deployable
Server Threat Model
The Enterprise Server assumes the operator controls the host running it. An attacker with shell access to the data directory can append fabricated entries, but the previous-hash chain and Merkle commitments will fail verification at the next audit. The server does not protect against a malicious admin — an admin can issue API keys at any role. RBAC is for separation of duties among trusted operators, not for defense against root.

Server Limitations

LimitationDetailMitigation
Single-process design One node serves the registry. Horizontal scale requires either active-passive failover or partitioning by tenant. For typical enterprise volume, one node handles peak load comfortably. Run a hot standby reading the same data directory for HA.
No federation The transparency log is local to the deployment. Cross-organization log comparison is not built in. Export transparency.jsonl for offline comparison. Federation protocol planned for a future release.
JSONL log growth Append-only stores grow without bound. A high-rotation environment can produce a large transparency log over multi-year horizons. Periodic compaction to checkpoint summaries. Off-line archive of older entries with Merkle root snapshots.
Signature scheme lock-in Default continuity proofs use ML-DSA-65 (FIPS 204). The signing module is isolated, so the scheme can be swapped without changing the registry format, but a coordinated migration is still required across all SDK consumers. Plan the signature-scheme upgrade as a module-swap event across SDK versions. The log entries change shape; the transparency log format does not.
No revocation broadcast Revoked keys are recorded, but remote consumers learn of the revocation only on their next read. Pair with xBind for real-time signed revocation messages to known peers.
Air-Gapped Deployment
The Enterprise Server requires zero external network access. All cryptographic operations use Node.js built-in crypto. JSONL stores are local files. The server runs on a single port with no outbound connections. Ideal for classified environments, financial trading floors, and healthcare facilities that cannot allow outbound network traffic.
VERIFIED BY XPROVE

Verifiable Trust Operations

Every trust operation in this ACI produces a verifiable audit trail via xProve. HMAC-chained integrity proofs let auditors confirm that keys were registered, verified, and rotated correctly — without accessing the keys themselves.

XPROVE AUDIT TRAIL
Every TOFU registration, SAS verification, and key rotation generates HMAC-SHA256 integrity tags. xProve chains these into a tamper-evident audit trail that proves trust operations were handled correctly at every step. Upgrade to zero-knowledge proofs when regulators or counterparties need public verification without exposing key material.

Read the xProve white paper →
GET STARTED

Ready to deploy xTrust?

Talk to Sol, our AI platform engineer, or book a live demo with our team.

Quick Start
import {
  TofuManager,
  KeyTransparencyLog,
  KeyRotationManager,
  createChallenge,
  computeFingerprint,
  deriveSas,
} from '@private.me/xtrust';

// Initialize the trust stack
const log = new KeyTransparencyLog();
const tofu = new TofuManager(log);
const rotation = new KeyRotationManager(log);

// Register a contact's key (TOFU)
const fp = await computeFingerprint(contactPublicKey);
const trust = await tofu.processKey(
  'alice@example.com',
  fp
);
// trust.value.trustLevel === 'tofu'

// Upgrade to verified via SAS ceremony
const challenge = await createChallenge(
  'bob@example.com',
  'alice@example.com',
  myPublicKey,
  contactPublicKey
);
// challenge.value.shortAuthString === "arctic comet glacier..."
// Compare over phone/video, then:
await tofu.upgradeTrust('alice@example.com', fp);
// trust.value.trustLevel === 'verified'
Book a Demo

Deployment Options

SaaS Recommended

Fully managed infrastructure. Call our REST API, we handle scaling, updates, and operations.

  • Zero infrastructure setup
  • Automatic updates
  • 99.9% uptime SLA
  • Pay per use
View Pricing →

SDK Integration

Embed directly in your application. Runs in your codebase with full programmatic control.

  • npm install @private.me/xtrust
  • TypeScript/JavaScript SDK
  • Full source access
  • Enterprise support available
Get Started →

On-Premise Enterprise

Self-hosted infrastructure for air-gapped, compliance, or data residency requirements.

  • Complete data sovereignty
  • Air-gap capable
  • Docker + Kubernetes ready
  • RBAC + audit logs included
Enterprise CLI →

Pricing

Three tiers priced by managed contacts — the active trust relationships your deployment maintains. Free for real production deployments under 1,000 contacts. Pro for growing deployments. Enterprise for regulated and federated scale. See private.me/pricing for current rates.

FREE
Up to 1,000
managed contacts
Always free
Production-ready — small SaaS, AI agent prototypes, regional networks
  • ✓ All xTrust capabilities
  • ✓ TOFU registration & SAS ceremony
  • ✓ Transparency log (90-day retention)
  • ✓ Key rotation with continuity proofs
  • ✓ In-memory storage (SDK)
  • ✓ Community support
Start Free
No credit card required
POPULAR
PRO
Beyond 1,000
managed contacts
see private.me/pricing for current rates
Scales linearly — predictable per-contact pricing up to 50,000
  • Everything in Free, plus:
  • ✓ Persistent JSONL storage
  • ✓ Basic RBAC
  • ✓ Hosted transparency log
  • ✓ Email support (24h business-day SLA)
  • ✓ Soft cap at 50,000 contacts
Upgrade to Pro
Pay only for contacts above the Free tier
ENTERPRISE
Custom
pricing
Contact sales
Regulated & federated scale — sovereignty, compliance, on-premises
  • Everything in Pro, plus:
  • ✓ 50,000+ managed contacts
  • ✓ Federation across deployments
  • ✓ Air-gapped / on-premises deployment
  • ✓ BAA / DPA pass-through
  • ✓ 7-year transparency log retention
  • ✓ Full RBAC & auto-archival policies
  • ✓ Dedicated CSM & custom SLA

What counts as a managed contact

A managed contact is any DID with at least one entry in the xTrust transparency log, in Active, Dormant, or Revoked state. DIDs you explicitly archive after dormancy review stop counting toward the limit; transparency log history is preserved.

xTrust prices by maintained trust relationships, not per-operation throughput. A typical relationship involves 1 registration, 0–1 verification ceremonies, a handful of rotations, and 0–1 revocations — the value is in the relationship itself, not the call volume.

Questions about pricing or commercial use? Contact sales
API Reference

Purchase Endpoint

Programmatic subscription creation via REST API. Supports both email-based and xBind identity-based purchases.

Endpoint

HTTP Request
POST https://private.me/api/aci/checkout

Request Body

TypeScript — Purchase Request Schema
interface PurchaseRequest {
  // Product identification (required)
  productId: 'xtrust';
  tier: 'pro' | 'enterprise';

  // Customer identification (one required)
  email?: string;              // Email-based purchase
  did?: string;                // xBind identity-based purchase

  // Optional metadata
  metadata?: Record<string, string>;
}

Response

TypeScript — Success Response (201 Created)
interface PurchaseResponse {
  checkoutUrl: string;         // Stripe Checkout session URL
  sessionId: string;           // Stripe session ID
  expiresAt: string;           // ISO 8601 timestamp
}

Error Response (RFC 7807)

All errors follow RFC 7807 Problem Details for HTTP APIs format.

TypeScript — Error Response Schema
interface ProblemDetails {
  type: string;                // URI identifying the problem type
  title: string;               // Human-readable summary
  status: number;              // HTTP status code
  detail?: string;             // Detailed explanation
  instance?: string;           // URI reference to specific occurrence
}

Common Error Codes:

  • 400 Bad Request — Invalid productId, tier, or missing identification
  • 401 Unauthorized — Invalid or expired xBind signature
  • 429 Too Many Requests — Rate limit exceeded (60/min for xBind, 10/min for email)
  • 500 Internal Server Error — Stripe API failure or server error

Example: Email-Based Purchase

TypeScript — Basic Purchase Request
const response = await fetch('https://private.me/api/aci/checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    productId: 'xtrust',
    tier: 'pro',
    email: 'user@example.com'
  })
});

const { checkoutUrl } = await response.json();
// Redirect user to checkoutUrl for payment
window.location.href = checkoutUrl;

Example: xBind Identity Purchase

TypeScript — Agent-Based Purchase
import { Agent } from '@private.me/xbind';

// Create agent identity
const agent = await Agent.quickstart({ name: 'purchase-agent' });

// Purchase using agent DID (email optional)
const envelope = await agent.send(
  'did:web:private.me',
  {
    productId: 'xtrust',
    tier: 'pro',
    did: agent.did
    // email optional - fallback generated if missing
  }
);

const response = await fetch('https://private.me/api/aci/checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(envelope)
});

const { checkoutUrl } = await response.json();
// Higher rate limit: 60/min (vs 10/min for email-based)
Rate Limits

Email-based: 10 requests/min per IP address
xBind identity: 60 requests/min per DID (6× faster, prevents impersonation)