@agentvault/secure-channel
v0.7.0
Published
End-to-end encrypted communication channel for AI agents on the [AgentVault](https://agentvault.chat) platform. Connect your agent to its owner with XChaCha20-Poly1305 encryption and Double Ratchet forward secrecy.
Readme
@agentvault/secure-channel
End-to-end encrypted communication channel for AI agents on the AgentVault platform. Connect your agent to its owner with XChaCha20-Poly1305 encryption and Double Ratchet forward secrecy.
What's New in v0.5.0
Desktop Notifications — Incoming messages now trigger native OS notifications (macOS Notification Center, Windows Toast, Linux notify-send) when using the CLI. Enabled by default — disable with --no-notifications.
Webhook URL CLI Flag (v0.4.4) — --webhook-url flag and AGENTVAULT_WEBHOOK_URL env var for programmatic webhook registration.
Webhook Notifications (v0.4.0) — HTTP webhook callbacks when a new message arrives, even when not connected via WebSocket.
Upgrading
npm install @agentvault/secure-channel@latestNo code changes required — fully backward-compatible.
Installation
npm install @agentvault/secure-channelQuick Start
Option 1: CLI (Interactive)
Run directly with npx using the invite token from your AgentVault dashboard:
npx @agentvault/secure-channel --token=YOUR_INVITE_TOKENThe CLI will:
- Enroll your agent with the server
- Display a fingerprint for the owner to verify
- Wait for owner approval
- Establish an encrypted channel
- Enter interactive mode where you can send/receive messages
CLI Flags:
| Flag | Default | Description |
|------|---------|-------------|
| --token | (required on first run) | Invite token from dashboard |
| --name | "CLI Agent" | Agent display name |
| --data-dir | ./agentvault-data | Directory for persistent state |
| --api-url | https://api.agentvault.chat | API endpoint |
| --webhook-url | (none) | URL for HTTP webhook notifications |
| --no-notifications | (notifications on) | Disable OS desktop notifications |
Environment variables (AGENTVAULT_INVITE_TOKEN, AGENTVAULT_AGENT_NAME, AGENTVAULT_DATA_DIR, AGENTVAULT_API_URL, AGENTVAULT_WEBHOOK_URL, AGENTVAULT_NO_NOTIFICATIONS) work as alternatives to flags.
Option 2: SDK (Programmatic)
import { SecureChannel } from "@agentvault/secure-channel";
const channel = new SecureChannel({
inviteToken: "YOUR_INVITE_TOKEN",
dataDir: "./agentvault-data",
apiUrl: "https://api.agentvault.chat",
agentName: "My Agent",
});
channel.on("message", (text, metadata) => {
console.log(`Received: ${text}`);
// Echo back
channel.send(`You said: ${text}`);
});
channel.on("ready", () => {
console.log("Secure channel established!");
});
await channel.start();Webhook Notifications (v0.4.0+)
Enable webhook notifications so your agent gets an HTTP POST when a new message arrives — useful for agents that aren't always connected via WebSocket.
Setup
Add webhookUrl to your config:
const channel = new SecureChannel({
inviteToken: "YOUR_INVITE_TOKEN",
dataDir: "./agentvault-data",
apiUrl: "https://api.agentvault.chat",
webhookUrl: "https://your-server.com/webhook/agentvault",
});The webhook URL is registered automatically during device activation. The channel emits a webhook_registered event on success:
channel.on("webhook_registered", ({ url, secret }) => {
console.log(`Webhook registered at ${url}`);
// Save the secret to verify incoming webhooks
});Webhook Payload
When the owner sends a message, your webhook endpoint receives:
POST /webhook/agentvault HTTP/1.1
Content-Type: application/json
X-AgentVault-Event: new_message
X-AgentVault-Signature: sha256=<hmac-hex>
{
"event": "new_message",
"conversation_id": "uuid",
"sender_device_id": "uuid",
"message_id": "uuid",
"timestamp": "2026-02-17T12:00:00Z"
}Verifying Webhook Signatures
Each webhook includes an HMAC-SHA256 signature in the X-AgentVault-Signature header. Verify it using the secret from the webhook_registered event:
import crypto from "crypto";
function verifyWebhook(body, signature, secret) {
const expected = "sha256=" +
crypto.createHmac("sha256", secret).update(body).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}Configuration Reference
interface SecureChannelConfig {
// Required
inviteToken: string; // Invite token from the AgentVault dashboard
dataDir: string; // Directory for persistent state files
apiUrl: string; // API endpoint (e.g., "https://api.agentvault.chat")
// Optional
agentName?: string; // Display name (default: "CLI Agent")
platform?: string; // Platform identifier (e.g., "node")
maxHistorySize?: number; // Max stored messages for cross-device replay (default: 500)
webhookUrl?: string; // Webhook URL for new message notifications (v0.4.0+)
// Callbacks (alternative to event listeners)
onMessage?: (text: string, metadata: MessageMetadata) => void;
onStateChange?: (state: ChannelState) => void;
}Events
| Event | Payload | Description |
|-------|---------|-------------|
| message | (text: string, metadata: MessageMetadata) | Owner sent a message |
| ready | none | WebSocket connected, channel operational |
| state | (state: ChannelState) | State transition occurred |
| error | (error: Error) | Fatal error |
| webhook_registered | ({ url: string, secret: string }) | Webhook registered (v0.4.0+) |
Channel States
idle → enrolling → polling → activating → connecting → ready
If disconnected: ready → disconnected → connecting → ready (auto-reconnect)
API
| Method | Description |
|--------|-------------|
| start() | Initialize, enroll, and connect |
| send(text) | Encrypt and send message to all owner devices |
| stop() | Gracefully disconnect |
| Property | Description |
|----------|-------------|
| state | Current channel state |
| deviceId | Agent's device ID (after enrollment) |
| fingerprint | Device fingerprint for verification |
| conversationId | Primary conversation ID |
| conversationIds | All active conversation IDs (multi-device) |
| sessionCount | Number of active encrypted sessions |
Multi-Device Support
AgentVault supports multiple owner devices (e.g., desktop + mobile). The channel automatically:
- Maintains independent encrypted sessions per owner device
- Fans out
send()to all active sessions - Stores message history for cross-device replay (up to
maxHistorySize) - Replays history when a new device connects
No additional configuration needed — multi-device is handled transparently.
Running as a Service
The agent process must stay running to receive messages and desktop notifications. Use pm2 to keep it alive:
# Install pm2 globally
npm install -g pm2
# Start your agent as a background service
pm2 start npx --name "my-agent" -- @agentvault/secure-channel \
--token=YOUR_TOKEN --name="My Agent"
# View logs
pm2 logs my-agent
# Auto-restart on crash
pm2 save
# Stop the agent
pm2 stop my-agentpm2 keeps the process running if the terminal closes and auto-restarts on crashes. Desktop notifications continue to work as long as pm2 was started from your desktop session.
For headless servers (no desktop), use --no-notifications and configure --webhook-url instead.
Security
- XChaCha20-Poly1305 symmetric encryption (192-bit nonces)
- X3DH key agreement (Ed25519 + X25519)
- Double Ratchet for forward secrecy — old keys deleted after use
- Zero-knowledge server — the server never sees plaintext
- HMAC-SHA256 webhook signatures for authenticity verification
License
MIT
