Modern async/await API for Node.js and browser environments
# npm
npm install @avp-protocol/sdk
# yarn
yarn add @avp-protocol/sdk
# pnpm
pnpm add @avp-protocol/sdk
import { AVPClient, FileBackend } from '@avp-protocol/sdk';
// Create client with file backend
const client = new AVPClient({
backend: new FileBackend({
path: './vault.enc',
password: 'your-secure-password'
})
});
// Authenticate to a workspace
const session = await client.authenticate({ workspace: 'my-agent' });
// Store a secret
await client.store({
sessionId: session.sessionId,
name: 'OPENAI_API_KEY',
value: Buffer.from('sk-...')
});
// Retrieve a secret
const secret = await client.retrieve({
sessionId: session.sessionId,
name: 'OPENAI_API_KEY'
});
console.log(secret.value.toString()); // sk-...
interface AVPClientOptions {
backend: Backend; // Storage backend instance
logger?: Logger; // Optional custom logger
defaultTtl?: number; // Default session TTL in seconds
}
const client = new AVPClient({
backend: new FileBackend({ path: './vault.enc', password: 'pass' }),
defaultTtl: 3600
});
In-memory storage for testing. Data is lost when the process exits.
import { MemoryBackend } from '@avp-protocol/sdk';
const backend = new MemoryBackend();
Encrypted file storage using AES-256-GCM.
import { FileBackend } from '@avp-protocol/sdk';
const backend = new FileBackend({
path: './vault.enc', // Path to encrypted vault file
password: 'your-password' // Encryption password
});
OS-native credential storage (requires keytar peer dependency).
import { KeychainBackend } from '@avp-protocol/sdk';
// First install keytar
// npm install keytar
const backend = new KeychainBackend({
serviceName: 'my-app-avp' // Service identifier in keychain
});
Query vault capabilities.
const info = await client.discover();
console.log(info.version); // "0.1.0"
console.log(info.backends); // ["memory", "file", "keychain"]
console.log(info.operations); // ["DISCOVER", "AUTHENTICATE", ...]
Create an authenticated session.
| Parameter | Type | Description |
|---|---|---|
workspace | string | Workspace name |
ttlSeconds | number? | Session lifetime (default: 3600) |
const session = await client.authenticate({
workspace: 'production',
ttlSeconds: 7200 // 2 hours
});
console.log(session.sessionId); // "sess_abc123..."
console.log(session.expiresAt); // Date object
Store a secret.
| Parameter | Type | Description |
|---|---|---|
sessionId | string | Active session ID |
name | string | Secret name |
value | Buffer | Secret value |
labels | Record<string, string>? | Optional metadata |
expiresAt | Date? | Optional expiration |
await client.store({
sessionId: session.sessionId,
name: 'DATABASE_URL',
value: Buffer.from('postgres://...'),
labels: { environment: 'production', service: 'api' },
expiresAt: new Date('2025-12-31')
});
Retrieve a secret value.
| Parameter | Type | Description |
|---|---|---|
sessionId | string | Active session ID |
name | string | Secret name |
version | number? | Specific version (default: latest) |
const secret = await client.retrieve({
sessionId: session.sessionId,
name: 'DATABASE_URL'
});
console.log(secret.value.toString()); // postgres://...
console.log(secret.version); // 1
console.log(secret.labels); // { environment: 'production', ... }
Delete a secret.
await client.delete({
sessionId: session.sessionId,
name: 'OLD_API_KEY'
});
List all secrets in the workspace.
const secrets = await client.list({
sessionId: session.sessionId,
labelFilter: { environment: 'production' } // Optional filter
});
for (const secret of secrets) {
console.log(secret.name, secret.version);
}
Update a secret with version tracking.
const result = await client.rotate({
sessionId: session.sessionId,
name: 'API_KEY',
newValue: Buffer.from('sk-new-key-...')
});
console.log(result.previousVersion); // 1
console.log(result.newVersion); // 2
import { AVPError, ErrorCode } from '@avp-protocol/sdk';
try {
await client.retrieve({ sessionId, name: 'UNKNOWN_KEY' });
} catch (error) {
if (error instanceof AVPError) {
switch (error.code) {
case ErrorCode.NOT_FOUND:
console.log('Secret not found');
break;
case ErrorCode.SESSION_EXPIRED:
console.log('Session expired, re-authenticate');
break;
case ErrorCode.UNAUTHORIZED:
console.log('Not authorized for this workspace');
break;
default:
console.log('AVP Error:', error.message);
}
}
}
import type {
AVPClient,
Backend,
Session,
Secret,
StoreOptions,
RetrieveOptions,
ListOptions,
RotateResult,
DiscoverInfo,
AVPError,
ErrorCode
} from '@avp-protocol/sdk';
MemoryBackend is available. File and Keychain backends require Node.js.
// Browser bundle
import { AVPClient, MemoryBackend } from '@avp-protocol/sdk/browser';
const client = new AVPClient({
backend: new MemoryBackend()
});
import { AVPClient, FileBackend } from '@avp-protocol/sdk';
async function main() {
// Initialize client
const client = new AVPClient({
backend: new FileBackend({
path: './my-agent-vault.enc',
password: process.env.VAULT_PASSWORD!
})
});
// Create session
const session = await client.authenticate({
workspace: 'openai-agent'
});
// Store credentials
await client.store({
sessionId: session.sessionId,
name: 'OPENAI_API_KEY',
value: Buffer.from(process.env.OPENAI_API_KEY!),
labels: { provider: 'openai' }
});
// Use in your agent
const apiKey = await client.retrieve({
sessionId: session.sessionId,
name: 'OPENAI_API_KEY'
});
// Pass to OpenAI client
const openai = new OpenAI({
apiKey: apiKey.value.toString()
});
// Rotate when needed
await client.rotate({
sessionId: session.sessionId,
name: 'OPENAI_API_KEY',
newValue: Buffer.from('sk-new-key-...')
});
}
main().catch(console.error);