Custom Agent Integration
Integrate Agent Action Firewall with any custom AI agent framework.
Overview
The firewall's REST API allows integration with any agent framework or custom implementation. This guide covers the core patterns for securing your custom agents.
Basic Integration Pattern
TypeScript
import { AgentFirewallClient } from '@agent-action-firewall/sdk';
class SecureAgent {
private firewall: AgentFirewallClient;
constructor(agentId: string) {
this.firewall = new AgentFirewallClient({
baseUrl: process.env.AGENT_FIREWALL_BASE_URL!,
apiKey: process.env.AGENT_FIREWALL_API_KEY!,
agentId,
});
}
async executeAction(
tool: string,
operation: string,
params: Record<string, unknown>
) {
// 1. Submit action for policy evaluation
const response = await this.firewall.submitAction({
tool,
operation,
params,
});
// 2. Handle the response
switch (response.status) {
case 'allowed':
return this.performAction(tool, operation, params);
case 'pending_approval':
const approved = await this.firewall.waitForApproval(response.id);
if (approved.status === 'allowed') {
return this.performAction(tool, operation, params);
}
throw new Error('Action not approved');
case 'denied':
throw new Error(response.decision?.reason || 'Action denied');
}
}
private async performAction(
tool: string,
operation: string,
params: Record<string, unknown>
) {
// Your actual action implementation
}
}Direct REST API Usage
If not using the SDK, integrate directly with the REST API:
TypeScript
async function submitActionToFirewall(action: {
tool: string;
operation: string;
params: Record<string, unknown>;
}) {
const response = await fetch(
'https://api.agentactionfirewall.com/v1/actions',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Agent-Key': `${process.env.API_KEY}`,
'X-Agent-Id': 'custom-agent',
},
body: JSON.stringify(action),
}
);
return response.json();
}
async function waitForApproval(actionId: string, timeoutMs = 300000) {
const startTime = Date.now();
while (Date.now() - startTime < timeoutMs) {
const response = await fetch(
`https://api.agentactionfirewall.com/v1/actions/${actionId}`,
{
headers: {
'X-Agent-Key': `${process.env.API_KEY}`,
},
}
);
const action = await response.json();
if (action.status !== 'pending_approval') {
return action;
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error('Approval timeout');
}Python Integration
Python
import requests
import time
import os
class AgentFirewall:
def __init__(self, agent_id: str):
self.base_url = os.environ['AGENT_FIREWALL_BASE_URL']
self.api_key = os.environ['AGENT_FIREWALL_API_KEY']
self.agent_id = agent_id
def submit_action(self, tool: str, operation: str, params: dict) -> dict:
response = requests.post(
f'{self.base_url}/v1/actions',
headers={
'X-Agent-Key': self.api_key,
'X-Agent-Id': self.agent_id,
},
json={
'tool': tool,
'operation': operation,
'params': params,
}
)
return response.json()
def wait_for_approval(self, action_id: str, timeout: int = 300) -> dict:
start = time.time()
while time.time() - start < timeout:
response = requests.get(
f'{self.base_url}/v1/actions/{action_id}',
headers={'X-Agent-Key': self.api_key}
)
action = response.json()
if action['status'] != 'pending_approval':
return action
time.sleep(5)
raise TimeoutError('Approval timeout')
# Usage
firewall = AgentFirewall('my-python-agent')
def secure_http_call(url: str, method: str, body: dict = None):
response = firewall.submit_action('http_proxy', method, {
'url': url,
'method': method,
'body': body,
})
if response['status'] == 'allowed':
return make_http_request(url, method, body)
elif response['status'] == 'pending_approval':
result = firewall.wait_for_approval(response['id'])
if result['status'] == 'allowed':
return make_http_request(url, method, body)
raise Exception(f"Action denied: {response.get('decision', {}).get('reason')}")Webhook Integration
Receive real-time notifications for action status changes:
TypeScript
// Configure webhook in dashboard
// POST https://your-app.com/webhooks/firewall
app.post('/webhooks/firewall', async (req, res) => {
const { event, action } = req.body;
switch (event) {
case 'action.approved':
await resumeAction(action.id);
break;
case 'action.denied':
await cancelAction(action.id, action.decision.reason);
break;
}
res.sendStatus(200);
});Error Handling
TypeScript
async function robustActionSubmit(action: Action) {
try {
const response = await firewall.submitAction(action);
return response;
} catch (error) {
if (error.status === 429) {
// Rate limited - implement backoff
await sleep(error.retryAfter || 1000);
return robustActionSubmit(action);
}
if (error.status === 503) {
// Service unavailable - fail open or closed based on policy
console.error('Firewall unavailable:', error);
throw new Error('Security service unavailable');
}
throw error;
}
}