Robotics is full of experimentation: evaluating different hardware and software, pushing ahead with what works, and culling what doesn’t. ROS was designed to be flexible to enable this experimentation; to allow existing components to easily be combined with new ones or swapped with others. In ROS 1, this flexibility was valued above all else, at the cost of security. By virtue of being designed on top of DDS, ROS 2 is able to retain that flexibility while obtaining the ability to be secured by properly utilizing the DDS-Security specification. This article describes how ROS 2 integrates with DDS-Security.
Authors: Kyle Fazzari
Date Written: 2019-07
Last Modified: 2020-07
The DDS-Security specification expands upon the DDS specification, adding security enhancements by defining a Service Plugin Interface (SPI) architecture, a set of builtin implementations of the SPIs, and the security model enforced by the SPIs. Specifically, there are five SPIs defined:
ROS 2’s security features currently utilize only the first three. This is due to the fact that neither Logging nor Data Tagging are required in order to be compliant with the DDS-Security spec (see section 2.3), and thus not all DDS implementations support them. Let’s delve a little further into those first three plugins.
The Authentication plugin (see section 8.3 of the DDS-Security spec) is central to the entire SPI architecture, as it provides the concept of a confirmed identity without which further enforcement would be impossible (e.g. it would be awfully hard to make sure a given ROS identity could only access specific topics if it was impossible to securely determine which identity it was).
The SPI architecture allows for a number of potential authentication schemes, but ROS 2 uses the builtin authentication plugin (called “DDS:Auth:PKI-DH”, see section 9.3 of the DDS-Security spec), which uses the proven Public Key Infrastructure (PKI). It requires a public and private key per domain participant, as well as an x.509 certificate that binds the participant’s public key to a specific name. Each x.509 certificate must be signed by (or have a signature chain to) a specific Certificate Authority (CA) that the plugin is configured to trust.
The rationale for using the builtin plugin as opposed to anything else is twofold:
The Access control plugin (see section 8.4 of the DDS-Security spec) deals with defining and enforcing restrictions on the DDS-related capabilities of a given domain participant. For example, it allows a user to restrict a particular participant to a specific DDS domain, or only allow the participant to read from or write to specific DDS topics, etc.
Again the SPI architecture allows for some flexibility in how the plugins accomplish this task, but ROS 2 uses the builtin access control plugin (called “DDS:Access:Permission”, see section 9.4 of the DDS-Security spec), which again uses PKI. It requires two files per domain participant:
Both of these files must be signed by a CA which the plugin is configured to trust. This may be the same CA that the Authentication plugin trusts, but that isn’t required.
The rationale for using the builtin plugin as opposed to anything else is the same as the Authentication plugin:
The Cryptographic plugin (see section 8.5 of the DDS-Security spec) is where all the cryptography-related operations are handled: encryption, decryption, signing, hashing, etc. Both the Authentication and Access control plugins utilize the capabilities of the Cryptographic plugin in order to verify signatures, etc. This is also where the functionality to encrypt DDS topic communication resides.
While the SPI architecture again allows for a number of possibilities, ROS 2 uses the builtin cryptographic plugin (called “DDS:Crypto:AES-GCM-GMAC”, see section 9.5 of the DDS-Security spec), which provides authenticated encryption using Advanced Encryption Standard (AES) in Galois Counter Mode (AES-GCM).
The rationale for using the builtin plugin as opposed to anything else is the same as the other plugins:
Now that we have established some shared understanding of how security is supported in DDS, let’s discuss how that support is exposed in ROS 2. By default, none of the security features of DDS are enabled in ROS 2. The set of features and tools in ROS 2 that are used to enable them are collectively named “Secure ROS 2” (SROS 2).
Most of the user-facing runtime support for SROS 2 is contained within the ROS Client Library. Once its requirements are satisfied it takes care of configuring the middleware support for each supported DDS implementation. RCL includes the following features for SROS 2:
Let’s discuss each of these in turn.
As stated earlier, the DDS-Security plugins require a set of security files (e.g. keys, governance and permissions files, etc.) per domain participant. Domain participants map to a context within process in ROS 2, so each process requires a set of these files. RCL supports being pointed at a directory containing security files in two different ways:
Let’s delve further into these.
RCL supports finding security files in one directory that is inside the reserved enclaves
subfolder, within the root keystore, corresponding to the fully-qualified path of every enclave.
For example, for the /front/camera
enclave, the directory structure would look like:
<root>
├── enclaves
│ └── front
│ └── camera
│ ├── cert.pem
│ ├── key.pem
│ ├── ...
└── public
├── ...
The set of files expected within each enclave instance directory are:
This can be specified by setting the ROS_SECURITY_KEYSTORE
environment variable to point to the root of the keystore directory tree, and then specifying the enclave path using the --ros-args
runtime argument -e
, --enclave
, e.g.:
export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
ros2 run <package> <executable> --ros-args --enclave="/front/camera"
RCL also supports specifying the enclave path for the process that needs to be launched using an overriding environmental variable.
This can be done by setting the ROS_SECURITY_ENCLAVE_OVERRIDE
environment variable to an alternate enclave path within the keystore.
Note that this setting takes precedence over ROS_SECURITY_KEYSTORE
with --enclave
.
Note that the following two examples load from the same enclave path as demonstrated prior:
export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
export ROS_SECURITY_ENCLAVE_OVERRIDE="/front/camera"
ros2 run <package> <executable>
export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
export ROS_SECURITY_ENCLAVE_OVERRIDE="/front/camera"
ros2 run <package> <executable> --ros-args --enclave="/spam"
Participants with the security features enabled will not communicate with participants that don’t, but what should RCL do if one tries to launch a participant that has no discernable enclave with keys/permissions/etc.? It has two options:
The type of mode desired can be specified by setting the ROS_SECURITY_STRATEGY
environment variable to “Enforce” (case-sensitive) for strict mode, and anything else for permissive mode.
In addition to the supported features just discussed, RCL also supports a master shutoff for security features for easy experimentation. If it’s turned off (the default), none of the above security features will be enabled.
In order to enable SROS 2, set the ROS_SECURITY_ENABLE
environment variable to “true” (case-sensitive).
To disable, set to any other value.
Configuring a ROS 2 system to be secure in RCL involves a lot of new technology (PKI, DDS governance and permissions files and their syntax, etc.).
If a user is comfortable with these technologies, the above information should be all that’s necessary to properly lock things down.
However, the SROS 2 CLI should include a tool ros2 security
to help those who don’t want to set it all up themselves, including the following capabilities: