A lightweight OTP (One-Time Permission) service for AI Agents, enabling scoped, ephemeral, and human-approved access to sensitive operations.
Agent OTP provides a security layer for AI agents (like Moltbot, LangChain, CrewAI, etc.) that need to perform sensitive operations. Instead of giving agents broad, long-lived permissions, Agent OTP enables:
- Scoped permissions: Define exactly what an agent can do
- Ephemeral tokens: Permissions expire quickly (default: 5 minutes)
- Human-in-the-loop: Require approval for sensitive operations
- Policy-based decisions: Auto-approve, require-approval, or deny based on rules
- Full audit trail: Track every permission request and usage
npm install @orrisai/agent-otp-sdk
# or
bun add @orrisai/agent-otp-sdkCreate an account at agentotp.com and register an agent to get an API key.
import { AgentOTPClient } from '@orrisai/agent-otp-sdk';
const otp = new AgentOTPClient({
apiKey: process.env.AGENT_OTP_KEY,
});
// Request permission with automatic waiting for approval
const permission = await otp.requestPermission({
action: 'gmail.send',
resource: 'email:client@example.com',
scope: {
max_emails: 1,
subject_pattern: '^Invoice.*',
},
context: {
reason: 'Sending monthly invoice to client',
},
waitForApproval: true,
onPendingApproval: (info) => {
console.log(`Waiting for approval: ${info.approvalUrl}`);
},
});
if (permission.status === 'approved') {
// Use the token for your protected operation
await sendEmail({
to: 'client@example.com',
subject: 'Invoice #123',
otpToken: permission.token,
});
// Mark token as used
await otp.useToken(permission.id, permission.token);
}┌──────────────┐ 1. Request Permission ┌──────────────┐
│ AI Agent │ ─────────────────────────────► │ Agent OTP │
│ + SDK │ │ API │
└──────────────┘ └──────────────┘
│ │
│ │ 2. Evaluate
│ │ Policy
│ ▼
│ ┌──────────────┐
│ │ Policy │
│ │ Engine │
│ └──────────────┘
│ │
│ 3. Decision │
│ ◄─────────────────────────────────────────────┤
│ (auto_approve | require_approval | deny) │
│ │
│ If require_approval: │
│ ▼
│ ┌──────────────┐
│ │ Telegram │
│ │ / Web UI │
│ └──────────────┘
│ │
│ 4. User Decision │
│ ◄─────────────────────────────────────────────┤
│ │
│ 5. Token │
│ ◄─────────────────────────────────────────────┤
│ │
▼ │
┌──────────────┐ 6. Use Token ┌──────────────┐
│ Protected │ ─────────────────────────────►│ Audit │
│ Operation │ │ Log │
└──────────────┘ └──────────────┘
Full documentation is available at agentotp.com/docs.
agent-otp/
├── apps/
│ ├── api/ # Main API service (Hono + Cloudflare Workers)
│ ├── website/ # Documentation website (Next.js)
│ ├── dashboard/ # Web Dashboard (Next.js) - Coming soon
│ └── telegram-bot/ # Telegram approval bot - Coming soon
├── packages/
│ ├── sdk/ # TypeScript SDK
│ └── shared/ # Shared types and utilities
├── docs/ # Internal documentation
└── docker-compose.yml # Local development setup
- Clone the repository:
git clone https://github.com/yourusername/agent-otp.git
cd agent-otp- Install dependencies:
bun install- Start the local database and Redis:
docker compose up -d- Copy environment variables:
cp .env.example .env
# Edit .env with your configuration- Start the development server:
bun devThe API will be available at http://localhost:8787.
# Run all tests
bun test
# Run tests with coverage
bun test:coverage
# Run tests for a specific package
bun test --filter @orrisai/agent-otp-sdkIf you discover a security vulnerability, please email security@agentotp.com. Do not open public issues for security vulnerabilities.
- Never commit secrets: All sensitive configuration should be in
.envfiles (which are gitignored) - Use environment variables: API keys, database credentials, and JWT secrets should always be in environment variables
- Rotate API keys: Regularly rotate your Agent OTP API keys
- Review policies: Audit your permission policies regularly to ensure they follow least-privilege principles
POST /api/v1/permissions/request
Authorization: Bearer ak_your_api_key
{
"action": "gmail.send",
"resource": "email:recipient@example.com",
"scope": {
"max_emails": 1,
"subject_pattern": "^Invoice.*"
},
"context": {
"reason": "Sending monthly invoice"
},
"ttl": 300
}POST /api/v1/permissions/:id/verify
Authorization: Bearer ak_your_api_key
{
"token": "otp_xxxxxx"
}POST /api/v1/permissions/:id/use
Authorization: Bearer ak_your_api_key
{
"token": "otp_xxxxxx",
"actionDetails": {
"recipient": "client@example.com",
"subject": "Invoice #123"
}
}Policies define how permission requests are handled. Example policies:
# Auto-approve small file reads
- name: "Auto-approve file reads"
conditions:
action: { equals: "file.read" }
scope.size_limit: { lessThan: 1048576 }
action: auto_approve
scopeTemplate:
max_size: 1048576
allowed_extensions: [".txt", ".md", ".json"]
# Require approval for financial operations
- name: "Financial operations require approval"
conditions:
action: { startsWith: "bank." }
action: require_approval
priority: 100
# Auto-approve internal emails
- name: "Auto-approve internal emails"
conditions:
action: { equals: "gmail.send" }
context.recipient: { matches: ".*@mycompany\\.com$" }
action: auto_approve
# Default deny
- name: "Default deny"
conditions: {}
action: deny
priority: -1000- Core API with permission request/verify/use
- TypeScript SDK
- Policy engine with conditions
- Documentation website
- Web Dashboard
- Telegram Bot for approvals
- Python SDK
- LangChain integration
- CrewAI integration
- Enterprise features (SSO, advanced audit)
Contributions are welcome! Please read our Contributing Guide for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes
- Run tests:
bun test - Commit with a descriptive message
- Push and open a Pull Request
MIT License - see LICENSE for details.