AI Agent Integration
Integrate Elydora into your AI agent workflows to create cryptographically signed, tamper-evident records of every autonomous action.
Why AI Agents Need Accountability
Autonomous AI agents make decisions and take actions without direct human oversight. In regulated industries — finance, healthcare, insurance — every agent action must be auditable. Elydora wraps each action in a signed Elydora Operation Record (EOR) that proves what the agent did, when it did it, and that the record has not been altered.
Supported AI Coding Tools
Elydora provides one-command installation for popular AI coding tools. The CLI installs a self-contained hook script that automatically records every tool use as a signed EOR — no code changes required.
One-Command Install
After registering an agent in the Elydora Console, run a single CLI command to configure your tool. The command writes a self-contained hook script and registers it with your tool's hook system. Choose your SDK:
npx @elydora/sdk install --agent claudecode \
--org_id "your_org_id" --agent_id "your_agent_id" \
--private_key "your_private_key" --kid "your_key_id" \
--token "your_api_token"pip install elydora && elydora install --agent claudecode \
--org_id "your_org_id" --agent_id "your_agent_id" \
--private_key "your_private_key" --kid "your_key_id" \
--token "your_api_token"go install github.com/Elydora-Infrastructure/Elydora-Go-SDK/cmd/elydora@latest && \
elydora install --agent claudecode \
--org_id "your_org_id" --agent_id "your_agent_id" \
--private_key "your_private_key" --kid "your_key_id" \
--token "your_api_token"Replace claudecode with the agent flag for your tool: claudecode, cursor, gemini, kirocli, kiroide, opencode, copilot, or letta. Other agents can integrate via the SDK directly.
The console pre-fills all credential flags after registration, so you can copy and paste the full command directly.
How It Works
The install command creates a per-agent directory at ~/.elydora/{agentId}/ and configures the following:
- Hook script (hook.js / hook.py) — A PostToolUse hook that fires after each tool call. Embeds all cryptographic logic (Ed25519 signing, SHA-256 hashing, chain hash computation) with zero runtime dependencies
- Guard script (guard.js / guard.py) — A PreToolUse hook that enforces agent freeze status. When an agent is frozen via the console, the guard rejects tool calls before they execute, preventing further autonomous actions until the freeze is lifted
- Agent config — Credentials stored at ~/.elydora/{agentId}/config.json with the Ed25519 private key in a separate private.key file (chmod 600)
- Chain state (chain-state.json) — Persists the most recent chain hash for this agent, ensuring each new EOR links to the previous one even across process restarts
- Tool registration — The hook and guard are registered in your tool's configuration (e.g. ~/.claude/settings.json for Claude Code)
- Fire-and-forget — The hook always exits 0. Audit logging never blocks your workflow. Errors are logged to ~/.elydora/{agentId}/error.log
Per-Agent Directory Structure
Each agent gets its own isolated directory under ~/.elydora/:
~/.elydora/{agentId}/
├── config.json # Agent configuration (org_id, agent_id, kid, token)
├── private.key # Ed25519 private key (chmod 600)
├── hook.js/.py # PostToolUse audit logging hook
├── guard.js/.py # PreToolUse freeze enforcement hook
├── chain-state.json # Per-agent chain hash persistence
├── status-cache.json # Freeze status cache (60s TTL)
└── error.log # Per-agent error logCross-Platform Paths
On macOS and Linux, the base directory is ~/.elydora/. On Windows, the SDK uses the user profile directory:
$env:USERPROFILE\.elydora\{agentId}\%USERPROFILE%\.elydora\{agentId}\The CLI automatically resolves the correct base path for the current platform. No manual path configuration is needed.
CLI Commands
# Install a hook for a supported tool
elydora install --agent <name> [--org_id <id>] [--agent_id <id>] \
[--private_key <key>] [--kid <kid>] [--token <token>]
# Remove the hook and clean up config
elydora uninstall --agent <name>
# Show installation status for all agents
elydora status
# List all supported agent names
elydora agentsSDK Integration
For AI tools that do not support hooks — such as OpenAI Codex, Kimi, custom enterprise agents, or GUI-based agents — integrate Elydora directly in your code using the SDK. The console provides a step-by-step tutorial with pre-filled credentials after agent registration.
Step 1: Install the SDK
# Node.js
npm install @elydora/sdk
# Python
pip install elydora
# Go
go get github.com/Elydora-Infrastructure/Elydora-Go-SDKStep 2: Initialize the Client
Create a client with the credentials from your agent registration. Store your private key and token in environment variables — never commit them to source control.
import { ElydoraClient } from '@elydora/sdk';
const client = new ElydoraClient({
orgId: process.env.ELYDORA_ORG_ID,
agentId: process.env.ELYDORA_AGENT_ID,
privateKey: process.env.ELYDORA_PRIVATE_KEY,
kid: process.env.ELYDORA_KID,
});
client.setToken(process.env.ELYDORA_TOKEN);import os
from elydora import ElydoraClient
client = ElydoraClient(
org_id=os.environ["ELYDORA_ORG_ID"],
agent_id=os.environ["ELYDORA_AGENT_ID"],
private_key=os.environ["ELYDORA_PRIVATE_KEY"],
token=os.environ["ELYDORA_TOKEN"],
)
client.set_kid(os.environ["ELYDORA_KID"])import (
"os"
elydora "github.com/Elydora-Infrastructure/Elydora-Go-SDK"
)
client, err := elydora.NewClient(&elydora.Config{
OrgID: os.Getenv("ELYDORA_ORG_ID"),
AgentID: os.Getenv("ELYDORA_AGENT_ID"),
PrivateKey: os.Getenv("ELYDORA_PRIVATE_KEY"),
Token: os.Getenv("ELYDORA_TOKEN"),
})Step 3: Record Operations
Before or after each tool call, decision, or action your agent takes, create a tamper-evident operation record (EOR).
const eor = client.createOperation({
operationType: 'ai.tool_use',
subject: { type: 'user', id: 'user-123' },
action: { tool: 'web_search', query: 'quarterly revenue' },
payload: { result: 'approved', confidence: 0.97 },
});
const { receipt } = await client.submitOperation(eor);
console.log('Recorded:', receipt.operation_id, 'seq:', receipt.seq_no);Step 4: Verify (Optional)
const result = await client.verifyOperation(receipt.operation_id);
console.log('Signature:', result.checks.signature); // 'valid'
console.log('Chain:', result.checks.chain); // 'valid'Integration Pattern
The core pattern is straightforward: wrap each agent action with an Elydora operation. Before the agent executes an action, create and submit a signed EOR. After Elydora returns an Elydora Acknowledgement Receipt (EAR), proceed with execution.
while agent is running:
action = agent.decide_next_action()
// 1. Create a signed EOR for the action
eor = elydora.create_operation(
operation_type: action.type,
subject: action.target,
action: action.name,
payload: action.parameters
)
// 2. Submit the EOR to Elydora
ear = elydora.submit_operation(eor)
// 3. Execute the action only after receiving the receipt
result = agent.execute(action)
// 4. Optionally verify the record
verification = elydora.verify_operation(ear.operation_id)Example: LLM Tool-Calling Agent
In an LLM-based agent that uses tool calling, each tool invocation is a natural unit of accountability. Log every tool call as an Elydora operation before executing it.
import { ElydoraClient } from '@elydora/sdk';
const client = new ElydoraClient({
orgId: 'org_acme',
agentId: 'agent_assistant',
privateKey: process.env.ELYDORA_KEY,
});
async function handleToolCall(toolName: string, args: Record<string, unknown>) {
// Create and submit a signed operation record before executing
const record = client.createOperation({
operationType: `tool.${toolName}`,
subject: { type: 'tool', id: toolName },
action: { name: 'invoke', type: 'tool_use' },
payload: { tool: toolName, arguments: args },
});
const { receipt } = await client.submitOperation(record);
// receipt contains the EAR with receipt_id, seq_no, chain_hash
// Now execute the tool call
const result = await executeTool(toolName, args);
return { result, operationId: receipt.operation_id };
}Raw API Equivalent
Under the hood, the SDK constructs a full EOR and sends it to POST /v1/operations. Here is what the raw request looks like:
curl -X POST https://api.elydora.com/v1/operations \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"op_version": 1,
"operation_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"org_id": "org_acme",
"agent_id": "agent_assistant",
"issued_at": "2026-02-28T14:30:00Z",
"ttl_ms": 30000,
"nonce": "x9k2m4p7q1w3",
"operation_type": "tool.search_database",
"subject": { "type": "database", "id": "customer_records" },
"action": { "name": "search", "type": "query" },
"payload": {
"tool": "search_database",
"arguments": { "query": "overdue accounts", "limit": 50 }
},
"payload_hash": "sha256:b5bb9d8014a0f9b1d61e21e796d78dc...",
"prev_chain_hash": "sha256:7d793037a0760186574b0282f2f435e7...",
"agent_pubkey_kid": "kid_ast_001",
"signature": "base64:ed25519-signature-bytes..."
}'Example: Multi-Agent System
In a multi-agent architecture, each agent has its own Ed25519 key pair and its own chain of operations. Register each agent separately, then instantiate a client per agent.
import { ElydoraClient } from '@elydora/sdk';
// Each agent gets its own client with its own key pair
const researchAgent = new ElydoraClient({
orgId: 'org_acme',
agentId: 'agent_researcher',
privateKey: process.env.RESEARCHER_KEY,
});
const reviewAgent = new ElydoraClient({
orgId: 'org_acme',
agentId: 'agent_reviewer',
privateKey: process.env.REVIEWER_KEY,
});
// Agent 1: Research agent finds and summarizes data
const researchRecord = researchAgent.createOperation({
operationType: 'research.summarize',
subject: { type: 'dataset', id: 'quarterly_reports' },
action: { name: 'summarize', type: 'analysis' },
payload: { source: 'quarterly_reports', findings: summaryData },
});
const { receipt: researchReceipt } = await researchAgent.submitOperation(researchRecord);
// Agent 2: Review agent evaluates the research
const reviewRecord = reviewAgent.createOperation({
operationType: 'review.evaluate',
subject: { type: 'operation', id: researchReceipt.operation_id },
action: { name: 'evaluate', type: 'review' },
payload: {
sourceOperationId: researchReceipt.operation_id,
decision: 'approved',
notes: 'Findings consistent with source data',
},
});
const { receipt: reviewReceipt } = await reviewAgent.submitOperation(reviewRecord);Registering Multiple Agents
Before agents can submit operations, register each one with its Ed25519 public key via POST /v1/agents/register.
# Register the research agent
curl -X POST https://api.elydora.com/v1/agents/register \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"agentId": "agent_researcher",
"publicKey": "MCowBQYDK2VwAyEA...",
"label": "Research Agent v1"
}'
# Register the review agent
curl -X POST https://api.elydora.com/v1/agents/register \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"agentId": "agent_reviewer",
"publicKey": "MCowBQYDK2VwAyEB...",
"label": "Review Agent v1"
}'EOR Field Reference
Every EOR submitted to Elydora contains these fields. The SDK auto-generates operation_id, issued_at, nonce, payload_hash, prev_chain_hash, and signature.
- op_version — Protocol version (currently 1)
- operation_id — Client-generated UUID v4
- org_id — Your organization identifier
- agent_id — The agent performing the action
- issued_at — ISO 8601 timestamp of creation
- ttl_ms — Maximum submission window in milliseconds
- nonce — Random value for replay protection
- operation_type — Domain-specific type (e.g. tool.search_database)
- subject — The entity or resource acted upon
- action — The action performed (e.g. search, approve)
- payload — Arbitrary JSON with operation-specific data
- payload_hash — SHA-256 hash of the canonicalized payload
- prev_chain_hash — Chain hash of the agent's previous operation (null for the first)
- agent_pubkey_kid — Key ID of the agent's Ed25519 signing key
- signature — Ed25519 signature over the canonical EOR
Next Steps
- Follow the Getting Started guide for a complete end-to-end walkthrough
- Read the EOR specification for full field semantics and canonical form rules
- Browse the Operations API for all available endpoints
- Set up RBAC roles to control which agents and users can perform which actions