What are Permissions?
Permissions define what actions an agent is allowed to perform. Each permission specifies:
What action can be performed (e.g., stripe.refund)
Limits on that action (e.g., max amount)
Whether approval is required before execution
Permission Properties
The action identifier (e.g., stripe.refund, email.send, database.write)
Whether this action requires human approval before execution
Maximum monetary amount allowed (if applicable to the action)
Creating Permissions
Via Dashboard
Open Agent
Navigate to Agents and click on your agent
Add Permission
Click Add Permission
Configure
Enter the action name
Set max_amount (if applicable)
Toggle requires_approval if needed
Via API
curl -X POST https://api.agentwarden.io/api/agents/AGENT_ID/permissions \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "stripe.refund",
"max_amount": 100.00,
"requires_approval": false
}'
Action Naming Conventions
We recommend using a hierarchical dot notation for actions:
service.resource.operation
Examples
Payment Actions
Database Actions
API Actions
Infrastructure Actions
stripe.refund
stripe.charge
paypal.payout
stripe.subscription.cancel
Custom Actions
You can define any action name that makes sense for your use case:
# E-commerce
"order.cancel"
"inventory.adjust"
"customer.discount.apply"
# Content Management
"blog.post.publish"
"user.content.moderate"
"comment.delete"
# Analytics
"report.generate"
"data.export"
"metrics.collect"
Permission Strategies
Strategy 1: Tiered Permissions
Create multiple permissions for the same action with different limits:
# Small refunds - auto-approve
{
"action" : "stripe.refund.small" ,
"max_amount" : 50.00 ,
"requires_approval" : false
}
# Medium refunds - auto-approve
{
"action" : "stripe.refund.medium" ,
"max_amount" : 200.00 ,
"requires_approval" : false
}
# Large refunds - require approval
{
"action" : "stripe.refund.large" ,
"max_amount" : 1000.00 ,
"requires_approval" : true
}
Then in your code:
def process_refund ( amount ):
# Determine which permission to check
if amount <= 50 :
action = "stripe.refund.small"
elif amount <= 200 :
action = "stripe.refund.medium"
else :
action = "stripe.refund.large"
result = guard.check( AGENT_ID , action, { "amount" : amount})
Strategy 2: Environment-Based Permissions
Different permissions for different environments:
# Staging - no approval needed
{
"action" : "deploy.staging" ,
"requires_approval" : false
}
# Production - requires approval
{
"action" : "deploy.production" ,
"requires_approval" : true
}
Strategy 3: Resource-Specific Permissions
Fine-grained control over specific resources:
# Can read from all databases
{
"action" : "database.read" ,
"requires_approval" : false
}
# Can write to analytics DB only
{
"action" : "database.analytics.write" ,
"requires_approval" : false
}
# Writing to users DB requires approval
{
"action" : "database.users.write" ,
"requires_approval" : true
}
Using Max Amount
The max_amount field is useful for monetary limits:
Example: Refund Limits
{
"action" : "stripe.refund" ,
"max_amount" : 100.00 ,
"requires_approval" : false
}
When checking this permission:
# This will be ALLOWED (50 < 100)
guard.check(
agent_id = AGENT_ID ,
action = "stripe.refund" ,
context = { "amount" : 50.00 }
)
# This will be DENIED (150 > 100)
guard.check(
agent_id = AGENT_ID ,
action = "stripe.refund" ,
context = { "amount" : 150.00 }
)
Non-Monetary Uses
You can use max_amount for other numeric limits:
# Max number of emails to send
{
"action" : "email.send_bulk" ,
"max_amount" : 1000 , # Max 1000 emails
"requires_approval" : false
}
# Max number of API calls
{
"action" : "api.external.call" ,
"max_amount" : 100 , # Max 100 calls
"requires_approval" : false
}
Approval Requirements
When requires_approval is true:
Agent attempts action → guard.check() called
Permission check returns → allowed: false, requires_approval: true
Approval request created → Visible in dashboard
Human reviews → Approves or denies
Agent can proceed → After approval
Example Flow
result = guard.check(
agent_id = "devops-agent" ,
action = "deploy.production" ,
context = { "version" : "v2.1.0" }
)
if result.requires_approval:
print ( "⏳ Waiting for approval..." )
# Notify admin
notify_admin_for_approval()
# Queue the deployment
queue_deployment()
else :
# Proceed immediately
deploy_now()
Approval workflows are covered in detail in the Approvals guide.
Permission Conflicts
What if multiple permissions match?
If you create multiple permissions for the same action, AgentWarden uses the most permissive one:
# Permission 1
{
"action" : "stripe.refund" ,
"max_amount" : 50.00 ,
"requires_approval" : false
}
# Permission 2
{
"action" : "stripe.refund" ,
"max_amount" : 200.00 ,
"requires_approval" : false
}
# Result: Agent can refund up to $200 without approval
Avoid creating conflicting permissions. Use specific action names instead (e.g., stripe.refund.small vs stripe.refund.large).
Permission Validation
AgentWarden validates permissions during check:
result = guard.check(
agent_id = AGENT_ID ,
action = "stripe.refund" ,
context = { "amount" : 50.00 }
)
# result.allowed can be False for several reasons:
# 1. No permission exists for this action
# 2. Amount exceeds max_amount
# 3. Agent is inactive
# 4. Action requires approval
Check Result Properties
class CheckResponse :
allowed: bool # Can the action proceed?
requires_approval: bool # Does it need human approval?
reason: str | None # Why was it blocked (if blocked)
Deleting Permissions
Via Dashboard
Open Agent
Navigate to your agent
Find Permission
Locate the permission to delete
Delete
Click the delete icon
Confirm
Confirm the deletion
Via API
curl -X DELETE https://api.agentwarden.io/api/agents/AGENT_ID/permissions/PERMISSION_ID \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Deleting a permission immediately prevents the agent from performing that action. Any in-flight actions may be blocked.
Best Practices
1. Start Restrictive, Then Relax
Begin with stricter permissions and approval requirements. Relax them as you gain confidence in your agent’s behavior.
2. Use Specific Action Names
Avoid generic names like action1 or do_thing. Use descriptive names that clearly indicate what the action does.
3. Set Appropriate Limits
Consider the business impact of each action and set max_amount accordingly. Don’t set limits too high “just in case”.
4. Require Approval for High-Risk Actions
Any action with significant business impact should require approval, especially:
Large financial transactions
Production deployments
Data deletions
External API calls with rate limits
5. Review Permissions Regularly
Audit your permissions quarterly to ensure they still make sense as your agents evolve.
6. Document Permission Rationale
Keep notes on why certain permissions exist and what their limits mean. This helps during audits and onboarding.
Common Permission Patterns
E-commerce Customer Support
permissions = [
{ "action" : "order.cancel" , "requires_approval" : false},
{ "action" : "stripe.refund" , "max_amount" : 100 , "requires_approval" : false},
{ "action" : "stripe.refund" , "max_amount" : 500 , "requires_approval" : true},
{ "action" : "customer.discount.apply" , "max_amount" : 20 , "requires_approval" : false},
{ "action" : "email.send" , "requires_approval" : false}
]
DevOps Automation
permissions = [
{ "action" : "deploy.staging" , "requires_approval" : false},
{ "action" : "deploy.production" , "requires_approval" : true},
{ "action" : "database.migrate.staging" , "requires_approval" : false},
{ "action" : "database.migrate.production" , "requires_approval" : true},
{ "action" : "logs.read" , "requires_approval" : false},
{ "action" : "server.restart" , "requires_approval" : true}
]
Data Processing
permissions = [
{ "action" : "database.read" , "requires_approval" : false},
{ "action" : "database.write" , "requires_approval" : false},
{ "action" : "api.fetch" , "requires_approval" : false},
{ "action" : "s3.upload" , "requires_approval" : false},
{ "action" : "database.delete" , "requires_approval" : true}
]
Next Steps