Update README with full API reference and CLI docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
dbf7ded348
commit
deab4ebe1b
1 file changed
+167
-35
@@ -1,6 +1,6 @@
|
|||||||
# @elydora/sdk
|
# Elydora Node SDK
|
||||||
|
|
||||||
Node.js/TypeScript SDK for the Elydora tamper-evident audit platform.
|
Official Node.js/TypeScript SDK for the [Elydora](https://elydora.com) tamper-evident audit platform. Build cryptographically verifiable audit trails for AI agent operations.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -15,10 +15,10 @@ Requires Node.js 18+ (uses built-in `crypto` module with Ed25519 support).
|
|||||||
```typescript
|
```typescript
|
||||||
import { ElydoraClient } from '@elydora/sdk';
|
import { ElydoraClient } from '@elydora/sdk';
|
||||||
|
|
||||||
// 1. Authenticate
|
// Authenticate
|
||||||
const auth = await ElydoraClient.login('https://api.elydora.com', 'user@example.com', 'password');
|
const auth = await ElydoraClient.login('https://api.elydora.com', 'user@example.com', 'password');
|
||||||
|
|
||||||
// 2. Create client
|
// Create client
|
||||||
const client = new ElydoraClient({
|
const client = new ElydoraClient({
|
||||||
orgId: auth.user.org_id,
|
orgId: auth.user.org_id,
|
||||||
agentId: 'my-agent-id',
|
agentId: 'my-agent-id',
|
||||||
@@ -27,7 +27,7 @@ const client = new ElydoraClient({
|
|||||||
});
|
});
|
||||||
client.setToken(auth.token);
|
client.setToken(auth.token);
|
||||||
|
|
||||||
// 3. Create and submit an operation
|
// Create and submit an operation
|
||||||
const eor = client.createOperation({
|
const eor = client.createOperation({
|
||||||
operationType: 'data.access',
|
operationType: 'data.access',
|
||||||
subject: { user_id: 'u-123', resource: 'patient-record' },
|
subject: { user_id: 'u-123', resource: 'patient-record' },
|
||||||
@@ -39,48 +39,180 @@ const { receipt } = await client.submitOperation(eor);
|
|||||||
console.log('Operation submitted:', receipt.operation_id);
|
console.log('Operation submitted:', receipt.operation_id);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
The SDK includes a CLI for installing audit hooks into AI coding agents.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx elydora install \
|
||||||
|
--agent claudecode \
|
||||||
|
--org_id org-123 \
|
||||||
|
--agent_id agent-456 \
|
||||||
|
--private_key <key> \
|
||||||
|
--kid agent-456-key-v1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `elydora install` | Install Elydora audit hook for a coding agent |
|
||||||
|
| `elydora uninstall` | Remove Elydora audit hook for a coding agent |
|
||||||
|
| `elydora status` | Show installation status for all agents |
|
||||||
|
| `elydora agents` | List supported coding agents |
|
||||||
|
|
||||||
|
### Supported Agents
|
||||||
|
|
||||||
|
| Agent | Key |
|
||||||
|
|-------|-----|
|
||||||
|
| Claude Code | `claudecode` |
|
||||||
|
| Cursor | `cursor` |
|
||||||
|
| Gemini CLI | `gemini` |
|
||||||
|
| Augment Code | `augment` |
|
||||||
|
| Kiro | `kiro` |
|
||||||
|
| OpenCode | `opencode` |
|
||||||
|
|
||||||
## API Reference
|
## API Reference
|
||||||
|
|
||||||
### Static Methods
|
### Configuration
|
||||||
|
|
||||||
- `ElydoraClient.register(baseUrl, email, password, displayName?, orgName?)` — Register a new user and organization
|
```typescript
|
||||||
- `ElydoraClient.login(baseUrl, email, password)` — Authenticate and receive a JWT
|
const client = new ElydoraClient({
|
||||||
|
orgId: string, // Organization ID
|
||||||
|
agentId: string, // Agent ID
|
||||||
|
privateKey: string, // Base64url-encoded Ed25519 seed
|
||||||
|
baseUrl?: string, // API base URL (default: https://api.elydora.com)
|
||||||
|
ttlMs?: number, // Operation TTL in ms (default: 30000)
|
||||||
|
maxRetries?: number, // Max retries on transient failures (default: 3)
|
||||||
|
kid?: string, // Key ID (default: {agentId}-key-v1)
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
### Instance Methods
|
### Authentication
|
||||||
|
|
||||||
#### Agent Management
|
```typescript
|
||||||
- `registerAgent(request)` — Register a new agent with public keys
|
// Register a new user and organization
|
||||||
- `getAgent(agentId)` — Retrieve agent details
|
const reg = await ElydoraClient.register(baseUrl, email, password, displayName?, orgName?);
|
||||||
- `freezeAgent(agentId, reason)` — Freeze an agent
|
|
||||||
- `revokeKey(agentId, kid, reason)` — Revoke an agent key
|
|
||||||
|
|
||||||
#### Operations
|
// Login and receive a JWT
|
||||||
- `createOperation(params)` — Construct and sign an EOR locally (synchronous)
|
const auth = await ElydoraClient.login(baseUrl, email, password);
|
||||||
- `submitOperation(eor)` — Submit a signed EOR to the API
|
|
||||||
- `getOperation(operationId)` — Retrieve an operation
|
|
||||||
- `verifyOperation(operationId)` — Verify operation integrity
|
|
||||||
|
|
||||||
#### Audit
|
// Set token on client
|
||||||
- `queryAudit(params)` — Query the audit log
|
client.setToken(auth.token);
|
||||||
|
```
|
||||||
|
|
||||||
#### Epochs
|
### Operations
|
||||||
- `listEpochs()` — List all epochs
|
|
||||||
- `getEpoch(epochId)` — Retrieve an epoch
|
|
||||||
|
|
||||||
#### Exports
|
```typescript
|
||||||
- `createExport(params)` — Create a compliance export
|
// Create a signed EOR locally (synchronous, no network call)
|
||||||
- `listExports()` — List all exports
|
const eor = client.createOperation({
|
||||||
- `getExport(exportId)` — Retrieve export status
|
operationType: 'inference',
|
||||||
|
subject: { model: 'gpt-4' },
|
||||||
|
action: { type: 'completion' },
|
||||||
|
payload: { prompt: 'Hello' },
|
||||||
|
});
|
||||||
|
|
||||||
#### JWKS
|
// Submit to API
|
||||||
- `getJWKS()` — Retrieve platform public keys
|
const { receipt } = await client.submitOperation(eor);
|
||||||
|
|
||||||
## Cryptographic Details
|
// Retrieve an operation
|
||||||
|
const op = await client.getOperation(operationId);
|
||||||
|
|
||||||
- **Ed25519**: Signs operations using Node.js built-in `crypto` module
|
// Verify integrity (signature, chain, receipt, merkle)
|
||||||
- **Chain hashing**: `SHA-256(prev_chain_hash | payload_hash | operation_id | issued_at)`
|
const result = await client.verifyOperation(operationId);
|
||||||
- **JCS**: RFC 8785 JSON Canonicalization Scheme for deterministic serialization
|
```
|
||||||
- **Base64url**: RFC 4648 section 5, no padding
|
|
||||||
|
### Agent Management
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Register a new agent
|
||||||
|
const agent = await client.registerAgent({
|
||||||
|
agent_id: 'my-agent',
|
||||||
|
display_name: 'My Agent',
|
||||||
|
responsible_entity: 'team@example.com',
|
||||||
|
keys: [{ kid: 'key-v1', public_key: '<base64url>', algorithm: 'ed25519' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get agent details
|
||||||
|
const details = await client.getAgent(agentId);
|
||||||
|
|
||||||
|
// Freeze an agent
|
||||||
|
await client.freezeAgent(agentId, 'security review');
|
||||||
|
|
||||||
|
// Revoke a key
|
||||||
|
await client.revokeKey(agentId, kid, 'key rotation');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audit
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const results = await client.queryAudit({
|
||||||
|
agent_id: 'agent-123',
|
||||||
|
operation_type: 'inference',
|
||||||
|
start_time: Date.now() - 86400000,
|
||||||
|
end_time: Date.now(),
|
||||||
|
limit: 50,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Epochs
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const { epochs } = await client.listEpochs();
|
||||||
|
const { epoch } = await client.getEpoch(epochId);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exports
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const { export: exp } = await client.createExport({
|
||||||
|
start_time: Date.now() - 86400000,
|
||||||
|
end_time: Date.now(),
|
||||||
|
format: 'json',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { exports } = await client.listExports();
|
||||||
|
const { export: detail, download_url } = await client.getExport(exportId);
|
||||||
|
```
|
||||||
|
|
||||||
|
### JWKS
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const { keys } = await client.getJWKS();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Crypto Utilities
|
||||||
|
|
||||||
|
The SDK exports low-level cryptographic primitives for advanced use:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import {
|
||||||
|
jcsCanonicalise, // RFC 8785 JSON Canonicalization
|
||||||
|
sha256Base64url, // SHA-256 hash as base64url
|
||||||
|
computeChainHash, // Chain hash computation
|
||||||
|
computePayloadHash, // Payload hash computation
|
||||||
|
signEd25519, // Ed25519 signing
|
||||||
|
derivePublicKey, // Derive public key from private seed
|
||||||
|
ZERO_CHAIN_HASH, // Genesis chain hash constant
|
||||||
|
} from '@elydora/sdk';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { ElydoraError } from '@elydora/sdk';
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.submitOperation(eor);
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof ElydoraError) {
|
||||||
|
console.error(err.code); // e.g. 'INVALID_SIGNATURE'
|
||||||
|
console.error(err.message); // Human-readable message
|
||||||
|
console.error(err.statusCode); // HTTP status code
|
||||||
|
console.error(err.requestId); // Request ID for support
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user