TypeScript SDK - @kanoniv/agent-auth
Cryptographic identity and delegation for AI agents. Pure TypeScript implementation using @noble/ed25519 for Ed25519 operations. Cross-language compatible with the Rust and Python SDKs - signed messages and content hashes are deterministic across all three.
Installation
npm install @kanoniv/agent-authVersion: 0.2.0 | Runtime: Node.js 18+ or modern browsers | License: MIT
Import Patterns
// Named imports (recommended)
import { generateKeyPair, signMessage, verifyMessage } from "@kanoniv/agent-auth";
// Import types separately
import type { AgentIdentity, AgentKeyPair, SignedMessage } from "@kanoniv/agent-auth";
// Import everything
import * as agentAuth from "@kanoniv/agent-auth";Identity
Agent cryptographic identity - Ed25519 keypairs and did:agent: identifiers.
AgentIdentity (interface)
Public identity derived from a keypair - safe to share and store.
interface AgentIdentity {
/** Decentralized identifier: did:agent:{hex(sha256(pubkey)[..16])} */
did: string;
/** Raw public key bytes (32 bytes, Ed25519) */
publicKeyBytes: Uint8Array;
/** When this key was created (RFC 3339, if known) */
createdAt?: string;
}AgentKeyPair (interface)
An agent's Ed25519 keypair.
interface AgentKeyPair {
/** 32-byte secret key */
secretKey: Uint8Array;
/** Derived public identity */
identity: AgentIdentity;
}ServiceEndpoint (interface)
A service endpoint for a DID Document (W3C DID Core).
interface ServiceEndpoint {
/** Fragment ID (e.g. "#messaging") or full URI */
id: string;
/** Service type (e.g. "AgentMessaging", "KanonivResolve") */
serviceType: string;
/** The endpoint URL */
endpoint: string;
}generateKeyPair()
Generate a new random Ed25519 keypair with current timestamp.
function generateKeyPair(): AgentKeyPairkeyPairFromBytes()
Reconstruct a keypair from a 32-byte secret key.
function keyPairFromBytes(secret: Uint8Array, createdAt?: string): AgentKeyPairThrows CryptoError if secret.length !== 32.
computeDid()
Compute the DID string from public key bytes.
function computeDid(publicKeyBytes: Uint8Array): stringFormat: did:agent:{hex(sha256(pubkey)[..16])} (32 hex characters).
identityFromBytes()
Create an AgentIdentity from raw 32-byte public key bytes.
function identityFromBytes(bytes: Uint8Array): AgentIdentityThrows CryptoError if bytes.length !== 32.
identityFromMultibase()
Decode a multibase-encoded Ed25519 public key to an identity.
function identityFromMultibase(multibase: string): AgentIdentityExpects format: z{base58btc(0xed01 + 32_bytes)}.
encodeMultibaseEd25519()
Encode an Ed25519 public key as multibase.
function encodeMultibaseEd25519(publicKeyBytes: Uint8Array): stringReturns z{base58btc(0xed01 + key)}.
didDocument()
Generate a W3C DID Document for an identity (no service endpoints).
function didDocument(identity: AgentIdentity): Record<string, unknown>didDocumentWithServices()
Generate a W3C DID Document with service endpoints.
function didDocumentWithServices(
identity: AgentIdentity,
services: ServiceEndpoint[],
): Record<string, unknown>Fragment IDs starting with # are auto-prefixed with the DID.
bytesToHex()
Convert a Uint8Array to a lowercase hex string.
function bytesToHex(bytes: Uint8Array): stringhexToBytes()
Convert a hex string to a Uint8Array.
function hexToBytes(hex: string): Uint8ArrayThrows if the hex string has odd length.
Signing
Signed message envelopes with Ed25519 signatures.
SignedMessage (interface)
A cryptographically signed message envelope.
interface SignedMessage {
/** The message payload (arbitrary JSON) */
payload: unknown;
/** DID of the signer */
signer_did: string;
/** UUID v4 nonce for replay protection */
nonce: string;
/** RFC 3339 timestamp (milliseconds, Z suffix) */
timestamp: string;
/** Hex-encoded Ed25519 signature (128 hex chars) */
signature: string;
}signMessage()
Sign a payload with the given keypair.
function signMessage(keypair: AgentKeyPair, payload: unknown): SignedMessageverifyMessage()
Verify a signed message against a known public identity. Throws CryptoError on failure.
function verifyMessage(message: SignedMessage, identity: AgentIdentity): voidcontentHash()
Compute the SHA-256 content hash of a signed message. Uses canonical field ordering for cross-language determinism.
function contentHash(message: SignedMessage): stringReturns a 64-character hex string.
Delegation
Cryptographic delegation with attenuated capabilities.
Caveat (type)
A constraint on delegated authority. Tagged union on the type field.
type Caveat =
| { type: "action_scope"; value: string[] }
| { type: "expires_at"; value: string }
| { type: "max_cost"; value: number }
| { type: "resource"; value: string }
| { type: "context"; value: { key: string; value: string } }
| { type: "custom"; value: { key: string; value: unknown } };Delegation (interface)
A cryptographic delegation of authority.
interface Delegation {
issuer_did: string;
delegate_did: string;
/** Issuer's public key (hex-encoded) for self-verifying chains */
issuer_public_key: string;
caveats: Caveat[];
parent_proof: Delegation | null;
proof: SignedMessage;
}Invocation (interface)
An agent exercising delegated authority.
interface Invocation {
invoker_did: string;
action: string;
args: Record<string, unknown>;
delegation: Delegation;
proof: SignedMessage;
}VerificationResult (interface)
Result of a successful verification.
interface VerificationResult {
invoker_did: string;
root_did: string;
chain: string[];
depth: number;
}MAX_CHAIN_DEPTH
const MAX_CHAIN_DEPTH = 32;createRootDelegation()
Create a root delegation (issuer is the root authority).
function createRootDelegation(
issuerKeypair: AgentKeyPair,
delegateDid: string,
caveats: Caveat[],
): DelegationdelegateAuthority()
Create a delegated delegation with parent chain. Caveats accumulate - can only narrow authority, never widen.
function delegateAuthority(
issuerKeypair: AgentKeyPair,
delegateDid: string,
additionalCaveats: Caveat[],
parent: Delegation,
): DelegationThrows if parent.delegate_did !== issuerKeypair.identity.did.
createInvocation()
Create an invocation exercising delegated authority.
function createInvocation(
invokerKeypair: AgentKeyPair,
action: string,
args: Record<string, unknown>,
delegation: Delegation,
): InvocationThrows if delegation.delegate_did !== invokerKeypair.identity.did.
verifyInvocation()
Verify an invocation's full authority chain (no revocation check).
function verifyInvocation(
invocation: Invocation,
invokerIdentity: AgentIdentity,
rootIdentity: AgentIdentity,
): VerificationResultThrows CryptoError on failure.
verifyInvocationWithRevocation()
Verify with optional revocation callback. The callback receives a delegation's content hash and returns true if revoked.
function verifyInvocationWithRevocation(
invocation: Invocation,
invokerIdentity: AgentIdentity,
rootIdentity: AgentIdentity,
isRevoked: (hash: string) => boolean,
): VerificationResultMCP
MCP (Model Context Protocol) authentication middleware.
McpProofData (interface)
A self-contained invocation proof for MCP transport.
interface McpProofData {
invocation: Invocation;
/** The invoker's Ed25519 public key (hex-encoded, 64 chars) */
invoker_public_key: string;
}McpAuthMode (type)
MCP auth mode for server configuration.
type McpAuthMode = "required" | "optional" | "disabled";McpAuthOutcome (interface)
Result of MCP auth verification for a single tool call.
interface McpAuthOutcome {
/** Verification result if proof was present and valid */
verified: VerificationResult | null;
/** Tool arguments with _proof stripped */
args: Record<string, unknown>;
}McpProof (object)
Namespace object with static methods for creating, extracting, and injecting MCP proofs.
McpProof.create()
Create an MCP proof for a tool call.
McpProof.create(
invokerKeypair: AgentKeyPair,
action: string,
args: Record<string, unknown>,
delegation: Delegation,
): McpProofDataMcpProof.extract()
Extract an MCP proof from tool arguments. Returns the proof (if present) and cleaned arguments with _proof stripped.
McpProof.extract(
args: Record<string, unknown>,
): { proof: McpProofData | null; cleanArgs: Record<string, unknown> }McpProof.inject()
Inject a proof into tool arguments. Returns a new object with _proof added.
McpProof.inject(
proof: McpProofData,
args: Record<string, unknown>,
): Record<string, unknown>verifyMcpCall()
Verify an MCP proof against a root authority. Reconstructs the invoker identity from the embedded public key.
function verifyMcpCall(
proof: McpProofData,
rootIdentity: AgentIdentity,
): VerificationResultverifyMcpCallWithRevocation()
Verify with optional revocation callback.
function verifyMcpCallWithRevocation(
proof: McpProofData,
rootIdentity: AgentIdentity,
isRevoked: (hash: string) => boolean,
): VerificationResultverifyMcpToolCall()
All-in-one MCP tool call verification. Combines proof extraction, verification, and argument cleaning. Respects auth mode.
function verifyMcpToolCall(
toolName: string,
args: Record<string, unknown>,
rootIdentity: AgentIdentity,
mode: McpAuthMode,
): McpAuthOutcomeverifyMcpToolCallWithRevocation()
All-in-one with revocation support.
function verifyMcpToolCallWithRevocation(
toolName: string,
args: Record<string, unknown>,
rootIdentity: AgentIdentity,
mode: McpAuthMode,
isRevoked: (hash: string) => boolean,
): McpAuthOutcomeProvenance
Signed audit trail for agent actions.
ActionType (type)
Standard action types plus custom.
const ACTION_TYPES = [
"resolve", "merge", "split", "mutate",
"ingest", "delegate", "revoke",
] as const;
type ActionType = (typeof ACTION_TYPES)[number] | { custom: string };ACTION_TYPES (constant)
Array of the 7 standard action type strings.
ProvenanceEntry (interface)
A signed provenance entry in the audit chain.
interface ProvenanceEntry {
agent_did: string;
action: ActionType;
entity_ids: string[];
parent_ids: string[];
metadata: unknown;
signed_envelope: SignedMessage;
}createProvenanceEntry()
Create and sign a new provenance entry.
function createProvenanceEntry(
keypair: AgentKeyPair,
action: ActionType,
entityIds: string[],
parentIds: string[],
metadata: unknown,
): ProvenanceEntryverifyProvenanceEntry()
Verify a provenance entry: signature AND outer field integrity. Throws CryptoError on failure.
function verifyProvenanceEntry(
entry: ProvenanceEntry,
identity: AgentIdentity,
): voidverifyProvenanceSignatureOnly()
Verify only the cryptographic signature, without checking field integrity.
function verifyProvenanceSignatureOnly(
entry: ProvenanceEntry,
identity: AgentIdentity,
): voidprovenanceContentHash()
Get the content hash of a provenance entry (usable as parent_id for chaining).
function provenanceContentHash(entry: ProvenanceEntry): stringReturns a 64-character hex string (SHA-256).
Error
CryptoError (class)
Extends Error with a code field for programmatic error handling.
class CryptoError extends Error {
readonly code:
| "INVALID_KEY_LENGTH"
| "INVALID_PUBLIC_KEY"
| "SIGNATURE_INVALID"
| "INVALID_SIGNATURE_ENCODING"
| "SERIALIZATION_ERROR";
}Static factory methods:
CryptoError.invalidKeyLength(got: number): CryptoError
CryptoError.invalidPublicKey(): CryptoError
CryptoError.signatureInvalid(): CryptoError
CryptoError.invalidSignatureEncoding(detail: string): CryptoError
CryptoError.serializationError(detail: string): CryptoErrorFull Export List
// Identity
export { type AgentIdentity, type AgentKeyPair, type ServiceEndpoint }
export { generateKeyPair, keyPairFromBytes, computeDid }
export { identityFromBytes, identityFromMultibase, encodeMultibaseEd25519 }
export { didDocument, didDocumentWithServices }
export { bytesToHex, hexToBytes }
// Signing
export { type SignedMessage }
export { signMessage, verifyMessage, contentHash }
// Delegation
export { type Caveat, type Delegation, type Invocation, type VerificationResult }
export { MAX_CHAIN_DEPTH }
export { createRootDelegation, delegateAuthority, createInvocation }
export { verifyInvocation, verifyInvocationWithRevocation }
// MCP
export { type McpProofData, type McpAuthMode, type McpAuthOutcome }
export { McpProof }
export { verifyMcpCall, verifyMcpCallWithRevocation }
export { verifyMcpToolCall, verifyMcpToolCallWithRevocation }
// Provenance
export { type ActionType, type ProvenanceEntry }
export { ACTION_TYPES }
export { createProvenanceEntry, verifyProvenanceEntry, verifyProvenanceSignatureOnly }
export { provenanceContentHash }
// Error
export { CryptoError }