RFC-0011: Access-Aware Coordination v2.0#
Status: Proposed
Created: 2026-02-01
Updated: 2026-02-07
Authors: OpenIntent Contributors
Requires: RFC-0001 (Intents), RFC-0003 (Leasing)
Abstract#
This RFC adds a unified permissions model to OpenIntent. One field on each workflow phase controls who can access it, what context agents receive, and whether work can be delegated. It replaces the previous three separate fields (access, delegation, context) with a single block that supports both shorthand strings for common cases and a full object form for fine-grained control.
Quick Start#
Most workflows only need a one-liner. The permissions field accepts a string, a list of agent IDs, or a full object.
workflow:
# No restrictions (default if omitted)
research:
assign: researcher
permissions: open
# Only the assigned agent can access
extraction:
assign: ocr-agent
permissions: private
# Specific agents get write, others get read
analysis:
assign: analyst
permissions: [analyst, auditor]
In Python, permissions are typed with enums and dataclasses:
from openintent.workflow import AccessPolicy
from openintent import PermissionsConfig, PermissionLevel
# Shorthand — parsed from YAML automatically
config = PermissionsConfig.from_yaml("private")
config = PermissionsConfig.from_yaml(["analyst", "auditor"])
# Or construct directly
config = PermissionsConfig(
policy=AccessPolicy.RESTRICTED,
default=PermissionLevel.READ,
)
The Permissions Model#
Permission Levels#
Three cumulative levels. Each includes all capabilities of the level below it.
| Level | Capabilities |
|---|---|
read |
View intent metadata, state, events, attachments, cost summaries. Subscribe to events. |
write |
Patch state, emit events, acquire leases, add attachments, record costs. |
admin |
Change status, modify permissions, configure retry, create child intents, manage delegation. |
Access Policies#
| Policy | Description |
|---|---|
open |
Any agent can access at the default permission level. This is the default. |
restricted |
Only agents declared in the workflow (or in the allow list) can access. |
private |
Only the assigned agent has access. Others must be explicitly granted via the allow list. |
Full Permissions Object#
When you need fine-grained control, the permissions field accepts an object with five optional subkeys:
workflow:
sensitive_analysis:
title: "Analyze Sensitive Data"
assign: analyst
permissions:
policy: restricted
default: read
allow:
- agent: "analyst"
level: write
- agent: "auditor"
level: read
expires: "2026-12-31T00:00:00Z"
delegate:
to: ["specialist-bot"]
level: read
context: [dependencies, peers, acl]
Context Injection#
The context subkey controls what information the server auto-populates in intent.ctx when an agent receives work.
| Field | Description |
|---|---|
dependencies |
Outputs from upstream phases (keyed by phase name) |
peers |
Sibling intents under the same parent |
parent |
Parent intent metadata |
events |
Recent event log entries |
acl |
Current access control list (admin only) |
delegated_by |
Which agent delegated this work |
Set context: auto (the default) and the server decides what to inject based on the agent's permission level. Set context: none to disable context injection entirely.
Python SDK#
End-to-End Example#
An agent declares capabilities, receives auto-populated context, analyzes data, and delegates or escalates based on results.
@Agent("analyst", capabilities=["compliance", "risk-analysis"])
class AnalystAgent:
@on_assignment
async def work(self, intent):
# Context is auto-populated based on permissions
extraction = intent.ctx.dependencies.get("extraction", {})
text = extraction.get("text", "")
risk = await self.analyze(text)
if risk > 0.8:
# Escalate to a human when risk is high
await intent.escalate(reason="High risk", data={"score": risk})
if self.needs_specialist(text):
# Delegate to another agent with scoped access
await intent.delegate("specialist-bot")
return {"status": "reviewed", "risk_score": risk}
@on_access_requested
async def policy(self, request):
# Policy-as-code: approve read, defer everything else
return "approve" if request.level == "read" else "defer"
Scoped Temporary Access#
Grant temporary access that is automatically revoked when the block exits, even on exceptions.
async with self.temp_access(intent.id, "helper-agent", "write"):
await self.client.assign_agent(intent.id, "helper-agent")
# access is revoked automatically when the block exits
Endpoints#
Permissions Management#
| Method | Path | Description |
|---|---|---|
GET |
/v1/intents/{id}/acl |
Get the intent's access control list |
PUT |
/v1/intents/{id}/acl |
Replace the intent's ACL |
POST |
/v1/intents/{id}/acl/entries |
Grant access to an agent |
DELETE |
/v1/intents/{id}/acl/entries/{entryId} |
Revoke an agent's access |
Access Requests#
| Method | Path | Description |
|---|---|---|
POST |
/v1/intents/{id}/access-requests |
Request access to an intent |
GET |
/v1/intents/{id}/access-requests |
List pending access requests |
POST |
/v1/intents/{id}/access-requests/{reqId}/approve |
Approve a request |
POST |
/v1/intents/{id}/access-requests/{reqId}/deny |
Deny a request |
Event Types#
| Event Type | Description |
|---|---|
access_granted |
An agent was granted access to an intent |
access_revoked |
An agent's access was revoked |
access_expired |
A time-limited access grant expired |
access_requested |
An agent requested access to an intent |
access_request_approved |
An access request was approved |
access_request_denied |
An access request was denied |
All events include the actor field, maintaining the protocol's append-only audit trail.
Backward Compatibility#
Fully backward compatible with existing OpenIntent deployments:
- No permissions = open access: Intents without a permissions field work exactly as before.
- Context is additive: The
intent.ctxobject is new. Agents that don't use it are unaffected. - Legacy fields: The old
access,delegation, andcontextYAML fields are still parsed and automatically converted to the unifiedpermissionsformat. - Decorators are opt-in:
@on_access_requestedis optional. Without it, access requests flow through the governance pipeline (RFC-0003).