guides
Intended Documentation
ROS2 Integration
Layer Intended Authority Tokens onto a ROS2 agent — cobot, AMR, drone, surgical — using the intended-ros2 package over the cloud authority API.
Integrating Intended on ROS2#
Audience: robotics engineers shipping ROS2 agents (cobots, AMRs, drones, surgical robots) who want to gate state-changing actions on an Intended Authority Token.
Prereqs: ROS2 Humble or newer, Python 3.10+, an Intended tenant API key.
ROS2 has good primitives for what a robot is doing. It has no primitive for whether the robot is allowed to do it. The moment an LLM, planner, or operator command becomes the source of an action, you want an auditable record of which OI category it falls under, a short-lived signed credential the controller checks before commanding motors, and a safe-default fallback if that credential is denied or expires. Intended is that layer.
Architecture#
The node mediates: your agent never calls the cloud directly. Your safety-bus data never leaves your network — you read it and submit a structured snapshot. Token verification today is the cloud round-trip; a dedicated edge verifier is roadmap.
Install#
Configure#
INTENDED_ACTOR_IDENTITY should be the IEEE 802.1AR DevID of your robot once provisioned; until then any stable identifier works. It must be registered before it can be authorized.
Register the actor (once)#
Calling from your agent#
The structured goal is a ROS2 action shape, not English. From a Python node:
Snapshot, don't read
Intended never reads your safety bus. Your _snapshot_required_predicates() builds a predicate → PhysicalStateValue map from your bus/DDS reads and submits it. The discriminated union and attestation protocols are in the API reference wire format.
Implementing the state bridge#
Bridge each safety-bus signal into a structured predicate with honest attestation:
safetyRated: true and protocol: "fsoe" are the load-bearing claims. If your policy requires safety-rated input and the bus drops to an untrusted channel (or returns unavailable), the cloud denies on attestation grounds.
Verifying the token#
Today: the controller treats the token as valid if decision == "ALLOW", expiresAtMs > now(), and the signature checks out against /.well-known/jwks.json.
Set the verifier audience to intended-edge-verifier
The cloud signs tokens with aud: "intended-edge-verifier". The sample verifier in the intended-ros2 package defaults expected_audience="intended-edge" — set your verifier's expected audience to intended-edge-verifier so it matches what the issuer actually emits, otherwise valid tokens are rejected. The dedicated edge verifier binary that would standardize this is roadmap.
Common patterns#
- Behavior trees (BehaviorTree.CPP). Wrap the issuance call so an
ESCALATEdecision (HTTP 200 withescalationTicketId) pauses the tree; resume when an operator approves via/approvals/{ticketId}/decide, then re-issue withoperatorTicketIdset. - Real-time controllers (ros2_control). Never issue from the controller update loop — the cloud round-trip starves the deadline. Pre-issue from a non-RT planner and pass the token down via the command interface.
- Multi-robot fleets. One issuance path per robot; tokens bind to
actorIdentity, so a token forcobot-east-3carries thatsuband cannot be presented forcobot-east-4.
Troubleshooting#
| Symptom | Likely cause | Fix |
|---|---|---|
403 actor_not_registered | Actor not on the roster | POST /v1/physical/actors for this actorIdentity. |
| Every valid token rejected at verify | Verifier expects intended-edge, issuer mints intended-edge-verifier | Set verifier audience to intended-edge-verifier. |
422 policy_denied with an attestation clause | Predicates marked protocol: untrusted but policy requires safety-rated | Wire the safety bus; set safetyRated: true. |
failClosed: true on a novel goal | No classifier rule matched | Supply an explicit oiCode, or extend the corpus / use a learned-model fallback. |
| Token expires before motion starts | deadlineMs shorter than trajectory dispatch | Issue closer to motion, or widen the deadline. |
See also#
- pick-and-place reference — a runnable example of this flow.
- Authority API reference — every endpoint, claim, error.
- Safety-case writing — extending the integration into your machine's safety case.