Skip to content

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

bash
npm install @kanoniv/agent-auth

Version: 0.2.0 | Runtime: Node.js 18+ or modern browsers | License: MIT

Import Patterns

typescript
// 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.

typescript
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.

typescript
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).

typescript
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.

typescript
function generateKeyPair(): AgentKeyPair

keyPairFromBytes()

Reconstruct a keypair from a 32-byte secret key.

typescript
function keyPairFromBytes(secret: Uint8Array, createdAt?: string): AgentKeyPair

Throws CryptoError if secret.length !== 32.

computeDid()

Compute the DID string from public key bytes.

typescript
function computeDid(publicKeyBytes: Uint8Array): string

Format: did:agent:{hex(sha256(pubkey)[..16])} (32 hex characters).

identityFromBytes()

Create an AgentIdentity from raw 32-byte public key bytes.

typescript
function identityFromBytes(bytes: Uint8Array): AgentIdentity

Throws CryptoError if bytes.length !== 32.

identityFromMultibase()

Decode a multibase-encoded Ed25519 public key to an identity.

typescript
function identityFromMultibase(multibase: string): AgentIdentity

Expects format: z{base58btc(0xed01 + 32_bytes)}.

encodeMultibaseEd25519()

Encode an Ed25519 public key as multibase.

typescript
function encodeMultibaseEd25519(publicKeyBytes: Uint8Array): string

Returns z{base58btc(0xed01 + key)}.

didDocument()

Generate a W3C DID Document for an identity (no service endpoints).

typescript
function didDocument(identity: AgentIdentity): Record<string, unknown>

didDocumentWithServices()

Generate a W3C DID Document with service endpoints.

typescript
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.

typescript
function bytesToHex(bytes: Uint8Array): string

hexToBytes()

Convert a hex string to a Uint8Array.

typescript
function hexToBytes(hex: string): Uint8Array

Throws if the hex string has odd length.


Signing

Signed message envelopes with Ed25519 signatures.

SignedMessage (interface)

A cryptographically signed message envelope.

typescript
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.

typescript
function signMessage(keypair: AgentKeyPair, payload: unknown): SignedMessage

verifyMessage()

Verify a signed message against a known public identity. Throws CryptoError on failure.

typescript
function verifyMessage(message: SignedMessage, identity: AgentIdentity): void

contentHash()

Compute the SHA-256 content hash of a signed message. Uses canonical field ordering for cross-language determinism.

typescript
function contentHash(message: SignedMessage): string

Returns a 64-character hex string.


Delegation

Cryptographic delegation with attenuated capabilities.

Caveat (type)

A constraint on delegated authority. Tagged union on the type field.

typescript
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.

typescript
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.

typescript
interface Invocation {
  invoker_did: string;
  action: string;
  args: Record<string, unknown>;
  delegation: Delegation;
  proof: SignedMessage;
}

VerificationResult (interface)

Result of a successful verification.

typescript
interface VerificationResult {
  invoker_did: string;
  root_did: string;
  chain: string[];
  depth: number;
}

MAX_CHAIN_DEPTH

typescript
const MAX_CHAIN_DEPTH = 32;

createRootDelegation()

Create a root delegation (issuer is the root authority).

typescript
function createRootDelegation(
  issuerKeypair: AgentKeyPair,
  delegateDid: string,
  caveats: Caveat[],
): Delegation

delegateAuthority()

Create a delegated delegation with parent chain. Caveats accumulate - can only narrow authority, never widen.

typescript
function delegateAuthority(
  issuerKeypair: AgentKeyPair,
  delegateDid: string,
  additionalCaveats: Caveat[],
  parent: Delegation,
): Delegation

Throws if parent.delegate_did !== issuerKeypair.identity.did.

createInvocation()

Create an invocation exercising delegated authority.

typescript
function createInvocation(
  invokerKeypair: AgentKeyPair,
  action: string,
  args: Record<string, unknown>,
  delegation: Delegation,
): Invocation

Throws if delegation.delegate_did !== invokerKeypair.identity.did.

verifyInvocation()

Verify an invocation's full authority chain (no revocation check).

typescript
function verifyInvocation(
  invocation: Invocation,
  invokerIdentity: AgentIdentity,
  rootIdentity: AgentIdentity,
): VerificationResult

Throws CryptoError on failure.

verifyInvocationWithRevocation()

Verify with optional revocation callback. The callback receives a delegation's content hash and returns true if revoked.

typescript
function verifyInvocationWithRevocation(
  invocation: Invocation,
  invokerIdentity: AgentIdentity,
  rootIdentity: AgentIdentity,
  isRevoked: (hash: string) => boolean,
): VerificationResult

MCP

MCP (Model Context Protocol) authentication middleware.

McpProofData (interface)

A self-contained invocation proof for MCP transport.

typescript
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.

typescript
type McpAuthMode = "required" | "optional" | "disabled";

McpAuthOutcome (interface)

Result of MCP auth verification for a single tool call.

typescript
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.

typescript
McpProof.create(
  invokerKeypair: AgentKeyPair,
  action: string,
  args: Record<string, unknown>,
  delegation: Delegation,
): McpProofData

McpProof.extract()

Extract an MCP proof from tool arguments. Returns the proof (if present) and cleaned arguments with _proof stripped.

typescript
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.

typescript
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.

typescript
function verifyMcpCall(
  proof: McpProofData,
  rootIdentity: AgentIdentity,
): VerificationResult

verifyMcpCallWithRevocation()

Verify with optional revocation callback.

typescript
function verifyMcpCallWithRevocation(
  proof: McpProofData,
  rootIdentity: AgentIdentity,
  isRevoked: (hash: string) => boolean,
): VerificationResult

verifyMcpToolCall()

All-in-one MCP tool call verification. Combines proof extraction, verification, and argument cleaning. Respects auth mode.

typescript
function verifyMcpToolCall(
  toolName: string,
  args: Record<string, unknown>,
  rootIdentity: AgentIdentity,
  mode: McpAuthMode,
): McpAuthOutcome

verifyMcpToolCallWithRevocation()

All-in-one with revocation support.

typescript
function verifyMcpToolCallWithRevocation(
  toolName: string,
  args: Record<string, unknown>,
  rootIdentity: AgentIdentity,
  mode: McpAuthMode,
  isRevoked: (hash: string) => boolean,
): McpAuthOutcome

Provenance

Signed audit trail for agent actions.

ActionType (type)

Standard action types plus custom.

typescript
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.

typescript
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.

typescript
function createProvenanceEntry(
  keypair: AgentKeyPair,
  action: ActionType,
  entityIds: string[],
  parentIds: string[],
  metadata: unknown,
): ProvenanceEntry

verifyProvenanceEntry()

Verify a provenance entry: signature AND outer field integrity. Throws CryptoError on failure.

typescript
function verifyProvenanceEntry(
  entry: ProvenanceEntry,
  identity: AgentIdentity,
): void

verifyProvenanceSignatureOnly()

Verify only the cryptographic signature, without checking field integrity.

typescript
function verifyProvenanceSignatureOnly(
  entry: ProvenanceEntry,
  identity: AgentIdentity,
): void

provenanceContentHash()

Get the content hash of a provenance entry (usable as parent_id for chaining).

typescript
function provenanceContentHash(entry: ProvenanceEntry): string

Returns a 64-character hex string (SHA-256).


Error

CryptoError (class)

Extends Error with a code field for programmatic error handling.

typescript
class CryptoError extends Error {
  readonly code:
    | "INVALID_KEY_LENGTH"
    | "INVALID_PUBLIC_KEY"
    | "SIGNATURE_INVALID"
    | "INVALID_SIGNATURE_ENCODING"
    | "SERIALIZATION_ERROR";
}

Static factory methods:

typescript
CryptoError.invalidKeyLength(got: number): CryptoError
CryptoError.invalidPublicKey(): CryptoError
CryptoError.signatureInvalid(): CryptoError
CryptoError.invalidSignatureEncoding(detail: string): CryptoError
CryptoError.serializationError(detail: string): CryptoError

Full Export List

typescript
// 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 }

The identity and delegation layer for AI agents.