Guides
Delegation Guide
Let agents act on behalf of users with controlled, auditable delegations.
Delegation Guide
Delegations allow a human to grant an agent the right to act on their behalf at a specific service. Unlike regular grants (where the agent acts as itself), a delegated agent carries the human's identity — but only within the boundaries the human defined.
When to Use Delegations
| Scenario | Use |
|---|---|
| Agent runs a command as itself | Regular grant |
| Agent acts as a specific human | Delegation |
Examples:
- A bot that files GitHub issues as
alice@example.cominstead ofagent+bot@example.com - An agent that sends emails from a human's mailbox
- A browser automation that logs into a web app as a specific user
Create a Delegation
# Login as the human who wants to delegate
grapes login --idp https://id.example.com
# Delegate to the agent
grapes delegate \
--to agent+bot@example.com \
--at escapes \
--approval always \
--reason "Allow bot to act on my behalf for deployments"
Options
| Flag | Required | Description |
|---|---|---|
--to | Yes | Agent email that receives the delegation |
--at | Yes | Service/audience where the delegation applies |
--scopes | No | Comma-separated scopes (e.g., read,write) |
--approval | No | once, timed, always (default: once) |
--expires | No | ISO 8601 expiration (e.g., 2026-12-31T23:59:59Z) |
With Scopes
Scopes limit what the agent can do within the delegation:
# Only allow reading and commenting, not writing or deleting
grapes delegate \
--to agent+reviewer@example.com \
--at shapes \
--scopes "read,comment" \
--approval timed \
--expires "2026-04-01T00:00:00Z"
With Expiry
# Delegate for one week
grapes delegate \
--to agent+ops@example.com \
--at escapes \
--approval timed \
--expires "2026-03-29T23:59:59Z" \
--reason "On-call coverage while I'm on vacation"
List and Manage Delegations
# List active delegations
grapes delegations
grapes delegations --json
# Revoke a delegation (via API)
curl -X DELETE https://id.example.com/api/delegations/<id> \
-H "Authorization: Bearer <token>"
Using Delegations in @openape/browser
The browser package supports delegation login — the agent can log into web applications as the delegated user:
import { createGrantedBrowser } from '@openape/browser'
const browser = await createGrantedBrowser({
rulesFile: './rules.toml',
idpUrl: 'https://id.example.com',
agentEmail: 'agent+bot@example.com'
})
// Login as alice via delegation
await browser.loginAs({
email: 'alice@example.com',
delegationToken: '<delegation-jwt>'
})
// Browser now has alice's session
const page = await browser.newPage()
await page.goto('https://app.example.com/dashboard')
// → App sees alice@example.com, not agent+bot
How It Works
1. Alice delegates to agent+bot:
grapes delegate --to agent+bot@example.com --at shapes
2. Agent requests a grant, including delegator:
POST /api/grants { delegator: "alice@example.com", ... }
3. IdP checks:
- Does alice have an active delegation to this agent?
- Does the delegation cover this service/audience?
- Are the scopes sufficient?
4. If valid, the AuthZ-JWT includes:
{ sub: "agent+bot@example.com", delegator: "alice@example.com", ... }
5. Target system sees both identities:
- WHO is acting: agent+bot
- ON BEHALF OF: alice
- WHO approved: the approver
Delegation vs. Regular Grants
| Regular Grant | Delegation | |
|---|---|---|
| Agent identity | agent+bot@example.com | agent+bot@example.com |
| Acting as | Itself | The delegating human |
AuthZ-JWT sub | Agent email | Agent email |
AuthZ-JWT delegator | — | Human email |
| Use case | Agent's own actions | Acting on behalf of a user |
| Approval | Agent's approver | Delegating human + approver |
Security Considerations
- Delegations are traceable — the AuthZ-JWT always carries both the agent and the delegator identity
- Delegations can be scoped — limit to specific actions/services
- Delegations can expire — set an explicit end date
- Delegations are revocable — the human can revoke at any time
- The agent cannot create delegations for itself — only humans can delegate