Using RTI Security Plugins with Topic Aliasing ============================================== The combination of *RTI Security Plugins* and ROS 2 topic aliasing is supported (so is type aliasing, but this has no interoperability impact with the *Security Plugins*). .. note:: We recommend updating your Permissions and Governance documents to include both the real topic name and the demangled topic name when using topic aliases. Otherwise, you may observe unexpected results when communicating with *Connext* versions in which topic aliasing is not supported. See :ref:`ros-security-troubleshooting`. The following examples demonstrate updating the Permissions and Governance documents. .. _update-permissions-gov-docs: Update Permissions and Governance Documents ------------------------------------------- Permissions documents determine whether a participant is allowed to create a writer or reader and whether a remote writer or reader is allowed to communicate with local endpoints. If you are using a Permissions document with an ```` to publish the topic ``Foo``, we recommend updating this topic rule to the following: .. code-block:: xml Foo rt/Foo Alternatively, you can use an expression that matches both topic names, such as the following: .. code-block:: xml *Foo If using a Governance document to configure the protection rules of type ``Foo``, we recommend updating the document to include topic rules for both ``Foo`` and ``rt/Foo``: .. code-block:: xml Foo TRUE TRUE TRUE TRUE ENCRYPT ENCRYPT rt/Foo TRUE TRUE TRUE TRUE ENCRYPT ENCRYPT Alternatively, you can use an expression that matches both topic names, such as the following: .. code-block:: xml *Foo TRUE TRUE TRUE TRUE ENCRYPT ENCRYPT See `Access Control `__ in the *RTI Security Plugins User's Manual* for more information on Permissions and Governance documents. .. _ros-security-troubleshooting: If You Do Not Update Permissions and Governance Documents --------------------------------------------------------- When ROS 2 interoperability is enabled (``dds.ros.enable_interoperability`` is set to ``TRUE`` in a *Connext* application, or a ROS 2 application is using the *Connext* RMW with *Connext* 7.7.0+), some automatic conversion between *Connext* and ROS 2 topic names is done when evaluating permissions and selecting a governance policy. This feature is intended to allow you to reuse Permissions and Governance files from already existing ROS 2 applications, rather than having to update and re-sign these files when introducing *Connext* applications into your system. However, if you are able to update and re-sign your files, we highly recommend updating them to include both the topic and topic alias with the same settings, to avoid assymetric discovery. For example, your *Connext* 7.7.0+ application will allow both *Connext* and ROS 2 topic names, but your *Connext* application from before 7.7.0 will not; in the 7.7.0+ communication, the entities will be permitted to communicate, but in the pre-7.7.0 communication, they will not. If you cannot update/regenerate your permissions files as described in :ref:`update-permissions-gov-docs`, this section describes how enabling ROS 2 interoperability will still work using existing security documents that only use ROS 2 mangled topic names. When setting ``dds.ros.enable_interoperability`` to ``TRUE``, *Connext* 7.7.0+ attempts to convert the topic names in the existing permissions file if a match is not initially found to see if there is a match when topic aliases are taken into account. Permissions ^^^^^^^^^^^ When ROS 2 interoperability is enabled on a *DomainParticipant*, the *DomainParticipant* will allow for *Connext* topic names to be converted to their equivalent ROS 2 topic name counterpart when evaluating permissions. ``dds.ros.enable_interoperability`` must be set to ``TRUE`` on the *DomainParticipant* for this conversion to take place. If ``dds.ros.enable_interoperability`` is only set on an endpoint, then only the primary topic name will be used to evaluate permissions for any discovered remote endpoints. Likewise, *DomainParticipants* created with the *Connext* RMW using *Connext* 7.7.0+ are also permitted to convert topic names from the ROS 2 topic name to the *Connext* equivalent when evaluating permissions. If either the primary topic name or equivalent ROS 2 topic name is allowed to communicate in the system, then the endpoint will be allowed. This behavior differs slightly depending on whether the remote endpoint has topic aliases or not. If the remote endpoint has topic aliases, we will check the provided topic aliases for permissions. If the remote endpoint does **not** have topic aliases, we will check if any possible topic aliases have permissions (these "possible" topic aliases are calculated with the rules described in :ref:`connext-topic-type-alias`). See: - :ref:`endpoint-has-topic-aliases` - :ref:`endpoint-no-topic-aliases` .. _endpoint-has-topic-aliases: Remote Endpoint Has Topic Aliases """"""""""""""""""""""""""""""""" If a remote endpoint has topic aliases, then it is a *Connext* 7.7.0+ application that may or may not be using the ROS 2 RMW. In this case, we assume that the topic aliases have been properly configured. We again first evaluate permissions for the primary topic name. If no permissions are granted, we evaluate permissions for the topic alias name. If no permissions are granted, the endpoint is rejected. We do not do additional topic name conversion to other possible ROS 2 topic names, because the remote endpoint has already offered both its mangled and demangled topic name. The following examples all use the following setup with different Permissions documents: - *Connext* 7.7.0+ Participant A with a writer on topic ``Foo`` and ``dds.ros.enable_interoperability`` set to ``TRUE`` and ``dds.ros.use_mangled_names_as_default`` set to ``FALSE`` discovers *Connext* 7.7.0+ RMW Participant B with a reader on topic ``rt/Foo`` with topic alias ``Foo`` (the topic alias is automatically configured by the Connext 7.7.0+ RMW). - Participant A announces ``Foo`` as its primary topic and ``rt/Foo`` as its alias (because of ``dds.ros.use_mangled_names_as_default``). - Participant B announces ``rt/Foo`` as its primary topic and ``Foo`` as its alias. Participant A and Participant B are both using the permissions documents shown in the following examples. **Example 1: Primary topic denied (by default DENY rule), topic alias allowed: endpoint allowed** In this example, a denied topic (``Foo``) is allowed when using an allowed topic (``rt/Foo``) as its topic alias. (In contrast, the default behavior, if ``dds.ros.enable_interoperability`` were set to ``FALSE``, would be to deny ``Foo`` because the default rule is DENY.) .. code-block:: xml rt/Foo rt/Foo DENY When Participant A creates its writer on topic ``Foo``, it first sees that ``Foo`` is not allowed. It then evaluates its topic alias ``rt/Foo`` and sees that it is allowed. Participant A is allowed to create the writer. When Participant B creates its reader on topic ``rt/Foo``, it sees that ``rt/Foo`` is allowed and is allowed to create the reader. When Participant A discovers Participant B's reader, it sees that ``rt/Foo`` is allowed, so the remote reader is allowed. When Participant B discovers Participant A's writer, it sees that ``Foo`` is not allowed. It then checks ``rt/Foo`` and sees that it is allowed, so the remote writer is allowed. **Example 2: Primary topic allowed, topic alias denied (by default DENY rule): endpoint allowed** A denied topic (``rt/Foo``) is allowed when using an allowed topic (``Foo``) as its topic alias (default behavior is to deny). (In contrast, the default behavior, if ``dds.ros.enable_interoperability`` were set to FALSE, would be to deny ``Foo`` because the default rule is DENY.) .. code-block:: xml Foo Foo DENY When Participant A creates its writer on topic ``Foo``, it sees that ``Foo`` is allowed and is allowed to create the writer. When Participant B creates its reader on topic ``rt/Foo``, it sees that ``rt/Foo`` is not allowed and is at first not allowed to create the reader. Because Participant B is a *Connext* RMW participant, it then checks its topic alias ``Foo``, sees that it is allowed, and thus Participant B is allowed to create the reader. When Participant A discovers Participant B's reader, it sees that ``rt/Foo`` is not allowed. It then checks the topic alias ``Foo`` and sees that it is allowed, so the remote reader is allowed. When Participant B discovers Participant A's writer, it sees that ``rt/Foo`` is not allowed. It then checks ``Foo`` and sees that it is allowed, so the remote writer is allowed. **Example 3: Primary topic denied, topic alias allowed (by default ALLOW rule): endpoint allowed** In this example, because ``Foo`` has a topic alias ``rt/Foo``, Participant A is allowed to create the writer with topic ``Foo``, even though ``Foo`` is explicitly in a ``deny_rule``. .. code-block:: xml Foo Foo ALLOW When Participant A creates its writer on topic ``Foo``, it first sees that ``Foo`` is not allowed. It then evaluates its topic alias ``rt/Foo`` and sees that it is allowed (by virtue of the default ALLOW rule). Participant A is allowed to create the writer. When Participant B creates its reader on topic ``rt/Foo``, it sees that ``rt/Foo`` is allowed (by virtue of the default ALLOW rule), and it is allowed to create the reader. When Participant A discovers Participant B's reader, it sees that ``rt/Foo`` is allowed, so the remote reader is allowed. When Participant B discovers Participant A's writer, it sees that ``Foo`` is not allowed. It then checks ``rt/Foo`` and sees that it is allowed, so the remote writer is allowed. **Example 4: Primary topic denied, topic alias denied: endpoint denied (despite default ALLOW rule)** .. code-block:: xml Foo rt/Foo Foo rt/Foo ALLOW When Participant A creates its writer on topic ``Foo``, it first sees that ``Foo`` is not allowed. It then evaluates its topic alias ``rt/Foo`` and sees that it is also not allowed. Writer creation will fail. When Participant B creates its reader on topic ``rt/Foo``, it sees that ``rt/Foo`` is not allowed. It then evaluates its topic alias ``Foo`` and sees that it is also not allowed. Reader creation will fail. When Participant A discovers Participant B's reader, it sees that ``rt/Foo`` is not allowed. It then checks its topic alias ``Foo`` and sees that it is not allowed. The remote reader is not allowed. When Participant B discovers Participant A's writer, it sees that ``Foo`` is not allowed. It then checks ``rt/Foo`` and sees that it is not allowed. The remote writer is not allowed. .. _endpoint-no-topic-aliases: Remote Endpoint Does not Have Topic Aliases """"""""""""""""""""""""""""""""""""""""""" If the remote endpoint does not have topic aliases, we may still want to be able to grant it permissions. A remote endpoint may not have topic aliases if it is part of a ROS 2 application using an older version of *Connext* or using a different RMW. In this case, *Connext* 7.7.0+ first evaluates permissions for the primary topic name. If no permissions are granted, we evaluate all possible ROS 2 topic names for the endpoint (``rt/``, ``rr/Request``, ``rr/Reply``, ``rq/Request``, and ``rq/Reply``). If no permissions are granted for any of these topic names, the endpoint is rejected. The following examples all use the following setup: - *Connext* 7.7.0+ Participant A with a topic ``Foo`` and ``dds.ros.enable_interoperability`` set to ``TRUE`` discovers *Connext* 6.1.0 RMW Participant B with primary topic ``rt/Foo`` (and no topic aliases). - Participant A announces ``rt/Foo`` as its primary topic and ``Foo`` as its alias (because ``dds.ros.use_mangled_names_as_default`` takes its default value of ``TRUE``). - Participant B announces ``rt/Foo`` as its primary topic (Participant B does not have topic aliases because it is using 6.1.0). Participant A and Participant B are both using the following permissions documents: **Example 1: Primary topic denied (by default DENY rule), topic alias allowed: endpoint allowed** .. code-block:: xml rt/Foo rt/Foo DENY When Participant A creates its writer on topic ``Foo``, it first sees that ``Foo`` is not allowed. It then evaluates its topic alias ``rt/Foo`` and sees that it is allowed. Participant A is allowed to create the writer. When Participant B creates its reader on topic ``rt/Foo``, it sees that ``rt/Foo`` is allowed and is allowed to create the reader. When Participant A discovers Participant B's reader, it sees that ``rt/Foo`` is allowed, so the remote reader is allowed. When Participant B discovers Participant A's writer, it sees that ``rt/Foo`` is allowed, so the remote writer is allowed. **Example 2: Primary topic allowed to publish only, topic alias allowed to subscribe only: asymmetric permissions** .. code-block:: xml Foo rt/Foo DENY When Participant A creates its writer on topic ``Foo``, it sees that ``Foo`` is allowed and is allowed to create the writer. When Participant B creates its reader on topic ``rt/Foo``, it sees that ``rt/Foo`` is allowed and is allowed to create the reader. When Participant A discovers Participant B's reader, it sees that ``rt/Foo`` is allowed, so the remote reader is allowed. When Participant B discovers Participant A's writer, it sees that ``rt/Foo`` is *not* allowed, so the remote writer is not allowed. Participant B is using an older version of *Connext*, so it is not able to check Participant A's topic alias. This results in asymmetric discovery. Governance ^^^^^^^^^^ When ROS 2 interoperability is enabled on an entity (*DomainParticipant*, *DataReader*, or *DataWriter*), the entity will allow *Connext* topic names to be converted to their equivalent ROS 2 topic name counterpart when selecting a governance policy. When creating a local endpoint, the first topic name that we use to attempt to find the governance policy will be the “primary” topic name, which is set based on the value of ``dds.ros.use_mangled_names_as_default``. If there is no match, then *Connext* 7.7.0+ will try the “secondary” topic name. If there is still no match, then the endpoint creation will fail. The following examples use different governance policies for two topic names that result in a topic/topic alias pairing (that is, ``Foo`` and ``rt/Foo`` have different governance policies). This is generally *not* recommended. This is the easiest way to misconfigure your system, and although it will not result in an error, it may result in communication failure if different endpoints load different Governance policies. We use these examples for illustrative purposes only. The recommended configuration is to have both topic names in the Permissions and Governance file with the same settings, as shown in :ref:`update-permissions-gov-docs`, since that configuration supports the most interoperability cases. **Example 1:** .. code-block:: xml Foo true true true true ENCRYPT ENCRYPT rt/Foo false false false false NONE NONE **Example 1.a:** Participant A creates a writer on topic ``Foo`` with ``dds.ros.enable_interoperability`` set to ``TRUE`` and ``dds.ros.use_mangled_names_as_default`` set to ``TRUE``. When the writer is created, we will first search for ``rt/Foo`` for a governance policy because ``dds.ros.use_mangled_names_as_default`` is set to ``TRUE``. The endpoint will be created without protection or access control. **Example 1.b:** Participant A creates a writer on topic ``Foo`` with ``dds.ros.enable_interoperability`` set to ``TRUE`` and ``dds.ros.use_mangled_names_as_default`` set to ``FALSE``. When the writer is created, we will first search for ``Foo`` for a governance policy because ``dds.ros.use_mangled_names_as_default`` is set to ``FALSE``. The endpoint will be created with discovery protection, liveliness protection, read access control, write access control, and metadata and data encryption. **Example 2:** .. code-block:: xml rt/Foo false false false false NONE NONE **Example 2.a:** Participant A creates a writer on topic ``Foo`` with ``dds.ros.enable_interoperability`` set to ``TRUE`` and ``dds.ros.use_mangled_names_as_default`` set to ``TRUE``. When the writer is created, we will first search for ``rt/Foo`` for a governance policy because ``dds.ros.use_mangled_names_as_default`` is set to ``TRUE``. The endpoint will be created without protection or access control. **Example 2.b:** Participant A creates a writer on topic ``Foo`` with ``dds.ros.enable_interoperability`` set to ``TRUE`` and ``dds.ros.use_mangled_names_as_default`` set to ``FALSE``. When the writer is created, we will first search for ``Foo`` for a governance policy because ``dds.ros.use_mangled_names_as_default`` is set to ``FALSE``. There is no match. We then search for the topic alias ``rt/Foo``. There is a match, the endpoint will be created without protection or access control.