Scoped API keys for Agent Server: admin / write / read
Author: neubigCreated Sep 17, 2026Updated Sep 17, 2026
Labelsenhancementagent-canvasready-for-devsecurity
Follow-up to #17055 ([RFC] Role-Based Access Control for the Agent Canvas). This issue tracks the narrow, first implementation slice agreed in the RFC discussion: instance-local, operator-provisioned named API keys with three fixed tiers. It deliberately does not implement the RFC's later-stage items (service delegation, live revocation of open sockets, egress policy, SSO/OIDC).
Desired Behavior
- The existing API key is the admin key. Current behavior is preserved: one admin credential that can access every endpoint.
- The admin key can create named API keys scoped to either
readorwritepermission. Keys are stored server-side with metadata (name, permission tier, creation time), keyed hashes only. - Every HTTP endpoint and WebSocket message is classified as requiring
admin,write, orread, enforced by the Agent Server backend on every operation. Hierarchy:admininherits allwriteandreadcapabilities;writeinherits allreadcapabilities.
Proposed tier capabilities (instance-local):
| Tier | Can do |
|---|---|
admin |
Everything in write/read, plus key management (create/revoke named keys) and instance administration |
write |
Everything in read, plus starting/guiding agent work, running automations, and other mutating operations |
read |
Observe conversations/automations and workspace artifacts; no state mutation, no execution |
Scope and non-goals
- Key management is admin-only; named keys can only be
readorwrite(no key withadminscope in this slice). - These keys bound API-level access and attribution only. They do not isolate what an agent does once running inside its sandbox; that remains a separate security problem.
- Out of scope for this issue: user accounts/passwords, SSO/OIDC/SAML, per-conversation ACLs, service delegation identities, expired/revoked WebSocket sessions, egress policy, multi-node tenancy.
Acceptance Criteria
- Backend exposes an admin-only endpoint to create named keys (
readorwrite) and stores only keyed hashes plus metadata. - Every existing HTTP route and WebSocket message type has an explicit
admin/write/readclassification, with a fail-closed default for anything unclassified. - Backend enforces the tier hierarchy:
adminpasses write/read checks,writepasses read checks,readfails write/admin checks,writefails admin checks. - Existing session/API key authenticates as
adminduring migration (no breaking change). - An authenticated identity endpoint (e.g.
GET /api/auth/whoami) reports the current principal, tier, and effective capabilities. - Client (Agent Canvas / typescript-client) hides or disables actions the current principal cannot perform, with UI acting as affordance only — never the security boundary.
- Adversarial tests cover: admin key creation of named keys, read-tier mutation attempts rejected, write-tier admin-only operations rejected, and unclassified routes/messages fail closed.
Source: OpenHands/OpenHands