Skip to content
AgentField

Access control between agents

Allow or deny cross-agent calls based on tags, function names, and even argument values.

Cross-agent calls go through a policy engine. Match by tag, restrict to specific functions, and add argument-level constraints — analytics agents can call payments.balance_check but never payments.transfer, and only when amount < 10000.

from agentfield import Agent

# Tag the target — policies match on tags, not on agent IDs
app = Agent(
    node_id="treasury",
    version="1.0.0",
    tags=["finance", "transfers"],
)

@app.reasoner()
async def transfer(amount: float, execution_context=None) -> dict:
    # By the time this runs, the policy engine has already approved the call
    return {"transferred": amount, "caller": execution_context.caller_did}

app.run()

Define the policy once via the admin API:

# Allow finance-ops to read and transfer, but only under 10k, and never delete
curl -X POST http://localhost:8080/api/v1/admin/policies \
  -H "Content-Type: application/json" -d '{
    "name": "Finance ops — bounded transfer access",
    "caller_tags": ["finance-ops"],
    "target_tags": ["finance"],
    "allow_functions": ["transfer", "balance_check"],
    "deny_functions": ["delete_account", "modify_ledger"],
    "constraints": {
      "amount": {"operator": "<", "value": 10000}
    },
    "action": "allow",
    "priority": 100
  }'

# Block analytics from finance entirely
curl -X POST http://localhost:8080/api/v1/admin/policies \
  -H "Content-Type: application/json" -d '{
    "name": "Analytics blocked from finance",
    "caller_tags": ["analytics"],
    "target_tags": ["finance"],
    "deny_functions": ["*"],
    "action": "deny",
    "priority": 200
  }'

Tags and policies are managed and inspected from the Access management page in the control plane UI. Existing rules are listed priority-ordered with caller→target tag flow, allow/deny pills, and per-row edit:

Access management page showing three policies: analytics→finance deny, finance-ops→finance/transfers allow, compliance/auditor→* allow

The Create Policy dialog takes caller and target tags, allow/deny functions (with wildcards), and a priority:

Create Policy dialog showing the auditor read-only finance policy with caller tags, target tags, allowed functions, and priority

What callers see at runtime:

  • Agent tagged ["finance-ops"] calling treasury.transfer with amount=5000 → 200 OK
  • Same caller calling treasury.transfer with amount=50000 → 403 (constraint failed)
  • Agent tagged ["analytics"] calling treasury.balance_check → 403 (higher-priority deny)

What this gives you

  • Function-level granularity, not just agent-to-agent.
  • Argument constraints close the "right function, wrong amount" hole.
  • Priority + first-match-wins makes deny rules trivial to layer on.

Next