Quick Start
Get up and running with Agent OTP in under 5 minutes. This guide will walk you through installation, configuration, and your first permission request.
Prerequisites
- Node.js 18+ or Bun 1.0+
- Docker and Docker Compose (for self-hosting)
- An existing AI agent or application
Step 1: Start Agent OTP Server
Clone the repository and start the server locally using Docker:
# Clone the repository
git clone https://github.com/orristech/agent-otp.git
cd agent-otp
# Copy environment template
cp .env.example .env
# Start all services
docker compose up -dThe API will be available at http://localhost:3000.
Step 2: Create an agent and API key
Generate an API key using the CLI:
# Create a new agent and generate API key
docker compose exec api bun run cli agent:create --name "my-assistant"
# Output:
# Agent created successfully!
# API Key: ak_live_xxxxxxxxxxxxxxxxxxxxImportant: Save this API key securely. It will only be shown once and cannot be retrieved later.
Step 3: Install the SDK
Install the Agent OTP SDK in your project:
npm install @orrisai/agent-otp-sdkbun add @orrisai/agent-otp-sdkpnpm add @orrisai/agent-otp-sdkStep 4: Configure the client
Initialize the Agent OTP client with your API key. We recommend using environment variables:
// lib/otp.ts
import { AgentOTPClient } from '@orrisai/agent-otp-sdk';
export const otp = new AgentOTPClient({
apiKey: process.env.AGENT_OTP_KEY!,
// Point to your local or self-hosted instance
baseUrl: process.env.AGENT_OTP_URL || 'http://localhost:3000',
});Step 5: Request your first permission
Now you can request permissions for sensitive operations. Here's a complete example:
import { otp } from './lib/otp';
async function sendInvoiceEmail(clientEmail: string, invoiceId: string) {
// Request permission to send an email
const permission = await otp.requestPermission({
action: 'email.send',
resource: `email:${clientEmail}`,
scope: {
max_emails: 1,
allowed_recipients: [clientEmail],
},
context: {
reason: `Sending invoice #${invoiceId} to client`,
invoiceId,
},
waitForApproval: true, // Blocks until approved/denied
timeout: 60000, // 60 second timeout
});
// Check the result
if (permission.status === 'approved') {
console.log('Permission granted! Token:', permission.token);
// Use the token to send the email
// The token is scoped to exactly this operation
await yourEmailService.send({
to: clientEmail,
subject: `Invoice #${invoiceId}`,
// Pass the OTP token for verification
otpToken: permission.token,
});
// Mark the token as used
await otp.useToken(permission.token, {
recipient: clientEmail,
invoiceId,
});
return { success: true };
} else if (permission.status === 'denied') {
console.log('Permission denied:', permission.reason);
return { success: false, error: 'Permission denied' };
} else {
console.log('Permission timed out');
return { success: false, error: 'Approval timeout' };
}
}Step 6: Configure policies (optional)
By default, all permission requests require human approval. You can configure policies to auto-approve safe operations:
# Auto-approve file reads under 1MB
- name: "Auto-approve small file reads"
conditions:
action:
equals: "file.read"
scope.max_size:
less_than: 1048576
action: auto_approve
# Require approval for any financial operation
- name: "Financial operations"
conditions:
action:
starts_with: "bank."
action: require_approval
priority: 100See the Policies documentation for more details.