Using ACT with OpenAI Assistants
Add fine-grained permissions and runtime enforcement to OpenAI Assistants API
Overview
OpenAI Assistants are powerful, but they lack granular permission controls. Once you give an Assistant access to a function, it can call that function whenever the LLM decides to. This creates security risks:
- Assistants may hallucinate tool calls with incorrect parameters
- No way to enforce constraints (e.g., "only read, never delete")
- Limited audit logging for Assistant actions
- Cannot revoke access without deleting the entire Assistant
ACT solves this by adding a permission layer between your Assistant and your backend APIs.
Architecture
✓ Checks policy
✓ Logs action
⚠️ Authentication Required
All requests to https://api.acttokens.com require:
- API Key (in
X-Api-Keyheader) - Platform authentication - Capability Token (in request body) - Agent authorization
Quick Start
Step 1: Get Your API Key
Sign up for an ACT account and obtain your API key from the dashboard. You'll use this to authenticate REST API calls.
API_KEY="your_api_key_here"
ACT_BASE_URL="https://api.acttokens.com"Step 2: Register Your Assistant in ACT
curl -X POST $ACT_BASE_URL/v1/agents \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "OpenAI Customer Support Assistant",
"description": "Handles customer inquiries",
"metadata": {
"openai_assistant_id": "asst_abc123"
}
}'Step 3: Define a Policy
curl -X POST $ACT_BASE_URL/v1/policies \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer Support Read Policy",
"actions": ["read", "list"],
"resources": ["api://crm/customers/*"],
"effect": "allow",
"constraints": {
"maxRows": 100,
"allowedDomains": ["yourcompany.com"]
}
}'Step 4: Issue an ACT Token
curl -X POST $ACT_BASE_URL/v1/tokens \
-H "X-Api-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "agent_123",
"expiresIn": 3600
}'Step 5: Add ACT Validation to Your Functions
Create a helper function that validates requests with ACT before executing actions:
// Helper function to validate with ACT
async function validateWithACT(token, action, resource) {
const response = await fetch('$ACT_BASE_URL/v1/enforce', {
method: 'POST',
headers: {
'X-Api-Key': '$API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
requestId: crypto.randomUUID(),
capabilityToken: token,
action: action,
resourceId: resource,
tenantId: 'default-tenant',
context: {}
})
});
const result = await response.json();
return result.decision === 'allowed';
}
// Your OpenAI function that validates
async function getCustomerData(customerId, actToken) {
const allowed = await validateWithACT(
actToken,
'read',
`api://crm/customers/${customerId}`
);
if (!allowed) {
throw new Error("Action not permitted by ACT policy");
}
// Now fetch the data
const customer = await db.customers.findById(customerId);
return customer;
}Step 6: Run Your Assistant with ACT
import OpenAI from 'openai';
const openai = new OpenAI();
// Create a thread and run
const thread = await openai.beta.threads.create();
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: "asst_abc123",
metadata: {
act_token: actToken // Pass ACT token in metadata
}
});
// When the Assistant calls your function, it includes
// the ACT token, and your function validates it
// (as shown in Step 5)Example Use Cases
✅ Customer Support Assistant
Policy: Read customer data, create support tickets
actions: ["read", "create"]
resources: ["api://crm/customers/*", "api://tickets/*"]
constraints: { maxRows: 50 }✅ Data Analysis Assistant
Policy: Read-only access to analytics database
actions: ["read", "query"]
resources: ["api://analytics/*"]
constraints: { maxRows: 1000, readOnly: true }✅ Email Assistant
Policy: Send emails, only to internal domains
actions: ["send_email"]
resources: ["api://email/*"]
constraints: { allowedDomains: ["@yourcompany.com"] }Best Practices
- Use short-lived tokens: Issue ACT tokens with 1-hour expiration for Assistants
- Validate every function call: Never trust the Assistant to make the right decision — always validate with ACT
- Log everything: ACT automatically logs all validation attempts, giving you full audit trails
- Start restrictive: Begin with read-only policies and gradually expand permissions as needed
- Use constraints: Add row limits, domain allowlists, and other constraints to prevent abuse
- Monitor audit logs: Regularly review ACT audit logs to detect unusual Assistant behavior
Troubleshooting
Assistant calls are being blocked
Solution: Check your policy. The action or resource may not be allowed. Review ACT audit logs to see exactly what was blocked.
Token expired errors
Solution: Issue a new ACT token. Consider implementing automatic token refresh in your application.
Not seeing audit logs
Solution: Ensure you're calling act.validate() before executing actions. Only validated actions appear in audit logs.