Overview
Conductor is secure by default. All API routes require authentication unless explicitly configured otherwise. This guide covers:- Two Execution Paths - Triggers vs API routes
- API Authentication - Bearer tokens and API keys
- Permission System - Fine-grained access control
- API Key Management - CLI commands for key generation
- Configuration - Security settings in
conductor.config.ts - SSRF Protection - Built-in protection against server-side request forgery
Two Execution Paths
Conductor provides two ways to execute ensembles and agents:Path 1: HTTP Triggers (Recommended for Public APIs)
Triggers are defined in ensemble YAML and go through the full routing system:- ✅ Explicit
public: truerequired for unauthenticated access - ✅ Per-trigger auth configuration
- ✅ Rate limiting support
- ✅ CORS configuration
- ✅ Path-based routing
Path 2: API Execute Routes (For Service-to-Service)
The/api/v1/execute/* routes provide direct access to run ensembles and agents:
- ✅ Authentication required by default
- ✅ Permission-based access control
- ✅ Direct agent execution can be disabled
- ✅ Works with any auth provider (JWT, API keys, Unkey)
API Authentication
All/api/v1/* routes require authentication by default. Conductor supports multiple authentication methods:
Bearer Token (JWT)
API Key (Recommended Default)
The simplest authentication method uses API keys stored in Cloudflare KV:- Create a KV namespace for API keys:
- Add to
wrangler.toml:
- Configure in your trigger:
- Generate keys with the CLI:
Unkey Integration (Advanced)
For advanced API key management with built-in rate limiting, usage analytics, and key rotation, you can optionally use Unkey:Unkey requires installing a plugin and an Unkey account. For most use cases, the simple
apiKey method above is sufficient and recommended.
Recommendation: Start with simple apiKey. Only switch to Unkey if you need its advanced features like built-in rate limiting or usage analytics.
Permission System
Conductor uses an industry-standard permission format compatible with OAuth 2.0 / RBAC patterns:Permission Examples
Wildcard Patterns
The permission system supports glob-style wildcards:Auto-Permissions
WhenautoPermissions is enabled, Conductor automatically requires the appropriate permission for each resource:
POST /api/v1/execute/ensemble/invoice-pdfrequiresensemble:invoice-pdf:executePOST /api/v1/execute/agent/httprequiresagent:http:execute
API Key Management
Conductor includes CLI commands for managing API keys stored in Cloudflare KV.Generate a Key
List Keys
Revoke a Key
Get Key Info
Rotate a Key
Generate a new key while keeping the same metadata:Configuration
Security Configuration
API Execution Access Control
TheapiExecutable flag on agents and ensembles controls whether they can be executed via the Execute API (/api/v1/execute/*).
Per-Agent/Ensemble Configuration:
Example: Strict Production Setup:
When
requireExplicit: true, you get an allowlist model - only explicitly marked agents/ensembles are accessible via the Execute API. This is recommended for production environments.Docs Authentication
By default, documentation follows the same security model as other routes. The built-indocs-serve ensemble explicitly sets public: true for convenience:
public: false setting means the route requires authentication. Conductor will enforce auth based on the request headers (Bearer token, API key, etc.).
SSRF Protection
Conductor includes built-in SSRF (Server-Side Request Forgery) protection for all HTTP operations. This prevents attackers from using your agents to probe internal network resources, cloud metadata services, or localhost.How It Works
When agents make HTTP requests using user-provided URLs, Conductor automatically validates the URL before making the request:Blocked Address Ranges
The following are automatically blocked:Bypassing SSRF Protection (Use Carefully)
In rare cases where you need to access internal resources (e.g., internal microservices), you can bypass SSRF protection:Universal Coverage
SSRF protection is enabled by default for ALL agents - both built-in and user-created:
When your agent handler receives the
AgentExecutionContext, it includes a pre-configured fetch function with SSRF protection:
Disabling SSRF Protection (Per-Agent)
In rare cases, you can disable SSRF protection for a specific agent:fetch() directly since the URLs are trusted.
Privacy Compliance
Conductor provides built-in location context for privacy law compliance:Jurisdiction Detection
Consent Helpers
Security Best Practices
1. Never Expose API Keys in Client Code
API keys should only be used server-side. For client applications, use:- Short-lived JWT tokens
- OAuth 2.0 flows
- Session cookies
2. Use Scoped Permissions
Instead of giving services full access (*), scope their permissions:
3. Rotate Keys Regularly
4. Use Unkey for Production
For production deployments, use Unkey for:- Rate limiting
- Usage analytics
- Automatic rotation
- Key insights
5. Enable Auto-Permissions
For strict access control:6. Disable Direct Agent Execution
If you don’t need to call agents directly:7. Use Edge Context for Bot Detection
Leverage edge context for traffic analysis:API Reference
Execute Ensemble
Authorization: Bearer <token>orX-API-Key: <key>Content-Type: application/json
401 Unauthorized- Missing or invalid authentication403 Forbidden- Missing required permission404 Not Found- Ensemble not found500 Internal Server Error- Execution failed
Execute Agent
Authorization: Bearer <token>orX-API-Key: <key>Content-Type: application/json
400 Bad Request- Missing required input401 Unauthorized- Missing or invalid authentication403 Forbidden- Direct agent execution disabled or missing permission404 Not Found- Agent not found500 Internal Server Error- Execution failed
Migrating from v0.3.x
If you’re upgrading from v0.3.x, note these breaking changes:-
Auth Required by Default: All
/api/v1/*routes now require authentication. To restore open access (not recommended): -
Docs Auth Default Changed: Documentation now defaults to
requiredauth. Shipped templates explicitly setpublic. -
New Route Structure: Prefer the new URL-based routes:
- Old:
POST /api/v1/executewith{"ensemble": "name"} - New:
POST /api/v1/execute/ensemble/{name}
- Old:

