Loading vLEI.wiki
Fetching knowledge base...
Fetching knowledge base...
This comprehensive explanation has been generated from 94 GitHub source documents. All source documents are searchable here.
Last updated: October 7, 2025
This content is meant to be consumed by AI agents via MCP. Click here to get the MCP configuration.
Note: In rare cases it may contain LLM hallucinations.
For authoritative documentation, please consult the official GLEIF vLEI trainings and the ToIP Glossary.
Signify represents a fundamental architectural pattern in the KERI ecosystem that redistributes cryptographic operations between client and server components. Available in multiple programming languages including TypeScript (signify-ts), Python (signifypy), and Java (cf-signify-java), Signify implements what is called "signing at the edge" - a security model where the most sensitive cryptographic operations remain under direct user control on client devices.
The core design principle addresses a critical security requirement: cryptographic proofs should be verifiable and non-repudiable, which necessitates that signatures come directly from the controller's private keys rather than from intermediary infrastructure. This architectural decision fundamentally shapes how Signify interacts with cloud-based KERIA agents and other KERI infrastructure components.
Private Key Isolation: Signify's fundamental security property is that private keys exist only in client memory during signing operations. Implementations must never serialize keys to disk unencrypted, must clear keys from memory after use, and must ensure encrypted keys sent to KERIA use strong X25519 encryption with decryption keys never transmitted to the server.
Passcode Strength: The entire system's security depends on passcode (bran) strength. Generate random passcodes with 21+ characters of entropy, use Argon2 key stretching, never transmit passcodes over the network, and implement secure passcode entry mechanisms.
KRAM Authentication: All requests to KERIA must include KRAM headers with ISO-8601 timestamps within acceptable server time windows, signed request bodies including timestamps, and server-side validation of both signature and timestamp freshness.
Client-Agent Delegation: Signify operates in a cooperative delegation model where the Client AID (controlled by Signify) delegates to an Agent AID (managed by KERIA). Both parties must participate in all establishment events, enabling scalable operations while retaining ultimate control through rotation authority.
Asynchronous Operations: Most Signify operations are asynchronous due to network communication with KERIA, witness coordination (may take seconds), and cryptographic operations. Use async/await patterns consistently, provide operation polling mechanisms, implement timeout handling, and support operation cancellation.
Multi-Signature Coordination: For multi-sig identifiers, each participant signs with their portion of keys, signatures are collected asynchronously, events are only valid when threshold is met, and KERIA coordinates signature collection across potentially offline participants.
Caching Strategy: Cache resolved KELs locally, cache key state for frequently accessed AIDs, implement cache invalidation on rotation events, and use OOBI resolution results for subsequent verifications to reduce network overhead.
Operation Polling: Implement exponential backoff for operation polling, distinguish between retryable and permanent failures, provide detailed error messages, and clean up partial state on failures.
Unit Tests: Test cryptographic operations in isolation - key generation produces valid key pairs, signing produces verifiable signatures, CESR encoding/decoding round-trips correctly.
: Test client-agent interactions - boot and connect sequences complete successfully, AID creation and rotation work end-to-end, OOBI resolution discovers and verifies KELs, credential issuance and presentation flows work.
Signify is not a complete KERI implementation but rather a specialized client library that implements a specific subset of KERI agent functions. Traditional KERI agents perform five core functions:
Signify specifically implements key generation and event signing on the client side, while delegating event generation, encrypted storage coordination, and validation to remote KERIA agents. This separation ensures that private keys never need to be transmitted to or accessed by cloud infrastructure, maintaining the non-repudiable property essential to KERI's security model.
The fundamental capability of Signify is performing cryptographic operations at the edge - on the user's device rather than on remote servers. This includes:
Key Pair Generation: Signify uses libsodium as its cryptographic foundation, generating two types of asymmetric key pairs:
For both inception events (identifier creation) and rotation events (key updates), Signify generates new key pair sets containing current keys and next keys (for pre-rotation). Critically, only the public keys and blake3 hashes of the next keys are transmitted to the agent, maintaining the security boundary.
Event Signing: All key events and other KERI protocol messages requiring signatures are signed client-side using the controller's private keys. The signed events are then transmitted to the KERIA agent for dissemination to witnesses and storage in the KEL.
While private keys never leave the client in unencrypted form, Signify supports encrypted key storage on remote KERIA agents. The encryption uses X25519 key pairs, and the critical security property is that the cloud agent never has access to the decryption keys. This enables:
The encrypted storage includes:
Signify communicates with KERIA agents using CESR (Composable Event Streaming Representation) encoding. The initial implementations encode all cryptographic primitives as CESR base64 encoded strings in the text domain, though the architecture supports future binary CESR encoding for improved efficiency.
This protocol choice ensures:
Signify operates within a cooperative delegation architecture where:
This delegation enables:
Signify uses a passcode (called bran in KERI terminology) as the entropy source for deterministic key generation. The key generation algorithm:
signify:controller00 for signing keys)This approach enables:
Prerequisites:
Installation:
npm install signify-ts
Basic Setup:
import { randomPasscode, ready, SignifyClient, Tier } from 'signify-ts';
// Initialize libsodium (required before any operations)
await ready();
// Generate a random passcode
const bran = randomPasscode();
// Create client instance
const client = new SignifyClient(
'http://127.0.0.1:3901', // KERIA admin URL
bran, // passcode for key derivation
Tier.low, // security tier
'http://127.0.0.1:3903' // KERIA boot URL
);
The ready() function must be called at application initialization because the dependency libsodium must be initialized before any signify-ts functionalities can work.
Prerequisites:
Installation:
pip install signifypy
Basic Setup: The Python implementation follows similar patterns to the TypeScript version, using the same underlying cryptographic libraries and CESR encoding.
Prerequisites:
Installation:
./gradlew build
The Java implementation provides equivalent functionality for JVM-based applications, using libsodium through native bindings.
All Signify implementations require a running KERIA agent. The agent exposes three HTTP interfaces:
Signify clients connect to the Admin and Boot interfaces, while the Protocol interface handles external KERI communications.
The Signify client initialization follows a multi-step process:
Step 1: Create SignifyClient Instance
const client = new SignifyClient(
adminUrl, // KERIA admin interface URL
bran, // passcode for key derivation
tier, // security tier (low, med, high)
bootUrl // KERIA boot interface URL
);
Step 2: Boot the Agent
await client.boot();
This initializes the KERIA agent connection and prepares for AID operations.
Step 3: Connect and Establish Delegation
await client.connect();
This establishes the Client AID to Agent AID delegation relationship through a three-step handshake:
Creating a New AID:
const result = await client.identifiers().create(
'my-identifier', // alias for the AID
{
toad: 3, // threshold of accountable duplicity
wits: [ // witness AIDs
'witness1-aid',
'witness2-aid',
'witness3-aid'
]
}
);
// Wait for operation completion
const op = await client.operations().wait(result.op);
The creation process:
Key Rotation:
const rotateResult = await client.identifiers().rotate(
'my-identifier' // alias of AID to rotate
);
await client.operations().wait(rotateResult.op);
Rotation demonstrates Signify's security model:
Out-of-Band Introductions enable discovery and trust establishment:
Generating an OOBI:
const oobi = await client.oobis().get(
'my-identifier', // AID alias
'agent' // role (typically 'agent' for KERIA)
);
// Returns URL like: http://keria:3902/oobi/{aid}/agent/{agent-aid}
Resolving an OOBI:
const resolveResult = await client.oobis().resolve(
oobiUrl, // OOBI URL to resolve
'remote-alias' // local alias for the discovered AID
);
await client.operations().wait(resolveResult.op);
OOBI resolution:
Issuing a Credential:
const issueResult = await client.credentials().issue(
'issuer-aid', // issuing AID alias
registryId, // credential registry SAID
schemaId, // schema SAID
recipientAid, // issuee AID
attributes // credential attributes
);
await client.operations().wait(issueResult.op);
Presenting a Credential:
const presentResult = await client.ipex().grant(
'holder-aid', // presenting AID alias
'verifier-aid', // recipient AID
credentialSaid, // credential to present
includeChain // include chained credentials
);
Credential operations demonstrate the edge signing model:
Signify supports challenge-response protocols for proving control:
Generating a Challenge:
const challenge = await client.challenges().generate(
'my-aid', // AID to challenge
recipientAid // who should respond
);
Responding to a Challenge:
const response = await client.challenges().respond(
'my-aid', // responding AID
challengeData // challenge to respond to
);
The challenge-response flow:
KERIA is the complementary server-side component that Signify clients connect to. While Signify handles edge signing, KERIA provides:
KERIA exposes REST APIs that Signify clients use for all non-signing operations.
KERIpy is the reference Python implementation of the complete KERI protocol. Unlike Signify, KERIpy:
Signifypy is built on KERIpy's cryptographic primitives but provides a simplified client-focused API.
The signify-browser-extension provides a browser-based wallet using Signify:
This enables MetaMask-like functionality for KERI-based identity management.
Rust: While there is no direct Signify implementation in Rust, cesride provides CESR primitives that could support a Rust Signify client.
Go: No official Signify implementation exists, though the CESR specification enables implementation in any language.
Swift: KERIml provides Swift KERI primitives that could support iOS Signify clients.
Private Key Isolation: The fundamental security property of Signify is that private keys exist only in client memory during signing operations. Implementations must ensure:
Passcode Strength: The security of the entire system depends on the passcode (bran) strength. Implementations should:
Replay Attack Protection: All requests to KERIA must include KRAM (KERI Request Authentication Method) headers:
Asynchronous Operations: Most Signify operations are asynchronous because they involve:
Implementations should:
Caching: To reduce network overhead:
Signify supports multi-signature identifiers where multiple parties must coordinate:
Partial Signing: When a multi-sig event is created:
Threshold Configuration: Multi-sig AIDs specify:
Operation Failures: Signify operations can fail at multiple points:
Implementations should:
Witness Agreement: Operations requiring witness agreement may fail if:
Clients should implement timeout and retry logic appropriate for their use case.
Unit Tests: Test cryptographic operations in isolation:
Integration Tests: Test client-agent interactions:
End-to-End Tests: Test complete workflows:
Web Applications: Signify-ts can run in browsers:
Mobile Applications: Signify can integrate with mobile apps:
Desktop Applications: Signify works in Electron or native apps:
Server-Side: While Signify is designed for edge signing, server-side use cases exist:
Server deployments must carefully manage key security and access control.
End-to-End Tests: Test complete workflows - multi-party credential exchanges, challenge-response authentication, multi-signature coordination, error recovery scenarios.
Web Applications: Use WebAssembly for libsodium, store encrypted keys in IndexedDB, use Service Workers for background operations, implement secure passcode entry.
Mobile Applications: Use platform secure storage (Keychain, Keystore), implement biometric authentication, handle background/foreground transitions, manage network connectivity changes.
Desktop Applications: Use OS credential storage, implement auto-lock mechanisms, support hardware security modules, provide backup/restore functionality.
Server-Side: While designed for edge signing, server-side use cases exist for automated credential issuance, service-to-service authentication, batch operations, and testing. Server deployments must carefully manage key security and access control.