Skip to content

Grant, approve and surface paired-device capabilities #15145

Open

Description

@mrveiss

Follow-up to #14964 (part of #14958).

Problem

#14964 gave desktop_mobile_devices a capability set (permissions), an approval flag
(is_approved) and a soft-revocation field (revoked_at), and wired a positive capability
assertion into the remote-control WebSocket guards. Backfill and column defaults are deny,
which is correct — but the consequence is that no code path can move a credential out of the
denied state
. There is a revoke path (POST /api/devices/{id}/revoke) and no grant path.

Concretely missing:

  1. No grant/approval path. Nothing sets is_approved or writes into permissions. A device
    can only be granted a capability by a direct database write, which is not an operator action.
  2. No visibility. DeviceResponse and the device list do not expose permissions,
    is_approved or revoked_at, so a user cannot see that a device is revoked or what it may do.
    A revoked device is listed indistinguishably from an active one.

Proposed approach

  • Owner-scoped endpoints to approve a device and to set its capability set, writing through
    autobot_shared.auth.device_capabilities.serialise_device_permissions so unknown names are
    dropped at the boundary rather than stored.
  • Extend the device response with the three fields, and surface them in the paired-devices UI
    (all 11 locales).
  • Grants are privilege escalation: each one needs an audit record, the way
    services/device_jwt.mint_device_jwt already records a mint.

Constraints

  • The denied default must survive: a grant is an explicit act, never a side effect of pairing.
  • Response-shape changes touch generated frontend types (frontend-codegen-drift).

Acceptance criteria

  • An owner can approve a paired device and set its capabilities through the API.
  • Unknown capability names are rejected or dropped at the write boundary, never stored.
  • Every grant and revocation produces an audit record naming the actor.
  • The device list shows approval, capability and revocation state.
  • Pairing still produces a denied credential; a test asserts a freshly paired device holds
    no capability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions