Skip to content

Add token auth and role-gated subscriber permissions #28

@lsaether

Description

@lsaether

Feature

Add minimal token authentication plus role-gated subscriber permissions for multi-client ACP sessions.

Motivation

Once acp-mux is used from a phone, browser, remote desktop, or other companion client, every attached peer should not automatically have full control. The mux should distinguish watching, prompting, approving tool permissions, and administrative cancellation.

This is a better Hermes-first priority than broad fs/* / terminal/* compatibility because Hermes already executes tools inside the agent process. For Hermes users, the real risk is accidental or overprivileged session control from secondary clients.

Proposed roles

Suggested initial roles:

Role Can view stream Can prompt Can answer permission requests Can cancel active turn / admin actions
observer yes no no no
driver yes yes no own turn only, if implemented
approver yes no yes no
admin yes yes yes yes

Keep this intentionally small. More roles can come later if real clients need them.

Proposed auth shape

Prefer token-derived roles over trusting the role= query parameter.

One possible config:

{
  "tokens": [
    { "name": "desktop", "token": "REPLACE_WITH_RANDOM_TOKEN", "role": "admin" },
    { "name": "phone", "token": "REPLACE_WITH_RANDOM_TOKEN", "role": "driver" },
    { "name": "wallboard", "token": "REPLACE_WITH_RANDOM_TOKEN", "role": "observer" }
  ]
}

Possible flag:

amux --auth-file ~/.config/acp-mux/auth.json --agent-cmd 'hermes acp'

Transport:

  • Prefer Authorization: Bearer <token> where the client can set headers.
  • Allow ?token=<token> as a browser/WebSocket fallback if needed, but redact tokens from logs and debug endpoints.
  • The authenticated token assigns the effective role. The query role= value can remain a display/client hint only, or be ignored when auth is enabled.

Enforcement points

  • observer cannot send session/prompt or any mutating subscriber -> agent request.
  • driver can send session/prompt but cannot answer session/request_permission unless also allowed by policy.
  • approver can answer mux-fanned-out permission requests but cannot prompt.
  • admin can prompt, approve, and call amux/cancel_active_turn.
  • Unauthorized requests receive a JSON-RPC error with a stable code/message and are not forwarded upstream.
  • /debug/sessions must not expose raw tokens.

Non-goals

  • No OAuth.
  • No user database.
  • No cross-host identity/federation.
  • No browser UI in this issue.

Acceptance criteria

  • Tests cover missing/invalid token rejection when auth is enabled.
  • Tests cover token-derived role assignment and prove a client cannot escalate by changing role= in the URL.
  • Tests prove observer cannot prompt.
  • Tests prove driver can prompt but cannot approve a permission request.
  • Tests prove approver can approve/deny a permission request but cannot prompt.
  • Tests prove admin can call amux/cancel_active_turn.
  • Logs and /debug/sessions redact or omit token values.
  • README documents auth setup with placeholder tokens only.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions