#17505·OpenHands

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

  1. The existing API key is the admin key. Current behavior is preserved: one admin credential that can access every endpoint.
  2. The admin key can create named API keys scoped to either read or write permission. Keys are stored server-side with metadata (name, permission tier, creation time), keyed hashes only.
  3. Every HTTP endpoint and WebSocket message is classified as requiring admin, write, or read, enforced by the Agent Server backend on every operation. Hierarchy: admin inherits all write and read capabilities; write inherits all read capabilities.

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 read or write (no key with admin scope 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 (read or write) and stores only keyed hashes plus metadata.
  • Every existing HTTP route and WebSocket message type has an explicit admin / write / read classification, with a fail-closed default for anything unclassified.
  • Backend enforces the tier hierarchy: admin passes write/read checks, write passes read checks, read fails write/admin checks, write fails admin checks.
  • Existing session/API key authenticates as admin during 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.