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

action
string
required
The action identifier (e.g., stripe.refund, email.send, database.write)
requires_approval
boolean
default:"false"
Whether this action requires human approval before execution
max_amount
float
Maximum monetary amount allowed (if applicable to the action)

Creating Permissions

Via Dashboard

1

Open Agent

Navigate to Agents and click on your agent
2

Add Permission

Click Add Permission
3

Configure

  • Enter the action name
  • Set max_amount (if applicable)
  • Toggle requires_approval if needed
4

Save

Click Create

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

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:
  1. Agent attempts actionguard.check() called
  2. Permission check returnsallowed: false, requires_approval: true
  3. Approval request created → Visible in dashboard
  4. Human reviews → Approves or denies
  5. 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

1

Open Agent

Navigate to your agent
2

Find Permission

Locate the permission to delete
3

Delete

Click the delete icon
4

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

Begin with stricter permissions and approval requirements. Relax them as you gain confidence in your agent’s behavior.
Avoid generic names like action1 or do_thing. Use descriptive names that clearly indicate what the action does.
Consider the business impact of each action and set max_amount accordingly. Don’t set limits too high “just in case”.
Any action with significant business impact should require approval, especially:
  • Large financial transactions
  • Production deployments
  • Data deletions
  • External API calls with rate limits
Audit your permissions quarterly to ensure they still make sense as your agents evolve.
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