Roles and Permissions
RBAC model, tenant scoping, authentication methods, delegation, and audit trail in AgentOwl.
AgentOwl uses a role-based access control (RBAC) model to govern who can perform operations across the platform. Every authenticated API request carries an operator identity, a role, and a tenant scope that together determine what the caller is allowed to do.
Roles overview
AgentOwl defines two human-operator roles. There are no end-user or read-only roles in v1 — the system is designed for operators and automation, not end-user inboxes.
| Role | Scope | Intended for |
|---|---|---|
platform-admin | Global — all tenants | Infrastructure operators who manage the entire AgentOwl deployment |
tenant-admin | Scoped — explicitly listed tenants only | Team leads or service owners who manage their own tenants |
Platform admin
A platform admin has unrestricted access to every resource and operation in the system. The role is designed for the small number of operators who provision and maintain the AgentOwl deployment itself.
Platform admins can:
- Create, list, read, and delete any tenant.
- Create and manage bindings, endpoints, routes, and policies for any tenant without being listed in a tenant scope.
- Trigger worker-role deployments.
- Query the audit log across all tenants or for a specific tenant.
- Publish, validate, diff, and roll back runtime configuration.
- Trigger provider reconciliation and view drift reports.
- View dead-letter entries and replay events.
When a platform admin authenticates, tenant_scope is null, which the authorization layer interprets as "access all tenants."
Tenant admin
A tenant admin has full administrative access, but only within the tenants explicitly listed in their tenant_scope array. Any request that touches a tenant outside that list receives a 403 Forbidden response.
Tenant admins can:
- List and read tenants they are scoped to.
- Create and manage bindings, endpoints, routes, and policies within their authorized tenants.
- Query the audit log for their own tenants (the
tenant_idquery parameter is required). - View events, dead letters, and replay events within their tenants.
Tenant admins cannot:
- Create new tenants.
- Trigger worker deployments.
- Query the audit log without specifying a
tenant_id. - Access any resource belonging to a tenant outside their scope.
Tenant scoping
Multi-tenancy is the core isolation boundary in AgentOwl. Every resource — bindings, endpoints, routes, policies, events — belongs to exactly one tenant. The authorization layer enforces this on every request.
How it works
Each authenticated request carries an AuthContext with a tenant_scope field:
platform-admin -> tenant_scope: null (global access)
tenant-admin -> tenant_scope: ["t_abc123"] (scoped access)Before any tenant-scoped operation executes, the system calls requireTenantAccess(auth, tenantId):
- If the caller is a
platform-admin, access is granted immediately. - If the caller is a
tenant-adminand the targettenantIdis in theirtenant_scopearray, access is granted. - Otherwise, the request is rejected with a
403 Forbiddenresponse.
Scoping in list operations
When a tenant-admin lists resources, the query is automatically filtered to only return results from their authorized tenants.
Permission matrix
| Operation | Platform admin | Tenant admin |
|---|---|---|
| Tenants | ||
| Create tenant | Yes | No |
| List tenants | All | Scoped only |
| Get tenant | Any | Scoped only |
| Delete tenant | Any | Scoped only |
| Bindings | ||
| Create binding | Any tenant | Scoped only |
| List bindings | Any tenant | Scoped only |
| Get binding | Any tenant | Scoped only |
| Delete binding | Any tenant | Scoped only |
| Endpoints | ||
| Create endpoint | Any tenant | Scoped only |
| List endpoints | Any tenant | Scoped only |
| Get / update endpoint | Any tenant | Scoped only |
| Delete endpoint | Any tenant | Scoped only |
| Routes | ||
| Create route | Any tenant | Scoped only |
| List routes | Any tenant | Scoped only |
| Get / update route | Any tenant | Scoped only |
| Delete route | Any tenant | Scoped only |
| Policies | ||
| Create policy | Any tenant | Scoped only |
| List policies | Any tenant | Scoped only |
| Get / update policy | Any tenant | Scoped only |
| Delete policy | Any tenant | Scoped only |
| Configuration | ||
| Validate config | Yes | Yes (scoped) |
| Diff config | Yes | Yes (scoped) |
| Publish config | Yes | Yes (scoped) |
| Rollback config | Yes | Yes (scoped) |
| Deployments | ||
| Trigger deployment | Yes | No |
| List deployments | Yes | No |
| Audit log | ||
| Query all tenants | Yes | No |
| Query own tenant | Yes | Yes |
| Events | ||
| List / get events | Any tenant | Scoped only |
| Replay event | Any tenant | Scoped only |
| Operations | ||
| Trigger reconciliation | Yes | Yes (scoped) |
| View drift | Yes | Yes (scoped) |
| View dead letters | Any tenant | Scoped only |
Authentication methods
AgentOwl supports three authentication methods. All use the Authorization: Bearer <token> header.
Bearer token
The simplest method. A pre-shared API key is stored in KV as a SHA-256 hash. The raw token is never persisted.
Authorization: Bearer aow_live_abc123...When to use: CLI scripts, CI/CD pipelines, initial platform setup.
OAuth
Human operators authenticate with an OAuth provider. AgentOwl validates the JWT claims against registered OAuth client configurations stored in KV.
When to use: Interactive human authentication, SSO integrations.
MCP-delegated
An extension of OAuth for automation. A human operator authorizes an MCP (Model Context Protocol) client to act on their behalf. The delegated token inherits the granting operator's role and tenant scope.
When to use: AI agents, automation workflows, MCP tool servers that need to call AgentOwl APIs on behalf of a human operator.
Delegation and revocation
MCP-delegated credentials can be revoked without invalidating the granting operator's own credentials. This is critical for scenarios where an automation client is compromised or decommissioned.
Revoking a delegation affects only the specific (delegated_by, automation_client_id) pair. The granting operator's own credentials remain valid.
Audit trail
Every authenticated API request is logged to the audit_log table with full actor attribution.
What is recorded
| Field | Description |
|---|---|
audit_id | Unique log entry ID |
timestamp | ISO 8601 timestamp |
operator_id | Who performed the action |
role | platform-admin or tenant-admin |
auth_method | bearer, oauth, or mcp-delegated |
tenant_id | Target tenant (if applicable) |
action | HTTP method + path |
resource_type | tenant, binding, endpoint, route, policy, etc. |
resource_id | ID of the affected resource |
request_id | Correlation ID for the request |
Access rules
- Platform admin: Can query with or without
tenant_id. Omitting it returns entries across all tenants. - Tenant admin: Must include
tenant_id, and it must be in their scope.
Best practices
For platform admins
- Use scoped tokens for automation. Even though platform-admin has global access, create tenant-scoped bearer tokens for CI/CD pipelines that only need to manage a single tenant.
- Rotate tokens regularly. Bearer tokens support
expires_at— set short-lived expiries and rotate. - Monitor the audit log. Regularly review the audit log for unexpected actions or unfamiliar operator IDs.
For tenant admins
- Request only the tenants you need. Your
tenant_scopeshould contain the minimum set of tenants required for your work. - Use MCP delegation for agents. Rather than sharing your bearer token with automation, set up MCP-delegated access so you can revoke it independently.
- Use dry-run for destructive operations. Tenant deletion supports
--planto preview what will be removed before executing.
For automation and MCP clients
- Prefer MCP delegation over shared tokens. Delegated access provides a clear audit trail back to the authorizing human and can be revoked without affecting other credentials.
- Handle revocation gracefully. If your delegation is revoked, surface the error to the operator who granted it rather than retrying.
- Include a descriptive User-Agent. The audit log records it, making it easier to identify which automation performed an action.