Hi all, my team at Amazon has been working on security tools for ROS2 (see related thread), and as part of that effort we’d like to help with adding support for secure CLI.
- What does this mean?
In essence, being able to create keys & define a permission policy for ros2cli, enabling all CLI commands (such as
ros2 topic echo/pub,
ros2 param set/get, as well as
ros2 bag) to operate with those permissions and using the supported DDS security plugins (authentication, encryption, access control).
- Why isn’t it supported today?
Part of the issue lies with the fact that the CLI tool starts up different nodes using different names, and sometimes those names are only determined at runtime (e.g. due to appending the process ID to the name). The security directory lookup is done by the node’s name, overall making it unfeasible to generate and use keys & security settings for CLI nodes.
Approaches to enabling security for ros2cli
We have investigated a few possible solutions and have a proof of concept working for one (Option C). We’d appreciate your input before proceeding.
Option A: Consistent node naming, known at compile time. This essentially means having all CLI nodes use the same name (for example, “ros2cli_node”). This is the simplest approach; however, while non-unique node names should be possible with DDS, ROS2 makes no such guarantee and empirically this has been shown to cause problems .
Option B: External override to the node’s security directory. This is the approach proposed by ruffsl at https://github.com/ros2/sros2/issues/69 and it involves allowing a special environment variable to override the security directory lookup for the node.
Usage could look something like,
ROS_SECURITY_NODE_DIRECTORY=~/ros2cli_keys ros2 topic echo /sometopic
or potentially having the ros2cli tool supply that environment variable when invoked with a special flag.
Overall this is a good approach, but it relies on environment variables which could be error-prone and introduces the minor inconvenience of having to invoke the CLI tool in a different manner.
Option C: Directory lookup based on longest-prefix match rather than an exact match, and have all CLI nodes use the same predetermined prefix. Thus when a node named
_ros2cli_node_12498starts up, it would settle for the directory
_ros2cli_nodeif it can’t find any better match.
From the user’s perspective, usage would stay exactly the same. Since CLI nodes would start with the same prefix, say _ros2cli_node, you could simply setup security for all CLI nodes by using that prefix, e.g.:
ros2 security create_key <key store> _ros2cli_node
Thoughts on the different approaches discussed? Is there a potential problem we missed? Is there a fourth option worth considering?
Hidden node feature
Currently, the subscriber node (the one used for
ros2 topic echo ) is started as “hidden” (underscore prefix). If we keep that discrepancy, with Option C users would need to generate two sets of keys & policies:
ros2 security create_key <key store> _ros2cli_nodeto grant permissions to hidden CLI nodes
ros2 security create_key <key store> ros2cli_nodeto grant permissions to all other CLI nodes
This obviously complicates the setup, but regardless - What’s the use case for that discrepancy between the CLI nodes? Is that a discrepancy we’d want to keep? in ROS1, CLI nodes are all visible as far as I know. Considering that this functionality is at the CLI layer and can be easily ignored with --all, I wonder whether that discrepancy is something worth keeping.
We’d greatly appreciate any thoughts you might have on the various options presented, as well as on the matter of aligning the CLI nodes’ prefix.