22. Support for RTI Observability Framework

This chapter demonstrates how to configure the Security Plugins to secure DDS communications between RTI Monitoring Library 2.0 and RTI Collector Service, or between a Collector Service instance with a DDS exporter acting as a forwarder and a Collector Service instance with a DDS receiver. For information about configuration, usage, and components of Observability Framework, refer to the RTI Connext Observability Framework User’s Manual.

Attention

If your Connext application uses Monitoring Library 2.0, then you must secure the DDS communication between Monitoring Library 2.0 and Collector Service using the Security Plugins as explained in this section. Otherwise, the enablement of Monitoring Library 2.0 will fail with the following error message:

[ERROR] FAILED TO ENABLE | You are attempting to enable the RTI Monitoring Library 2.0 without security, but your system already contains a DomainParticipant with security enabled. Please, enable security for the RTI Monitoring Library 2.0 (refer to the RTI Connext Observability Framework for further information).

For the same reason, if your application has already enabled Monitoring Library 2.0 without security and you later enable a DomainParticipant using the Security Plugins or Lightweight Builtin Security Plugins, the DomainParticipant enablement will fail with the following error message:

[ERROR] FAILED TO ENABLE | You are attempting to enable a secure DomainParticipant, but the RTI Monitoring Library 2.0 is not secured. Please, disable RTI Monitoring Library 2.0 (using factoryQos.monitoring.enable) or enable security for it (refer to the RTI Connext Observability Framework for further information).

22.1. Security for Telemetry Data

If your Connext applications use Observability Framework, you may want to secure the DDS traffic published by Monitoring Library 2.0 and control which Collector Service can subscribe to it. Telemetry data may contain sensitive information about your system (for example, logging messages) that must be protected from unauthorized access.

Monitoring Library 2.0 uses a DomainParticipant, Topics, and DataWriters to publish telemetry data. Collector Service uses a DomainParticipant, Topics, and DataReaders to subscribe to that data. Therefore, the Security Plugins can be used to secure the communications between them as if they were regular Connext applications. The Governance Document and the Permissions Document provide specific XML tags for Observability.

Configuring security for telemetry data does not affect your application data. You can secure telemetry data independently from your application data and vice versa.

Important

22.1.1. Securing Telemetry Data with Security Plugins

22.1.1.1. Creating a Governance Document for Observability Framework

The first thing you need to determine is the level of protection you want for telemetry data (ENCRYPT, ENCRYPT_WITH_ORIGIN_AUTHENTICATION, SIGN, SIGN_WITH_ORIGIN_AUTHENTICATION, or NONE). Metrics and logs can have different levels of sensitivity, so you may want to protect them differently. Use the monitoring_metrics_protection_kind and monitoring_logging_protection_kind tags to set the protection level for metrics and logs, respectively. For example, if you want to encrypt logs but not metrics:

Listing 22.1 Example Governance Document for Observability Framework
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/current/dds_security_governance.xsd">
    <domain_access_rules>
        <domain_rule>
            <domains>
                <id_range>
                    <min>0</min>
                </id_range>
                <tag>RTI_o11y</tag>
                <tag></tag>
            </domains>
            <allow_unauthenticated_participants>false</allow_unauthenticated_participants>
            <enable_join_access_control>true</enable_join_access_control>
            <discovery_protection_kind>ENCRYPT</discovery_protection_kind>
            <liveliness_protection_kind>ENCRYPT</liveliness_protection_kind>
            <monitoring_metrics_protection_kind>ENCRYPT</monitoring_metrics_protection_kind>
            <monitoring_logging_protection_kind>ENCRYPT</monitoring_logging_protection_kind>
            <rtps_protection_kind>SIGN</rtps_protection_kind>
            <rtps_psk_protection_kind>ENCRYPT</rtps_psk_protection_kind>
            <topic_access_rules>
                <topic_rule>
                    <topic_expression>*</topic_expression>
                    <enable_discovery_protection>true</enable_discovery_protection>
                    <enable_liveliness_protection>true</enable_liveliness_protection>
                    <enable_read_access_control>true</enable_read_access_control>
                    <enable_write_access_control>true</enable_write_access_control>
                    <metadata_protection_kind>ENCRYPT</metadata_protection_kind>
                    <data_protection_kind>ENCRYPT</data_protection_kind>
                </topic_rule>
            </topic_access_rules>
        </domain_rule>
    </domain_access_rules>
</dds>

Note

monitoring_metrics_protection_kind applies to both event and periodic metrics.

Note

By default, Observability Framework uses the domain tag RTI_o11y for the observability domain. This is why the example Governance Document includes <tag>RTI_o11y</tag> in the domains section—it matches the observability DomainParticipant.

The empty <tag></tag> is only needed if this domain rule is shared with the application domains, which by default do not have a domain tag. The empty tag matches DomainParticipants that have no domain tag configured. If the Governance Document is not shared with application domains, you do not need to include the empty tag.

If one of these tags is not present in the Governance Document, the protection level for that data (metrics or logs) is inherited from discovery_protection_kind. Both tags are optional.

Attention

Protection kinds for Observability Topics must be configured using the XML tags described in this section. If they are configured using the Topic names in the topic_expression tag, an error will occur.

Using wildcards will not result in an error. However, even if the wildcard matches a Topic name, the rule will not be applied.

Important

If you also want to secure remote administration commands, you need to protect the ServiceRequest channel using the service_request_protection_kind XML tag. See service_request_protection_kind (domain_rule) for further information.

22.1.1.2. Creating a Permissions Document for Collector Service

The second thing you need to determine is which Collector Services can subscribe to telemetry data and which data they can subscribe to. For example, you may want to allow one Collector Service to subscribe to all telemetry data, while another subscribes only to metrics. Use the subscribe_monitoring XML tag in the Permissions Document to set which data a Collector Service instance can subscribe to. In the following example Permissions Document, the Collector Service subscribes to all telemetry data:

Listing 22.2 Example Permissions Document for Collector Service
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../schema/dds_security_permissions.xsd">
    <permissions>
        <grant name="Participant_Monitoring">
            <subject_name>/C=US/ST=CA/O=Real Time Innovations/emailAddress=ecdsa01Peer01@rti.com/CN=RTI ECDSA01 (p256) PEER01</subject_name>
            <validity>
                <not_before>2015-09-14T01:00:00</not_before>
                <not_after>2037-09-14T01:00:00</not_after>
            </validity>
            <allow_rule>
                <domains>
                    <id>101</id>
                    <tag>RTI_o11y</tag>
                </domains>
                <subscribe_monitoring>ALL</subscribe_monitoring>
            </allow_rule>
            <default>DENY</default>
        </grant>
    </permissions>
</dds>

Note

By default, Observability Framework uses domain ID 101 with a domain tag of RTI_o11y. This is why the allow rule in the example Permissions Document includes <id>101</id> and <tag>RTI_o11y</tag> in the domains section. If you change the observability domain ID or domain tag, update the domains in the allow rule accordingly.

Valid values for subscribe_monitoring are ALL (logging and metrics), METRICS, and NONE. Note that a Collector Service cannot subscribe to logging data only. Also, this tag can only be used in allow rules.

Attention

  • The default rule for Observability Framework endpoints is always DENY regardless of the value configured in the Permissions Document.

  • The METRICS value for the subscribe_monitoring tag is not currently supported.

  • Observability endpoint permissions must be configured using the subscribe_monitoring XML tag. If these permissions are configured using the Topic names in topics, an error will occur. Using wildcards will not result in an error. However, even if the wildcard matches a Topic name, the rule will not be applied.

Allow rules in the Permissions Document are evaluated in order. If the Observability Domain ID matches the allowed domains, the Security Plugins will check the subscribe_monitoring tag in that allow rule. The rule will be ignored, and the next rule will be evaluated, if the tag is not present, if the tag is set to NONE, or if the current Topic is the logging Topic and the tag is set to METRICS. The process continues until a rule applies. If none of the allow rules apply, the default rule will be applied (always DENY).

22.1.1.3. Creating a Permissions Document for Monitoring Library 2.0

Publishing telemetry data is always allowed. Therefore, you do not need to create a special Permissions Document for Monitoring Library 2.0. You can reuse the same Permissions Document you created for Collector Service (although subscribe_monitoring is not required in this case).

22.1.1.4. Enabling Security Plugins in Collector Service

The enablement of the Security Plugins in Collector Service depends on how you deployed Collector Service in your system.

22.1.1.4.1. Evaluation Deployment Using Docker Compose

If you installed the Observability Framework in a single host using Docker Compose (see Observability Framework for Evaluation in the Connext Observability Framework User’s Manual), the Observability Framework components are configured using a JSON file the first time you run the rtiobservability script. Add the security artifacts to your JSON configuration file, as shown in the following example:

Listing 22.3 Example JSON configuration file for Observability Framework with Security Plugins
  {
      "hostname": "localhost",
      "securityConfig": {
          "basicAuthUsername": "...",
          "basicAuthPassword": "...",
          "httpsSecurity": {
              "caCertificate":     "...",
              "serverCertificate": "...",
              "serverKey":         "..."
          },
          "ddsSecurity": {
              "identityCaCertificate":    "path/to/identityCaCert.pem",
              "permissionsCaCertificate": "path/to/permissionsCaCert.pem",
              "identityCertificate":      "path/to/identityCert.pem",
              "identityKey":              "path/to/identityKey.pem",
              "signedPermissionsFile":    "path/to/signedPermissions.p7s",
              "signedGovernanceFile":     "path/to/signedGovernance.p7s",
              "pskSecretPassphrase":      "path/to/passphrase"
          }
      }
  }

See JSON Configuration File in the Connext Observability Framework User’s Manual for further information on the JSON configuration file syntax and usage.

If the JSON configuration contains the security artifacts, the Security Plugins will be enabled automatically in Collector Service.

Note

With Docker Compose, Collector Service can only be configured with a DDS receiver. Exporting to DDS is not supported.

22.1.1.4.2. Production Deployment
22.1.1.4.2.1. Collector Service Docker Image

If you are running Collector Service directly using the available Docker image (see Production Deployments in the Connext Observability Framework User’s Manual), the security artifacts must be bind-mounted when running the Collector Service Docker container, as shown in the following example:

Listing 22.4 Example bind-mounting of security artifacts for the Collector Service DDS receiver
  -v path/to/identityCaCert.pem:/rti/security/dds/identity_ca.pem
  -v path/to/permissionsCaCert.pem:/rti/security/dds/permissions_ca.pem
  -v path/to/identityCert.pem:/rti/security/dds/identity_certificate.pem
  -v path/to/identityKey.pem:/rti/security/dds/private_key.pem
  -v path/to/signedPermissions.p7s:/rti/security/dds/permissions.p7s
  -v path/to/signedGovernance.p7s:/rti/security/dds/governance.p7s
  -v /path/to/passphrase:/rti/security/dds/passphrase
Listing 22.5 Example bind-mounting of security artifacts for the Collector Service DDS exporter
  -v /path/to/identity_ca_output.pem:/rti/security/dds/identity_ca_output.pem
  -v /path/to/permissions_ca_output.pem:/rti/security/dds/permissions_ca_output.pem
  -v /path/to/identity_certificate_output.pem:/rti/security/dds/identity_certificate_output.pem
  -v /path/to/private_key_output.pem:/rti/security/dds/private_key_output.pem
  -v /path/to/governance_output.p7s:/rti/security/dds/governance_output.p7s
  -v /path/to/permissions_output.p7s:/rti/security/dds/permissions_output.p7s
  -v /path/to/passphrase_output:/rti/security/dds/passphrase_output

In addition, you need to set the CFG_NAME environment variable to one of the provided Docker image’s builtin configurations that enable the Security Plugins in Collector Service. See Collector Service Builtin Configurations in the Connext Observability Framework User’s Manual for details about the available builtin configurations.

For additional information on how to use the Collector Service Docker image, refer to the Collector Service article in Docker Hub.

22.1.1.4.2.2. Collector Service Executable

If you are running Collector Service as an executable (see Production Deployments in the Connext Observability Framework User’s Manual), the security artifacts must be provided via the definition of environment variables, as shown in the following example:

Listing 22.6 Example set environment variables for security artifacts for the Collector Service DDS receiver
  -DOBSERVABILITY_DDS_SECURITY_IDENTITY_CA="path/to/identity_ca.pem"
  -DOBSERVABILITY_DDS_SECURITY_PERMISSIONS_CA="path/to/permissions_ca.pem"
  -DOBSERVABILITY_DDS_SECURITY_IDENTITY_CERTIFICATE="path/to/identity_certificate.pem"
  -DOBSERVABILITY_DDS_SECURITY_PRIVATE_KEY="/path/to/private_key.pem"
  -DOBSERVABILITY_DDS_SECURITY_PERMISSIONS="/path/to/permissions.p7s"
  -DOBSERVABILITY_DDS_SECURITY_GOVERNANCE="/path/to/governance.p7s"
  -DOBSERVABILITY_DDS_SECURITY_PASSPHRASE="path/to/passphrase"
Listing 22.7 Example set environment variables for security artifacts for the Collector Service DDS exporter
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_IDENTITY_CA="path/to/identity_ca_output.pem"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PERMISSIONS_CA="path/to/permissions_ca_output.pem"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_IDENTITY_CERTIFICATE="path/to/identity_certificate_output.pem"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PRIVATE_KEY="/path/to/private_key_output.pem"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PERMISSIONS="/path/to/permissions_output.p7s"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_GOVERNANCE="/path/to/governance_output.p7s"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PASSPHRASE="path/to/passphrase_output"

In addition, you need to set the -cfgName environment variable to one of the provided Docker image’s builtin configurations that enable the Security Plugins in Collector Service. See Collector Service Builtin Configurations in the Connext Observability Framework User’s Manual for details about the available builtin configurations.

For additional information on how to use the Collector Service, refer to Collector Service chapter in the Connext Observability Framework User’s Manual.

22.1.1.5. Enabling Security Plugins in Monitoring Library 2.0

To enable the Security Plugins in Monitoring Library 2.0, you need to define a QoS profile with the properties related to security artifacts (Security Plugins enablement, certificates, Governance Document, and Permissions Document). Then, you need to set that profile name in participant_factory_qos.monitoring.distribution_settings.dedicated_participant.participant_qos_profile_name (see MONITORING QosPolicy (DDS Extension) for further information on this field). For example:

Listing 22.8 Example QoS configuration for enabling Security Plugins in Monitoring Library 2.0
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../schema/rti_dds_qos_profiles.xsd">
    <qos_library name="MyQosLibrary">
        <qos_profile name="MyObservabilityProfileWithSecurity" base_name="BuiltinQosLib::Generic.Monitoring2">
            <domain_participant_qos>
                <property>
                    <value>
                        <!-- Load Security Plugins -->
                        <element>
                            <name>com.rti.serv.load_plugin</name>
                            <value>com.rti.serv.secure</value>
                        </element>
                        <element>
                            <name>com.rti.serv.secure.library</name>
                            <value>nddssecurity</value>
                        </element>
                        <element>
                            <name>com.rti.serv.secure.create_function</name>
                            <value>RTI_Security_PluginSuite_create</value>
                        </element>
                        <!-- Certificate Authorities -->
                        <element>
                            <name>dds.sec.auth.identity_ca</name>
                            <value>file:./path/to/identityCaCert.pem</value>
                        </element>
                        <element>
                            <name>dds.sec.access.permissions_ca</name>
                            <value>file:./path/to/permissionsCaCert.pem</value>
                        </element>
                        <!-- Participant Public Certificate and Private Key -->
                        <element>
                            <name>dds.sec.auth.identity_certificate</name>
                            <value>file:./path/to/identityCert.pem</value>
                        </element>
                        <element>
                            <name>dds.sec.auth.private_key</name>
                            <value>file:./path/to/identityKey.pem</value>
                        </element>
                        <!-- Signed Governance and Permissions Documents -->
                        <element>
                            <name>dds.sec.access.governance</name>
                            <value>file:./path/to/signedGovernance.p7s</value>
                        </element>
                        <element>
                            <name>dds.sec.access.permissions</name>
                            <value>file:./path/to/signedPermissions.p7s</value>
                        </element>
                    </value>
                </property>
            </domain_participant_qos>
        </qos_profile>
   
        <qos_profile name="MyApplicationProfile">
            <participant_factory_qos>
                <monitoring>
                    <enable>true</enable>
                    <distribution_settings>
                        <dedicated_participant>
                            <participant_qos_profile_name>
                                MyQosLibrary::MyObservabilityProfileWithSecurity
                            </participant_qos_profile_name>
                        </dedicated_participant>
                    </distribution_settings>
                </monitoring>
            </participant_factory_qos>
        </qos_profile>
    </qos_library>
</dds>

Note

You can see an example of how to enable the Security Plugins in Monitoring Library 2.0 in the shipped Temperature example (<path to examples>/observability/c++). This example is described in detail in the Tutorial in the Connext Observability Framework User’s Manual.

22.1.2. Securing Telemetry Data with Lightweight Builtin Security Plugins

22.1.2.1. Evaluation Deployment Using Docker Compose with Lightweight Builtin Security Plugins

Important

Lightweight Builtin Security Plugins is not supported for Observability Framework evaluation deployments.

22.1.2.2. Production Deployment with Lightweight Builtin Security Plugins

22.1.2.2.1. Collector Service Docker Image with Lightweight Builtin Security Plugins

If you are running Collector Service directly using the available Docker image (see Production Deployments in the Connext Observability Framework User’s Manual), the security artifacts must be bind-mounted when running the Collector Service Docker container, as shown in the following example:

Listing 22.9 Example bind-mounting of security artifacts for the Collector Service DDS receiver
  -v /path/to/passphrase:/rti/security/dds/passphrase
Listing 22.10 Example bind-mounting of security artifacts for the Collector Service DDS exporter
  -v /path/to/passphrase_output:/rti/security/dds/passphrase_output

In addition, you need to set the CFG_NAME environment variable to one of the provided Docker image’s builtin configurations that enable the Security Plugins in Collector Service. See Collector Service Builtin Configurations in the Connext Observability Framework User’s Manual for details about the available builtin configurations.

The following environment variables may optionally be changed to configure the protection kind and cipher for the Lightweight Builtin Security Plugins:

Listing 22.11 Example environment variables to configure the protection kind and cipher for the Lightweight Builtin Security Plugins in Collector Service using Docker image
  -e OBSERVABILITY_DDS_SECURITY_PSK_PROTECTION_KIND="<protection_kind>"
  -e OBSERVABILITY_DDS_SECURITY_PSK_CIPHER="<cipher>"
  -e OBSERVABILITY_OUTPUT_DDS_SECURITY_PSK_PROTECTION_KIND="<protection_kind>"
  -e OBSERVABILITY_OUTPUT_DDS_SECURITY_PSK_CIPHER="<cipher>"

For additional information on values for protection kind and cipher, see rtps_psk_protection_kind (domain_rule) and Supported Cryptographic Algorithms respectively.

For additional information on how to use the Collector Service Docker image, refer to the Collector Service article in Docker Hub.

22.1.2.2.2. Collector Service Executable with Lightweight Builtin Security Plugins

If you are running Collector Service as an executable, the security artifacts must be provided via the definition of environment variables, as shown in the following example:

Listing 22.12 Example set environment variables for security artifacts for the Collector Service DDS receiver
  -DOBSERVABILITY_DDS_SECURITY_PASSPHRASE="path/to/passphrase"
Listing 22.13 Example set environment variables for security artifacts for the Collector Service DDS exporter
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PASSPHRASE="path/to/passphrase_output"

In addition, you need to set the -cfgName environment variable to one of the provided Docker image’s builtin configurations that enable the Lightweight Builtin Security Plugins in Collector Service. See Collector Service Builtin Configurations in the Connext Observability Framework User’s Manual for details about the available builtin configurations.

The following environment variables may optionally be changed to configure the protection kind and cipher for the Lightweight Builtin Security Plugins:

Listing 22.14 Example environment variables to configure the protection kind and cipher for the Lightweight Builtin Security Plugins in Collector Service using executable
  -DOBSERVABILITY_DDS_SECURITY_PSK_PROTECTION_KIND="<protection_kind>"
  -DOBSERVABILITY_DDS_SECURITY_PSK_CIPHER="<cipher>"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PSK_PROTECTION_KIND="<protection_kind>"
  -DOBSERVABILITY_OUTPUT_DDS_SECURITY_PSK_CIPHER="<cipher>"

For additional information on values for protection kind and cipher, see rtps_psk_protection_kind (domain_rule) and Supported Cryptographic Algorithms respectively.

For additional information on how to use the Collector Service, refer to Collector Service chapter in the Connext Observability Framework User’s Manual.

22.1.2.2.3. Enabling Lightweight Builtin Security Plugins in Monitoring Library 2.0

To enable the Security Plugins in Monitoring Library 2.0, you need to define a QoS profile with the properties related to security artifacts (Lightweight Builtin Security Plugins configuration and passphrase). Then, you need to set that profile name in participant_factory_qos.monitoring.distribution_settings.dedicated_participant.participant_qos_profile_name (see MONITORING QosPolicy (DDS Extension) for further information on this field). For example:

Listing 22.15 Example QoS configuration for enabling Lightweight Builtin Security Plugins in Monitoring Library 2.0
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../schema/rti_dds_qos_profiles.xsd">
    <qos_library name="MyQosLibrary">
        <qos_profile name="MyObservabilityProfileWithLightweightSecurity" base_name="BuiltinQosLib::Generic.Monitoring2">
            <domain_participant_qos>
                <property>
                    <value>
                        <!-- Load Security Plugins -->
                        <element>
                            <name>com.rti.serv.load_plugin</name>
                            <value>com.rti.serv.secure</value>
                        </element>
                        <element>
                            <name>com.rti.serv.secure.library</name>
                            <value>nddslightweightsecurity</value>
                        </element>
                        <element>
                            <name>com.rti.serv.secure.create_function</name>
                            <value>RTI_SecurityLightweight_PluginSuite_create</value>
                        </element>
                        <!-- PSK shared secret (must match on all peers) -->
                        <element>
                            <name>dds.sec.crypto.rtps_psk_secret_passphrase</name>
                            <value>0:PLEASE-CHANGE-THIS-DEFAULT-SEED</value>
                        </element>
                        <!-- Protection kind -->
                        <element>
                            <name>dds.sec.access.rtps_psk_protection_kind</name>
                            <value>ENCRYPT</value>
                        </element>
                        <!-- Cipher -->
                        <element>
                            <name>dds.sec.crypto.rtps_psk_symmetric_cipher_algorithm</name>
                            <value>AUTO</value>
                        </element>
                    </value>
                </property>
            </domain_participant_qos>
        </qos_profile>
   
        <qos_profile name="MyApplicationProfile">
            <participant_factory_qos>
                <monitoring>
                    <enable>true</enable>
                    <distribution_settings>
                        <dedicated_participant>
                            <participant_qos_profile_name>
                                MyQosLibrary::MyObservabilityProfileWithLightweightSecurity
                            </participant_qos_profile_name>
                        </dedicated_participant>
                    </distribution_settings>
                </monitoring>
            </participant_factory_qos>
        </qos_profile>
    </qos_library>
</dds>

Note

You can see an example of how to enable the Lightweight Builtin Security Plugins in Monitoring Library 2.0 in the shipped Temperature example (<path to examples>/observability/c++). This example is described in detail in the Tutorial in the Connext Observability Framework User’s Manual.