Capabilities and Limits System
Overview
The Agent Passport Registry implements a comprehensive capabilities and limits system that provides fine-grained control over what agents can do and how much they can do it. This system ensures security, compliance, and operational control across all agent interactions.
Capabilities System
What are Capabilities?
Capabilities are standardized permissions that define what actions an agent can perform. Each capability has:
- ID: Unique identifier (e.g.,
finance.payment.refund) - Parameters: Optional configuration (e.g., max amount, currency)
- Risk Level: Security assessment (low, medium, high, critical)
- Category: Functional grouping (payments, data, messaging, etc.)
Standard Capabilities
| Capability ID | Name | Risk Level | Description |
|---|---|---|---|
finance.payment.refund
|
Payment Refunds | High | Process payment refunds and chargebacks |
payments.payout
|
Payment Payouts | Critical | Process payments to external accounts |
returns.process
|
Process Returns | Medium | Handle product returns and exchanges |
inventory.adjust
|
Inventory Adjustment | Medium | Modify inventory levels and stock |
data.export
|
Data Export | Medium | Export data in various formats |
data.delete
|
Data Deletion | High | Delete data from systems |
identity.manage_roles
|
Role Management | High | Manage user roles and permissions |
messaging.send
|
Send Messages | Low | Send messages via Slack, Discord, Email with rate limits |
crm.update
|
CRM Updates | Medium | Update customer relationship data |
repo.pr.create
|
Create Pull Requests | Medium | Create pull requests with safety controls |
repo.merge
|
Repository Merge | High | Merge code changes with governance controls |
infra.deploy
|
Infrastructure Deploy | Critical | Deploy infrastructure changes |
media.image.generate
|
Image Generation | Medium | Generate or edit images with provider, prompt metadata, reference, output count, and format controls |
deliverable.task.complete
|
Task Completion | Low | Mark a task complete once acceptance criteria are attested with evidence |
Capability Parameters
Capabilities can include parameters for fine-grained control:
{
"capabilities": [
{
"id": "finance.payment.refund",
"params": {
"max_amount": 5000,
"currency": "USD",
"allowed_methods": ["stripe", "paypal"]
}
},
{
"id": "data.export",
"params": {
"max_rows": 10000,
"allowed_formats": ["csv", "json"],
"include_pii": false
}
}
]
}
Limits System
What are Limits?
Limits are operational constraints that control how much an agent can do within specific time periods. All limits are strongly typed and validated.
Limits are stored on the passport, under limits[". A verification request carries the action context only; it cannot add or override limits. If two tasks need different limits, they need different passports. Limit values are usually scalars or string arrays, and some are nested objects: payments.charge takes currency_limits, keyed by currency code. deliverable.task.complete is the one registered capability whose limits include an array of objects, acceptance_criteria: [{ "id", "description" }], which the agent must attest to one by one. See policies/deliverable.task.complete.v1/README.md.
Standard Limits
| Limit Key | Type | Min | Max | Description |
|---|---|---|---|---|
refund_amount_max_per_tx
|
number | 0 | 1,000,000 | Max refund per transaction (USD cents) |
refund_amount_daily_cap
|
number | 0 | 10,000,000 | Max total refunds per day (USD cents) |
payout_usd_daily_cap
|
number | 0 | 100,000,000 | Max total payouts per day (USD cents) |
max_actions_per_min
|
number | 1 | 10,000 | Max actions allowed per minute |
max_export_rows
|
number | 1 | 1,000,000 | Max rows in data exports |
allow_pii
|
boolean | - | - | Whether agent can access PII data |
max_deploys_per_day
|
number | 0 | 100 | Max deployments per day (0 blocks deployment outright) |
media.image.generate uses nested limits under limits["media.image.generate"]: allowed_providers, max_prompt_length, max_referenced_images, max_output_images, and allowed_output_formats. Hooks should send only metadata such as prompt length and output format, not raw prompt text or image contents.
Limits Validation
The system automatically validates limits to ensure consistency:
// Example validation rules
if (refund_amount_max_per_tx > refund_amount_daily_cap) {
throw new Error("Per-transaction limit cannot exceed daily cap");
}
if (max_actions_per_min < 1) {
throw new Error("Actions per minute must be at least 1");
}
Implementation Examples
Express.js Middleware
import {
agentPassportMiddleware,
requireCapability,
requireLimits
} from '@agent-passport/express';
// Require specific capability
app.use('/refunds',
agentPassportMiddleware(),
requireCapability('finance.payment.refund'),
requireLimits(['refund_amount_max_per_tx', 'refund_amount_daily_cap'])
);
// Check limits in your handler
app.post('/refunds', async (req, res) => {
const passport = req.agentPassport;
const refundAmount = req.body.amount;
// Check per-transaction limit
if (refundAmount > passport.limits.refund_amount_max_per_tx) {
return res.status(400).json({
error: 'limit_exceeded',
message: `Refund amount exceeds per-transaction limit of $${passport.limits.refund_amount_max_per_tx / 100}`
});
}
// Process refund...
});
FastAPI Middleware
from aporthq_middleware_fastapi import AgentPassportMiddleware, require_capability, require_limits
app.add_middleware(AgentPassportMiddleware)
@app.post("/refunds")
@require_capability("finance.payment.refund")
@require_limits(["refund_amount_max_per_tx", "refund_amount_daily_cap"])
async def process_refund(request: Request, refund_data: dict):
passport = request.state.agent_passport
refund_amount = refund_data["amount"]
# Check limits
if refund_amount > passport.limits.refund_amount_max_per_tx:
raise HTTPException(
status_code=400,
detail=f"Refund amount exceeds per-transaction limit of ${passport.limits.refund_amount_max_per_tx / 100}"
)
# Process refund...
Manual Verification
import { verifyAgent } from '@agent-passport/sdk';
async function checkAgentAccess(agentId: string, requiredCapability: string) {
const passport = await verifyAgent(agentId);
if (!passport) {
throw new Error('Agent not found');
}
if (passport.status !== 'active') {
throw new Error('Agent is not active');
}
const hasCapability = passport.capabilities.some(
cap => cap.id === requiredCapability
);
if (!hasCapability) {
throw new Error(`Agent lacks required capability: ${requiredCapability}`);
}
return passport;
}
Risk Assessment
Capability Risk Levels
- Low: Minimal risk, basic operations (messaging, data reading)
- Medium: Moderate risk, data modification (inventory, CRM updates)
- High: High risk, financial operations (refunds, role management)
- Critical: Maximum risk, infrastructure changes (deployments, payouts)
Assurance Level Requirements
Higher-risk capabilities may require higher assurance levels:
const CAPABILITY_ASSURANCE_REQUIREMENTS = {
'finance.payment.refund': 'L2',
'payments.payout': 'L4FIN',
'infra.deploy': 'L3',
'data.delete': 'L2',
'identity.manage_roles': 'L3'
};
Monitoring and Enforcement
Real-time Monitoring
The system tracks capability usage and limit consumption:
{
"capability_usage": {
"finance.payment.refund": {
"total_requests": 150,
"successful_requests": 148,
"failed_requests": 2,
"total_amount": 250000
}
},
"limit_consumption": {
"refund_amount_daily_cap": {
"used": 250000,
"limit": 1000000,
"percentage": 25
}
}
}
Alerting
Automatic alerts are triggered when:
- Limits are approaching (80% threshold)
- Limits are exceeded
- High-risk capabilities are used
- Assurance level requirements are not met
Best Practices
1. Principle of Least Privilege
Grant only the minimum capabilities required:
{
"capabilities": [
{
"id": "data.export",
"params": {
"max_rows": 1000,
"include_pii": false
}
}
]
}
2. Regular Audits
Periodically review agent capabilities and limits:
# Get agent capabilities
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.aport.io/api/admin/agents" | \
jq '.[] | {agent_id, capabilities, limits}'
3. Gradual Rollout
Start with conservative limits and increase as needed:
{
"limits": {
"refund_amount_max_per_tx": 1000,
"refund_amount_daily_cap": 5000,
"max_actions_per_min": 10
}
}
4. Monitoring and Alerting
Set up comprehensive monitoring:
// Monitor capability usage
const usage = await getCapabilityUsage(agentId, 'finance.payment.refund');
if (usage.percentage > 80) {
await sendAlert(`Agent ${agentId} approaching refund limit`);
}
API Reference
Capability Validation
POST /api/assurance/validate
Content-Type: application/json
{
"level": "L2",
"method": "email"
}
Limits Enforcement
GET /api/verify/ap_a2d10232c6534523812423eec8a1425c
Response includes current limits:
{
"agent_id": "ap_a2d10232c6534523812423eec8a1425c",
"limits": {
"refund_amount_max_per_tx": 5000,
"refund_amount_daily_cap": 50000,
"max_actions_per_min": 100
},
"capabilities": [
{
"id": "finance.payment.refund",
"params": {
"max_amount": 5000,
"currency": "USD"
}
}
]
}
Troubleshooting
Common Issues
- Capability Not Found
- Ensure capability ID is in the standard registry
- Check for typos in capability names
Debug Commands
# Check agent capabilities
curl "https://api.aport.io/api/verify/ap_a2d10232c6534523812423eec8a1425c" | jq '.capabilities'
# Check limits
curl "https://api.aport.io/api/verify/ap_a2d10232c6534523812423eec8a1425c" | jq '.limits'
# Validate assurance level
curl -X POST "https://api.aport.io/api/assurance/validate" \
-H "Content-Type: application/json" \
-d '{"level": "L2", "method": "email"}'
Future Enhancements
- Dynamic Limits: Adjust limits based on agent performance
- Time-based Capabilities: Capabilities that expire after certain time
- Geographic Restrictions: Capabilities limited to specific regions
- Verifiable Attestation: Detailed logging of capability usage
- Machine Learning: Automated risk assessment and limit recommendations