Reference/fleetless.yaml/Roles & Access

🔐 Roles & Access

role and access say which organisation role may use what a robot exposes. Both are optional, and both are the cloud’s alone: the robot is sent them and ignores them. The ideas, and what a role is, are on Roles and Rights; this page is the format.

yaml
fleetless: 1

access:
  assets: operate
  job_history: [operate]
  rules:
    - match: /arm/**
      role: admin
    - match: /diagnostics/*
      kinds: [read]
      role: maintenance

datapoints:
  battery_soc:
    topic: /battery
    type: sensor_msgs/msg/BatteryState
    field: percentage
  raw_diagnostics:
    topic: /diagnostics/raw
    type: diagnostic_msgs/msg/DiagnosticArray
    role: [maintenance, admin]

services:
  arm_home:
    ros_name: /arm/home
    type: std_srvs/srv/Trigger
    role: admin

Here battery_soc follows the organisation’s default for read, arm_home and everything else under /arm needs admin, and a datapoint under /diagnostics/ needs maintenance unless it names its own role, as raw_diagnostics does.

role on an entry

An optional field on every entry of datapoints, actions, services, publishers and cameras.

field type bounds absent means
role a role key, or a list of keys a key is lower-case, letter-initial, letters, digits and underscores, at most 63 characters, and not defaults; a list names 1 to 50 the first rule of access.rules that fits, then the organisation’s default for the entry’s kind

A list means any of them: holding one of the roles, or inheriting from one, is enough. An empty list is refused, because it would say nobody, which is already what a kind without a default means.

The kind an entry needs follows from its section:

section kind
datapoints, cameras read
actions, services invoke
publishers publish

An entry’s own role wins outright. The rules are not consulted for it.

access.rules

An ordered list that gives a role to every entry whose ROS name fits a pattern, so a namespace takes one line instead of one role per entry.

field type bounds absent means
match glob over a ROS name absolute, at most 255 characters required
kinds list one to three of read, invoke and publish the rule fits every kind
role a role key, or a list of keys as on an entry required

At most 100 rules. The glob works on whole name segments:

pattern fits does not fit
/arm/home /arm/home /arm, /arm/homing
/diagnostics/* /diagnostics/raw /diagnostics, /diagnostics/raw/left
/arm/** /arm, /arm/home, /arm/gripper/open /armature
/**/state /state, /arm/state, /arm/gripper/state /arm/state/raw
/joint_* /joint_1, /joint_left /joint, /arm/joint_1
  • * stands for one segment, and inside a segment for any characters (/joint_*).
  • ** stands for any number of whole segments, none included, so /arm/** fits /arm as well as everything below it. It stands alone as a segment: /ar** is refused.
  • A pattern is absolute, like every ROS name. A relative pattern or a trailing slash is refused as a schema error, not read as a warning.

The name an entry is matched by depends on its section:

section matched by
datapoints, publishers topic
actions, services ros_name
cameras source.topic, when source.kind is ros

A camera whose source is rtsp, mjpeg or v4l2 has no ROS name, so no rule fits it: give it a role, or the default decides. The built-in datapoint bridge_state has none either, and follows the default for read.

The first rule that fits decides. Put the narrow rule above the wide one:

yaml
access:
  rules:
    - match: /arm/gripper/**
      role: operate
    - match: /arm/**
      role: admin

/arm/gripper/open needs operate; the rest of /arm needs admin. Written the other way round, the second rule would never be reached.

kinds narrows a rule to the entries of those kinds: read is datapoints and cameras, invoke is services and actions, publish is publishers. A rule never touches assets or job_history.

access.assets and access.job_history

The two capabilities that belong to the robot as a whole. They have no ROS name, so rules cannot reach them.

field type bounds absent means
assets a role key, or a list of keys as on an entry the organisation’s default for assets
job_history a role key, or a list of keys as on an entry the organisation’s default for job_history

assets is the asset store, the URDF and the meshes, which give away the machine’s build. job_history is the past job runs; a run names the person who started it, so whoever reads it learns who else has been driving the robot. A caller whose role lacks either is refused with 403 capability_required.

Which one applies

For an entry, the first of these that exists:

  1. its own role;
  2. the role of the first rule of access.rules that fits it;
  3. the organisation’s default for its kind.

For assets and job_history: access.assets or access.job_history, then the organisation’s default. A kind without a default belongs to nobody.

Only the published version counts. A robot with nothing published has no entries, so it exposes nothing; its assets and job history follow the organisation’s defaults.

The warnings

A role the organisation does not have, and a rule that fits nothing, are published as usual. Neither is an error: the editor and the draft response list them as warnings, and the publish response carries all of the document’s warnings in warnings.

code when path
unknown_role a key names no role of the organisation. It grants nothing, and neither does inheritance through it. services.arm_home.role, access.rules[1].role, access.assets; in a list each key has its own index, as in services.arm_home.role[1]
rule_matches_nothing a rule fits no entry of this document, kinds included, so it changes nothing. access.rules[1].match

The messages read “services.arm_home names technician, which is no role of this organization.” and “Rule 2 matches nothing, so it changes nothing.” The message counts rules from 1 and the path counts from 0.

A malformed key, an empty list, an unknown key under access or a relative match are errors, and block the publish like any other.

The robot ignores both

The robot is sent the stored document unmutated, as it is for every field. It acts on neither role nor access, so a version that changes only them is stored and enforced at once and pushes no configuration to the robot (see what reaches the robot). Realtime subscriptions that a publish narrows are re-checked and end with forbidden.