Grants, revoke and unpair
Allow one capability at a time, take it back, or forget the device. Every change counts on the next call.
A grant is the person's yes to one capability on one device. There are no wildcard grants: allowing read_light allows nothing else.
Allow
At pairing, through the grant list in the person's answer:
consent: async (req) => ({ approved: true, grant: ["read_light"] })Or later:
registry.grant("desk-lamp", "set_light");grant throws if the device is not paired, or has no capability by that name.
Take it back
registry.revoke("desk-lamp", "set_light"); // that one capability
registry.unpair("desk-lamp"); // the whole device, grants and tokenBoth count on the next call. Grants are read on every call and never cached, so a revoked capability is refused on the next call, and on any call still waiting for the person. A call already sent to the device cannot be recalled, and v1 does not tell the device it was revoked. After unpair the device's token no longer authenticates and it has to pair again.
If a call is waiting for the person's approval when the capability is revoked, or the device is unpaired or paired again, the call is refused once the approval comes back.
Looking at what is allowed
| Call | Returns |
|---|---|
registry.isPaired(deviceId) | true if paired |
registry.isGranted(deviceId, capability) | true if that capability is allowed now |
registry.get(deviceId) | The pairing: manifest, digest, token hash, grants, pairedAt. A live object: read it, never change it, never send it to a device or the agent. |
registry.list() | Every pairing |
v1 has no screen for this. Showing paired devices in the TUI is a later slice.
Next: Capabilities as agent tools.