openvibers/openvibe.network Commits

Network: a person's OpenVibe.Actor agent may read and drive their OpenVibe.Bot robot (grants bot.robot.read, bot.robot.control) (#175)

OP OpenVibers committed 14 Oct 2026 · 414c7209a6 · 1 file, +5 −0

Plan T15 and T17: a person's OpenVibe.Actor agent can pilot their own robot.

The owner opts in per robot on OpenVibe.Bot ("Let my OpenVibe.Actor agent drive this robot", `robots.agent_control`). After that, Actor reads the robot and sends it step lines or commands as that owner, using `X-OV-Subject`. Bot's gate, limits, cooldowns and e-stop still judge every step. Bot refuses `svc:actor` for anyone but the robot's owner, and on any robot where the switch is off.

For that, Actor's service token for audience `openvibe.bot` needs two capabilities:
- `bot.robot.read`, for `GET /api/v1/robots?owner=` and `GET /api/v1/robots/:id/steps`;
- `bot.robot.control`, for `POST /api/v1/robots/:id/steps` and `/commands`.

**Change**
- Two new default grants in `server/identity/principals.js`: `['actor', 'bot.robot.read', 'openvibe.bot', []]` and `['actor', 'bot.robot.control', 'openvibe.bot', []]`.
- They are seeded at boot like the others. Both are new, so no RESTORED_GRANTS entry is needed.

**Tests**
- `principals`, `service-principal`, `restored-grants` and `grants-admin` pass.

Changes

ddiff --git a/server/identity/principals.js b/server/identity/principals.js
iindex f5d4a403..ba7a29ef 100644
---- a/server/identity/principals.js
++++ b/server/identity/principals.js
@@@ -257,6 +257,11 @@ const DEFAULT_GRANTS = [
// POST /api/v1/robots/:id/commands with X-OV-Subject naming the viewer, so Bot's roles, queue, cooldowns and e-stop
// judge each one as that person (Live has no robot code of its own since Live's controls were deleted).
['live', 'bot.robot.control', 'openvibe.bot', []],
++ // Plan T15/T17: a person's OpenVibe.Actor agent pilots their robot. Bot answers it only for the robot's owner
++ // (X-OV-Subject) and only where that owner turned on "Let my OpenVibe.Actor agent drive this robot"
++ // (robots.agent_control); its gate, limits and e-stop still judge every step.
++ ['actor', 'bot.robot.read', 'openvibe.bot', []],
++ ['actor', 'bot.robot.control', 'openvibe.bot', []],
// Plan T2 lane B step 3: Host places and runs per project, so it reads a project's tenancy, placement and quotas.
// Other services get this row only when they ship a caller of GET /internal/projects/:project_id.
['host', 'network.project.read', SELF_AUDIENCE, []],