.. include:: ../vars.rst .. _chapter-access-control: ************** Access Control ************** Access Control makes sure that |DPs| in your system have the right permissions to join your *DDS* |SecDomains|, to publish data on sensitive |TOPICs|, and to subscribe to them. Once a |DP| successfully authenticates, its permissions need to be validated and enforced. In this sense, the |SEC_SPEC| goes beyond many traditional security methods, where an application that is allowed to communicate within a secure system is trusted to access any information in it. Instead, the |AccessControlPlugin| provides fine-grained permissions that let you define whether a |DP| is allowed to join a particular |DOMAIN|, whether it is allowed to subscribe to a specific |TOPIC| within a particular |PARTITION|, etc. These permissions lock down the specific access that trusted applications have, so if one application becomes compromised, the damage to the system is limited. There is a strong relationship between the |AccessControlPlugin| and the Cryptography plugin because encryption keys need to be generated for |SecEntities| based on the |DP|'s permissions (see :ref:`p2_core/cryptography:Secure Entities`). When a |DP| is created, the |AccessControlPlugin| will check whether the local |PermissionsDoc| has a grant for the |DP| being created, based on its |IdentityCert|. Then the plugin will check whether the |DP| has permission to join the |DOMAIN| and permission to create the necessary entities. This is done by examining the |PermissionsDoc|. |PermissionsDocs| are exchanged between |DPs| during the Authentication process. This way, it's possible to check whether the remote participants have permission to join the |DOMAIN|, to publish/subscribe to certain |TOPICs|, etc. The |PermissionsDocs| need to be signed by the Permissions CA, therefore it's possible to verify that the |PermissionsDocs| provided by remote participants are legitimate. The Cryptography plugin has an important role in making sure the permissions apply by protecting the data. The |GovernanceDoc| specifies how |DOMAIN|-wide permissions are enforced, and how data and metadata is protected on those |DOMAINs|. |PermissionsDocs| provide granular access control at an individual participant level. .. admonition:: Definition We will refer to "|GovernanceDoc|" and "|PermissionsDoc|" as the abstract concept that contains the Governance rules or Permission grants that will apply in the system. On the other hand, we will refer to |GovernanceDoc| and |PermissionsDoc| to refer to the XML representation of the Governance rules and Permission grants. XML representation is the only one that is supported in the latest version of the |SEC_SPEC| and also in the current version of the |RTI_SP_PRODUCT|, so we will use these terms interchangeably in this chapter. .. note:: In the case of |LIGHT_SP_BUILTIN|, which implements |SEC_SPEC_12| builtin PSK plugins, the |AccessControlPlugin| does not support granular access control. Instead, all access control is based on the access to the right |PSK|. Consequently, most of this chapter is only applicable to |SP_BUILTIN| or custom security plugins. Access Control consists of two components: governance and permissions checking. Governance is the process of configuring locally created |DPs|, |TOPICs|, |DWs|, and |DRs| to perform the right amount of security for the right use case. Permissions checking is the process of making sure locally created and remotely discovered |Entities| are allowed to do what they want to do. Both governance and permissions checking are enforced by XML documents that are signed by a Permissions Certificate Authority that can be the same as the Identity Certificate Authority that signs |IdentityCerts|. The XSD definitions of these documents are in :ref:`p2_core/elements_dds_secure_system:XML Validation in the Governance Document` and :ref:`p2_core/elements_dds_secure_system:XML Validation in the Permissions Document`. For examples of these documents, refer to :ref:`p2_core/elements_dds_secure_system:Elements of a |RTI_SP_PRODUCT_HEADING| system`. Use these examples just as a reference; you will need to modify their content to match your system configuration (|DOMAINs|, |TOPICs|, and used |IdentityCerts|) and sign the XML files. To specify that you want to use these files, add the corresponding properties detailed in :numref:`DDS Security Properties for Configuring Access Control` and :numref:`|RTI_SP_PRODUCT_HEADING| Properties for Configuring Access Control` to the |DP|'s PROPERTY QosPolicy (see :ref:`p2_core/elements_dds_secure_system:QoS Properties`). Governance Document =================== The |GovernanceDoc| is an XML document that specifies how the |DOMAIN| should be secured. The Permissions CA (specified with the :property:`dds.sec.access.permissions_ca` property) must sign the |GovernanceDoc| using S/MIME version 3.2 format (which corresponds to the mime-type application/pkcs7-signature). The signed |GovernanceDoc| needs to be provided to the plugins using the :property:`dds.sec.access.governance` property as specified in :numref:`DDS Security Properties for Configuring Access Control`. This document configures multiple aspects that apply to the whole |DOMAIN|, such as: * whether the discovery/liveliness information should be protected and the kind of protection, * whether the whole RTPS message should be protected and the kind of protection, * whether a discovered |DP| that cannot authenticate or fail the authentication should be allowed to join the |DOMAIN|, * whether any successfully authenticated |DP| should be allowed to join the |DOMAIN| and see the discovery data without checking the access control policies. This document also specifies how the information on specific |TOPICs| within the |DOMAIN| should be treated. More specifically, it specifies: * whether the discovery/liveliness information on specific |TOPICs| should be sent using the secure (protected) writers or using the regular (unprotected) ones, * whether read/write access to the Topic should be open to all or restricted to the |DPs| that have the proper permissions, * whether the metadata information sent on the Topic should be protected and the kind of protection, * whether the payload data (serialized application level data) sent on the |TOPIC| should be protected and the kind of protection. The local |DP| validates the locally loaded |GovernanceDoc| against the Permissions CA specified in the :property:`dds.sec.access.permissions_ca` property (see :numref:`DDS Security Properties for Configuring Access Control`). If the Permissions CA cannot validate the |GovernanceDoc|, the validation will be retried with the alternative certificates specified in the :property:`access_control.alternative_permissions_authority_files` property (see :numref:`|RTI_SP_PRODUCT_HEADING| Properties for Configuring Access Control`). If none of the alternative CAs can validate the file (or if you did not set this property), the creation of the local |DP| will fail. The local |DP| checks the compatibility of the |GovernanceDoc| for remotely discovered |DPs| by checking the participant security attributes and the endpoint security attributes exchanged in the discovery, as explained in :ref:`p2_core/elements_dds_secure_system:Governance Compatibility Validation`. Further details on the |GovernanceDoc|: :ref:`p2_core/elements_dds_secure_system:Governance Document` Permissions Document ==================== The |PermissionsDoc| specifies what actions a |DP| is allowed to take in a |SecDomain|. For example, it determines whether the |DP| can join the |DOMAIN| (participant-level rules), whether it can publish or subscribe to particular |TOPICs|, |PARTITIONs|, etc. (endpoint-level rules). The |PermissionsDoc| is stored as an XML file. The Permissions CA must sign the |PermissionsDoc| using S/MIME version 3.2 format (which corresponds to the mime-type application/pkcs7-signature). The signed |PermissionsDoc| is provided to the |SP_BUILTIN| using the :property:`dds.sec.access.permissions` property, as specified in :numref:`DDS Security Properties for Configuring Access Control`. The local |DP| validates the |PermissionsDoc| against the Permissions CA specified in the :property:`dds.sec.access.permissions_ca` property (see :numref:`DDS Security Properties for Configuring Access Control`). If the Permissions CA cannot validate the |PermissionsDoc|, the validation will be retried with the alternative certificates specified in the :property:`access_control.alternative_permissions_authority_files` property (see :numref:`|RTI_SP_PRODUCT_HEADING| Properties for Configuring Access Control`). If none of the alternative CAs can validate the |PermissionsDoc| (or if you did not set this property), the validation process will fail. The |PermissionsDoc| contains a set of :xmltag:`grant` sections, each of which contains a :xmltag:`subject_name` section, a :xmltag:`validity` section, zero or more :xmltag:`allow_rule` sections, and zero or more :xmltag:`deny_rule` sections. Each grant contains the permissions of a particular |DP| and binds them to the subject name of the |DP| as defined in the |DP|'s |IdentityCert|. The :xmltag:`validity` tag determines whether the |PermissionsDoc| is valid for the current date and time. Please note that in the current version of |CONNEXT|, the signed |PermissionsDoc| only supports validity dates between 1970-01-01T00:00:00Z and 2106-02-07T06:28:15Z. Any dates before 1970-01-01T00:00:00Z will result in an error, and any dates after 2106-02-07T06:28:15Z will be treated as 2106-02-07T06:28:15Z. Currently, |CONNEXT| will not work if the system time is after February 7th, 2106. |PermissionsDocs| are exchanged between |DPs| during the authentication process to claim and verify permissions. Hence, to conserve bandwidth, it is best for this document to have exactly one :xmltag:`grant` section, which contains the subject name and rules for the |DP| presenting it. For more information about the |PermissionsDoc|, its structure, and its role in your secured system, see :ref:`p2_core/elements_dds_secure_system:Permissions Document` Using the :xmltag:`domains` tag you can control what |DOMAINs| your |DPs| are allowed to join (participant-level permissions), as described in :ref:`p2_core/elements_dds_secure_system:Specifying Domain IDs`. The following sections describe how to give your |DPs| permission to publish and subscribe to different |TOPICs| based on the topic name, |PARTITIONs|, and data tags. These endpoint-level permissions are specified using the elements in the :xmltag:`publish` and :xmltag:`subscribe` sections, which are inside the :xmltag:`allow_rule` and :xmltag:`deny_rule` sections. Topics ------ The :xmltag:`topics` element defines the DDS Topic names that must be matched for the rule to apply. Topic names may be given explicitly or by means of Topic name expressions. Each topic name or topic-name expression appears in a separate :xmltag:`topic` sub-element within the :xmltag:`topics` element. The Topic name expression syntax and matching shall use the syntax and rules of the POSIX ``fnmatch()`` function as specified in POSIX 1003.2-1992, Section B.6. Example (appearing within an :xmltag:`allow_rule` and within a :xmltag:`publish` tag): .. code-block:: xml Square B* The above topic condition would match |TOPIC| “Square” and any |TOPIC| that starts with a “B”. Partitions ---------- The :xmltag:`partitions` element defines the DDS Partition names that must be matched for the rule to apply (see :link_connext_dds_pro_um:`PARTITION QosPolicy in the RTI Connext DDS Core Libraries User's Manual <#users_manual/PARTITION_QosPolicy.htm>`). Partition names may be given explicitly or by means of partition-name expressions. Each partition name or partition-name expression appears in a separate :xmltag:`partition` sub-element within the :xmltag:`partitions` element. The partition-name expression syntax and matching shall use the syntax and rules of the POSIX ``fnmatch()`` function as specified in POSIX 1003.2-1992, Section B.6. Example (appearing within an :xmltag:`allow_rule` and within a :xmltag:`subscribe` tag): .. code-block:: xml Square Partition1 Partition2 PartitionA* ... Note the asterisk in the third partition. POSIX ``fnmatch()`` matching is allowed for the :xmltag:`partition` element. Behavior of the partitions tag within an allow_rule ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the :xmltag:`partitions` tag is under an :xmltag:`allow_rule`, it delimits which partitions (specified within :xmltag:`partition` tags) are allowed. In order for an action (e.g., a publish action) to meet the allowed partitions condition, the set of partitions associated with the |DDS_ENTITY| performing that action (e.g., a |DW| for a publish action) must be contained by the set of partitions defined by the allowed partitions condition section. As a limitation, if the |DDS_ENTITY| performing an action (e.g., a |DW| for a publish action) uses patterns in its partitions, these patterns must appear explicitly in the allowed partitions condition section. An exception to this rule is adding the :xmlval:`*` pattern to the allowed partitions condition section, which will allow the attempted action, regardless of the partitions announced by the |DDS_ENTITY|. If there is no :xmltag:`partitions` section, then the default "empty string" partition is assumed. Hence, the allowed action (e.g., a publish action) would only allow publishing on the "empty string" partition. Example (appearing within a :xmltag:`allow_rule` and within a :xmltag:`publish` tag): .. code-block:: xml Square A B ... The above allowed partitions condition would be matched if the partitions associated with the |DDS_ENTITY| performing the action (e.g., |DW| for publish action) are a subset of the set :value:`[A, B]`. So it would be OK to publish in partition :value:`A`, in partition :value:`B`, or in partition :value:`[A, B]` but not in partition :value:`[A, B, C]` [#]_ or in the "empty string" partition. .. [#] Assuming the property :property:`access_control.use_530_partitions` is :value:`FALSE` (see :numref:`|RTI_SP_PRODUCT_HEADING| Properties for Configuring Access Control`). Behavior of the partitions tag within a deny_rule ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the :xmltag:`partitions` tag is under a :xmltag:`deny_rule`, it delimits which partitions (specified within :xmltag:`partition` tags) are denied. For this condition to be met, the |DDS_ENTITY| associated with the action (e.g., |DW| for a publish action) must have a partition that matches one of the partitions explicitly listed in the denied partitions condition section. In other words, the |AccessControlPlugin| will deny the attempted action if the set of partitions announced by the |DDS_ENTITY| attempting to perform that action (e.g., |DW| for a publish action) intersects the set of partitions defined in the denied partitions condition section. For computing the intersection, both concrete partitions and expressions containing patterns are considered. Note that if the |DDS_ENTITY| only announces partitions containing patterns, it will fall back to the "empty string" partition. Therefore, the action will be denied if the denied partitions condition section intersects with the "empty string" partition. If there is no :xmltag:`partitions` section, then the :value:`*` partition expression is assumed. This means that the deny action (e.g., publish action) would apply regardless of the partitions associated with the |DDS_ENTITY| (e.g., |DW| for a publish action). Example (appearing within a :xmltag:`deny_rule` and within a :xmltag:`publish` tag): .. code-block:: xml Square A B ... ALLOW The above denied partitions condition would be matched if the partitions associated with the |DDS_ENTITY| performing the action (e.g., |DW| for a publish action) intersect the partition set :value:`[A, B]`. So, it would be OK to publish in partition :value:`C` or in the "empty string" partition, but not in partition :value:`A`, in partition :value:`[A,B]`, or in partition :value:`[A, B, C]`. Partition Mutability ^^^^^^^^^^^^^^^^^^^^ |DWs| need to avoid sending historical data to unauthorized |DRs| joining a new partition. Therefore, there are scenarios where |PUBs| are not allowed to change partitions. Note that these restrictions do not apply to |SUBs|. The |RTI_SP_PRODUCT| do not allow a |PUB| to change the PARTITION QosPolicy after the |PUB| has been enabled if the |PUB| contains any |DW| that meets the following two criteria: * The TopicSecurityAttributes for that |DW| have :xmltag:`is_read_protected` (which corresponds to :xmltag:`enable_read_access_control` in the |GovernanceDoc|) set to :xmlval:`TRUE`. * The |DW| has the DURABILITY QosPolicy kind set to something other than :xmlval:`VOLATILE`. When these two criteria are met, a |DW| should send historical data only to |DRs| that were passing the :xmltag:`topic` access control rules at the time the historical data was generated. The rule about PartitionQoS immutability enforces this behavior by conservatively preventing a |DW| of a protected |TOPIC| from sending historical data to |DRs| that were not matched before a PartitionQoS change and that potentially could have failed to pass the :xmltag:`topic` access control rules. .. figure:: ../static/datawriter-changing-partition.png :scale: 50% :name: Reliable DataWriter Changing Partition :align: center Reliable |DW| Changing Partitions Data Tags --------- The RTI Connext DDS Core Libraries User's Manual describes the DATATAG QosPolicy as a sequence of :value:`(name, value)` string pairs that belong to a |DW| or |DR| (see :link_connext_dds_pro_um:`DATATAG QosPolicy in the Core Libraries User's Manual <#users_manual/DATATAG_Qos.htm>`). The |AccessControlPlugin| uses these tags to determine whether or not a |DW| or |DR| is allowed to exist according to the |PermissionsDoc|. Inside the |PermissionsDoc|, the :xmltag:`data_tags` element may appear within a :xmltag:`publish` or :xmltag:`subscribe` element. :xmltag:`data_tags` may contain one or more :xmltag:`tag` elements, each containing a :xmltag:`name` and a :xmltag:`value` element. For example: .. code-block:: xml Sq* Department Engineering Seniority Senior Title *Software* Note the asterisk in the third tag's value. POSIX ``fnmatch()`` matching is allowed for the :xmltag:`value` element, but not for the :xmltag:`name` element. For further information on data tags, refer to :ref:`p2_core/tagging:Data Tagging`. Behavior of data_tags within an allow_rule ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the :xmltag:`data_tags` are under an :xmltag:`allow_rule`, then the :xmltag:`data_tags` delimit an allowed data tags condition section. In order for an action (e.g., a publish action) to meet the allowed data tags condition, the set of the data tags associated with the |DDS_EP| performing the action (e.g., a |DW| for a publish action) must be contained in the set of data tags defined by the allowed data tags condition section. If there is no :xmltag:`data_tags` section, then the default empty set is assumed. This means that the allow action (e.g., publish action) would only allow publishing if there are no data tags associated with the |DDS_EP| (e.g., |DW| for a publish action). Example (appearing within an :xmltag:`allow_rule` and within a :xmltag:`publish` tag): .. code-block:: xml Square aTagName1 aTagValue1 The above allowed data tags condition would be matched if the data tags associated with the |DDS_ENTITY| performing the action (e.g., |DW| for publish action) are a subset of the set :value:`[(aTagName1, aTagValue)]`. So it would be OK to publish using a |DW| with no associated data tags, or a |DW| with a single tag with name :value:`aTagName1` and value :value:`aTagValue1`. Behavior of data_tags within a deny_rule ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the :xmltag:`data_tags` are under a :xmltag:`deny_rule`, then the :xmltag:`data_tags` delimit a denied data tags condition section. For this condition to be met, the |DDS_ENTITY| associated with the action (e.g., |DW| for a publish action) must have a data tag name and value pair that matches one of the data tags explicitly listed in the denied data tags condition section. If there is no :xmltag:`data_tags` section, then the "set of all possible tags" set is assumed as default. This means that the deny action (e.g., deny publish action) would apply regardless of the data tags associated with the |DDS_EP| (e.g., |DW| for a publish action). Example (appearing within a :xmltag:`deny_rule` and within a :xmltag:`publish` tag): .. code-block:: xml aTagName1 aTagValue1 The above denied data tags condition would be matched if the data tags associated with the |DDS_ENTITY| performing the action (e.g., |DW| for a publish action) intersect the set :value:`[(aTagName1, aTagValue1)]`. So it would not deny publishing using a |DW| with no associated data-tags, or a |DW| with a single tag with name :value:`aTagName2`, or a |DW| with a single tag with name :value:`aTagName1` and value :value:`aTagValue2`. But it would deny publishing using a |DW| with two associated data tags :value:`[(aTagName1, aTagValue1), (aTagName2, aTagValue2)]`. :numref:`Effect of the Example Deny Rule When Different Data Tags Are Present` analyzes other scenarios for this concrete example. .. list-table:: Effect of the Example Deny Rule When Different Data Tags Are Present :name: Effect of the Example Deny Rule When Different Data Tags Are Present :width: 70% :widths: auto :align: center :header-rows: 1 :class: longtable * - |DW| Tag(s) - Allow/Deny * - .. code-block:: xml aTagName1 aTagValue1 - Deny * - .. code-block:: xml - Allow * - .. code-block:: xml aTagName1 aTagValue2 - Allow * - .. code-block:: xml aTagName2 aTagValue1 - Allow * - .. code-block:: xml aTagName1 aTagValue1 aTagName2 aTagValue2 - Deny Related Governance Rules ======================== This section describes the Access Control attributes that appear in the |GovernanceDoc|. Domain-level rules ------------------ The following attributes can be configured inside a :xmltag:`domain_rule`: enable_join_access_control (within a domain_rule) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :xmltag:`enable_join_access_control` may be :xmlval:`TRUE` or :xmlval:`FALSE`. It controls whether or not |DP|-level permissions are checked when a |DP| is created or discovered. When :xmltag:`enable_join_access_control` = :xmlval:`TRUE`, the local |DP| will check whether it has permission to join the |DOMAIN|. If it does, it will perform the same check for each of the remotely discovered |DPs|. When :xmltag:`enable_join_access_control` = :xmlval:`FALSE`, the local |DP| is still required to have a valid |PermissionsDoc|, but this |PermissionsDoc| is not required to allow the local |DP| to join the |DOMAIN|. Remote |DPs| are not even required to have a valid |PermissionsDoc| unless :xmltag:`enable_read_access_control` = :xmlval:`TRUE` or :xmltag:`enable_write_access_control` = :xmlval:`TRUE` for a discovered |TOPIC|. Note that :xmltag:`enable_join_access_control` does not affect endpoint-level permissions such as publishing or subscribing to specific |TOPICs|. The |AccessControlPlugin| will not check participant-level permissions for |DPs| that cannot be authenticated because they either are unsecure participants or they fail to authenticate. Therefore, :xmltag:`enable_join_access_control` does not have any effect when :xmltag:`allow_unauthenticated_participants` = :xmlval:`TRUE`, and the remote participant is unauthenticated. For more information, see :ref:`p2_core/access_control:Participant-level Permissions, Endpoint-level Permissions, and Unsecure DomainParticipants`. topic_access_rules (domain_rule) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :xmltag:`topic_access_rules` contains one or more :xmltag:`topic_rule` attributes where you can define your system's security requirements on a per-topic basis (see :ref:`p2_core/access_control:Governance Document`). Topic-level rules ------------------ The following attributes can be configured inside a :xmltag:`topic_rule`: enable_read_access_control (topic_rule) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This attribute may be :xmlval:`TRUE` or :xmlval:`FALSE`. It controls whether or not endpoint-level permissions are checked for |DRs|. If :xmltag:`enable_read_access_control` = :xmlval:`TRUE` for a given :xmltag:`topic`, the local permissions are enforced on locally created |DRs| of that :xmltag:`topic`, and the remote permissions are enforced on remotely discovered |DRs| of that :xmltag:`topic`. enable_write_access_control (topic_rule) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This attribute may be :xmlval:`TRUE` or :xmlval:`FALSE`. It controls whether or not |DW| permissions are checked. If :xmltag:`enable_writer_access_control` is :xmlval:`TRUE` for a given :xmltag:`topic`, the local permissions are enforced on locally created |DWs| of that :xmltag:`topic`, and the remote permissions are enforced on remotely discovered |DWs| of that :xmltag:`topic`. No Matching Rule ^^^^^^^^^^^^^^^^ If no matching domain (in the case of |DPs|) or topic rule (in the case of |DWs|/|DRs|) is found in the |GovernanceDoc|, the |Entity| creation will fail when Access Control checks if this |Entity| can be created in this |DOMAIN|. This is done because if there is no rule, the |AccessControlPlugin| assumes no permissions, which is the more restrictive decision. Advanced Access-Control Concepts ================================ Participant-Level Permissions, Endpoint-Level Permissions, and Unsecure DomainParticipants ------------------------------------------------------------------------------------------ As mentioned earlier, you can control whether the |AccessControlPlugin| will check participant-level permissions and endpoint-level permissions for remote participants with the enable_*_control Governance rules (see :ref:`p2_core/access_control:Related Governance Rules`). The |AccessControlPlugin| checks these permissions in different stages of the communication, so they are independent. (Note that successfully authenticated remote participants must present a grant matching the subject name in its |IdentityCert|, even though remote permissions checking is disabled. Authenticated participants failing to provide such a grant will be rejected.) The :xmltag:`enable_join_access_control` Governance rule controls whether the |AccessControlPlugin| will check participant-level permissions for remotely discovered participants. Your local participant (|P1|) checks participant-level permissions when it discovers and authenticates a remote participant (|P2|). When :xmltag:`enable_join_access_control` = :xmlval:`TRUE`, |P1| will check whether |P2| has permission to join the |SecDomain|. In other words, |P1| will check whether |P2| has an :xmltag:`allow_rule` that includes this |DOMAIN| in its |PermissionsDoc| (as specified with the :xmltag:`domains` tag). When :xmltag:`enable_join_access_control` = :xmlval:`FALSE`, |P1| skips this check. In turn, :xmltag:`enable_read_access_control`, and :xmltag:`enable_write_access_control` Governance rules control whether the |AccessControlPlugin| will check endpoint-level permissions for both locally created and remotely discovered |EPs|. When :xmltag:`enable_read_access_control` = :xmlval:`TRUE` for a given |TOPIC| (*T*), |P1| will enforce permissions on locally created |DRs| of |TOPIC| *T*. Also, |P1| will check whether |P2| |DRs| have permission to subscribe to |TOPIC| *T*. In other words, when :xmltag:`enable_read_access_control` = :xmlval:`TRUE` , |P1| will check: #. Whether |P1| has an :xmltag:`allow_rule` that includes permissions to subscribe to |TOPIC| *T* (as specified with the subscribe tag). This check takes place upon the creation of a |DR| for |TOPIC| *T*. #. Whether |P2| has an :xmltag:`allow_rule` that includes permissions to subscribe to |TOPIC| *T* (as specified with the subscribe tag). This check takes place upon the discovery of a |DR| for |TOPIC| *T* in |P2|. The same logic applies to :xmltag:`enable_write_access_control` and |DWs|. When :xmltag:`allow_unauthenticated_participants` = :xmlval:`TRUE`, unsecure |DPs| will be allowed to join the |DOMAIN|. Since unsecure |DPs| do not load the |RTI_SP_PRODUCT|, participant-level permissions and endpoint-level permissions for unsecure participants cannot be verified. Continuing with our previous example, a remote unsecure participant (|P3|) will not load the |RTI_SP_PRODUCT|; therefore, it cannot be bound to a Permissions or |GovernanceDoc|. From |P1|'s perspective, this is similar to having a |PermissionsDoc| that denies permissions for publishing/subscribing to any secure |TOPIC| (but not for joining the |DOMAIN|). As a result, |P3| has permission to join any |SecDomain| that sets :xmltag:`allow_unauthenticated_participants` = :xmlval:`TRUE`. However, |P3| is only allowed to subscribe to |TOPICs| that do not enforce read access control (:xmltag:`enable_read_access_control` = :xmlval:`FALSE`) and is only allowed to publish |TOPICs| that do not enforce write access control (:xmltag:`enable_write_access_control` = :xmlval:`FALSE`). Please note that if :xmltag:`allow_unauthenticated_participants` = :xmlval:`FALSE` for this domain, communication ends when |P1| fails to authenticate |P3|; neither endpoint discovery nor Permissions checks happen in this case. To summarize: * When :xmltag:`enable_read_access_control` = :xmlval:`TRUE`, the |TOPIC| is protected from unauthorized |DRs| (only participants that have permissions to subscribe to that |TOPIC| can subscribe to it). * When :xmltag:`enable_read_access_control` = :xmlval:`FALSE`, any |DR| of this |TOPIC| can subscribe to it (provided that the |DP| this |DR| belongs to, succeeds in joining the |SecDomain|). Therefore, enabling read access control (:xmltag:`enable_read_access_control` = :xmlval:`TRUE`) does not affect secure participants' ability to publish a particular |TOPIC|. However, it does affect the unsecure participants' ability to subscribe to that |TOPIC|, since only secure participants with permissions to subscribe to that |TOPIC| will be allowed to do so. Also note that :xmltag:`enable_read_access_control` = :xmlval:`TRUE` will enforce checks on both locally created and remotely discovered |DRs|, regardless of the value of :xmltag:`enable_join_access_control`. The same logic applies to :xmltag:`enable_write_access_control` and |DWs|. Access Control and Unauthenticated Participants ----------------------------------------------- The following matrix shows the security implications of the combinations of :xmltag:`allow_unauthenticated_participants` and :xmltag:`enable_join_access_control`. As described in :ref:`p2_core/authentication:allow_unauthenticated_participants (domain_rule)`, :xmltag:`allow_unauthenticated_participants` determines whether participants failing to authenticate will be allowed to communicate in the system, whereas :xmltag:`enable_join_access_control` determines whether the participant-level permissions of successfully authenticated remote participants will be checked. In other words, :xmltag:`allow_unauthenticated_participants` deals with the result of the authentication process (performed right after the participant discovery phase); :xmltag:`enable_join_access_control` deals with the result of a participant-level permissions check (performed right after the remote participant is successfully authenticated). Also note that the participant-level permissions check does not apply to allowed unauthenticated remote participants (i.e., unauthenticated remote participants that are allowed in the |DOMAIN| because :xmltag:`allow_unauthenticated_participants` = :xmlval:`TRUE`). .. list-table:: Security Implications of :xmltag:`allow_unauthenticated_participants` and :xmltag:`enable_join_access_control` :name: Security Implications of allow_unauthenticated_participants and enable_join_access_control :widths: 15 15 70 :header-rows: 1 :class: longtable * - :xmltag:`allow_unauthenticated_participants` - :xmltag:`enable_join_access_control` - Security Implications * - :xmlval:`FALSE` - :xmlval:`FALSE` - Participants failing to authenticate (including unsecure participants) cannot join the |SecDomain|. Once a remote secure participant successfully authenticates, the local participant trusts it to communicate in the |DOMAIN| and its permissions are not checked. Note that the Authentication Plugin always checks whether the local secure participant has permissions to join the |DOMAIN|, regardless of :xmltag:`enable_join_access_control`. * - :xmlval:`FALSE` - :xmlval:`TRUE` - Participants failing to authenticate (including unsecure participants) cannot join the |SecDomain|. When a remote secure participant successfully authenticates, its permissions to joining the |DOMAIN| are locally checked. The remote participant will only be allowed in the |DOMAIN| if it has the right permissions. * - :xmlval:`TRUE` - :xmlval:`FALSE` - Participants failing to authenticate (including unsecure participants) can join the |SecDomain|. However, they can only publish to |TOPICs| that are not protected against unauthorized |DWs| and can only subscribe to |TOPICs| that are not protected against unauthorized |DRs|. * - :xmlval:`TRUE` - :xmlval:`TRUE` - Participants failing to authenticate (including unsecure participants) can join the |SecDomain|. However, they can only publish to |TOPICs| that are not protected against unauthorized |DWs| and can only subscribe to |TOPICs| that are not protected against unauthorized |DRs|. When a remote secure participant successfully authenticates, its permissions to joining the |DOMAIN| are locally checked. The remote participant will only be allowed in the |DOMAIN| if it has the right participant-level permissions. Properties for Configuring Access Control ========================================= :numref:`DDS Security Properties for Configuring Access Control` lists the properties that you can set to configure Access Control. These properties are configured through the |DP|'s PROPERTY QosPolicy (see :ref:`p2_core/elements_dds_secure_system:QoS Properties`). .. list-table:: DDS Security Properties for Configuring Access Control :name: DDS Security Properties for Configuring Access Control :widths: 40 60 :header-rows: 1 :class: longtable * - Property Name - Property Value Description * - :property:`dds.sec.access.permissions_ca` - :required:`Required` This Permissions Certificate Authority is used for signing access control governance and permissions XML files and verifying the signatures of those files. The Permissions Certificate Authority file may or may not be the same as the Identity Certificate Authority file. Two participants that want to securely communicate with each other must use the same Permissions Certificate Authority. The document should be in PEM format. You may specify either the file name or the document contents. If specifying the file name, the property value must have the prefix :value:`file:` (no space after the colon), followed by the fully qualified path and name of the file. If specifying the contents of the document, the property value must have the prefix :value:`data:,` (no space after the comma), followed by the contents inside the document. For example: .. code-block:: none :class: break-lines-anywhere "data:,-----BEGIN CERTIFICATE-----\nabcdef\n-----END CERTIFICATE-----" Note that the two ``\n`` characters are required. :type:`String`. Default: :value:`NULL` * - :property:`dds.sec.access.governance` - :required:`Required` The signed document that specifies the level of security required per |DOMAIN| and per |TOPIC| (see :ref:`p2_core/access_control:Governance Document`). The Permissions CA (:property:`dds.sec.access.permissions_ca`) must sign the |GovernanceDoc| using S/MIME version 3.2 format (which corresponds to the mime-type application/pkcs7-signature). You may specify either the file name or the document contents. If specifying the file name, the property value must have the prefix :value:`file:` (no space after the colon), followed by the fully qualified path and name of the file. If specifying the contents of the document, the property value must have the prefix :value:`data:,` (no space after the comma), followed by the contents inside the document. For example: .. code-block:: none :class: break-lines-anywhere "data:,MIME-Version: 1.0\nContent-Type:...boundary=\"---7236--\"\n\n" Note that for signed XML files, all whitespace characters (' ', '\r', '\n') are significant, and all quotes must be escaped by a backslash. The safest way to get the correct property value is to call the ``fread()`` function on the file and use the resulting buffer as the property value. :type:`String`. Default: :value:`NULL` * - :property:`dds.sec.access.permissions` - :required:`Required` The signed document that specifies the access control permissions per |DOMAIN| and per |TOPIC| (see :ref:`p2_core/access_control:Permissions Document`) for individual |DPs| identified by subject names. The Permissions CA (:property:`dds.sec.access.permissions_ca`) must sign the |PermissionsDoc| using S/MIME version 3.2 format (which corresponds to the mime-type application/pkcs7-signature). The :xmltag:`subject_name` element identifies the |DP| to which the permissions apply. Each subject name can only appear in a single :xmltag:`permissions` section within the XML |PermissionsDoc|. The contents of the :xmltag:`subject_name` element should be the X.509 subject name for the |DP|. The format of the subject name should conform to `IETF RFC 4514 "Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names `_. Specifically, the `=` character should separate an attribute's name from its value, and the `,` character should separate attributes from each other. See :link_connext_dds_secure_gsg:`Hands-on 4 ` in the |SP_GSG| for an example openssl command to extract a correctly-formatted subject name. A :xmltag:`permissions` section with a subject name that does not match the subject name given in the corresponding |IdentityCert| will be ignored. The signed |PermissionsDoc| only supports validity dates between 1970-01-01T00:00:00Z and 2038-01-19T03:14:08Z. Any dates before 1970-01-01T00:00:00Z will result in an error, and any dates after 2038-01-19T03:14:08Z will be treated as 2038-01-19T03:14:08Z. Currently, |CONNEXT| will not work if the system time is after January 19th, 2038. You may specify either the file name or the document contents. If specifying the file name, the property value must have the prefix "file:" (no space after the colon), followed by the fully qualified path and name of the file. If specifying the contents of the document, the property value must have the prefix "data:," (no space after the comma), followed by the contents inside the document. For example: .. code-block:: none :class: break-lines-anywhere "data:,MIME-Version: 1.0\nContent-Type:...boundary=\"---7236--\"\n\n" Note that for signed XML files, all whitespace characters (' ', '\r', '\n') are significant, and all quotes must be escaped by a backslash. The safest way to get the correct property value is to call the ``fread()`` function on the file and use the resulting buffer as the property value. :type:`String`. Default: :value:`NULL` * - :property:`dds.sec.access.rtps_psk_protection_kind` - :required:`Optional` It specifies how to protect messages when using :ref:`p3_advanced/pre-shared_key:|PSKProtection|`: don't protect them, protect only their integrity, or protect both their integrity and confidentiality. This property can only be used in :ref:`p3_advanced/lightweight_security:The |LIGHT_SP_BUILTIN_HEADING|`. The |SP_BUILTIN| do not support this property. Instead, use the :xmltag:`rtps_psk_protection_kind` domain rule from the |GovernanceDoc|. For more information, read :ref:`p2_core/cryptography:rtps_psk_protection_kind (domain_rule)`. :type:`Enum`: :value:`NONE` (do not protect), :value:`SIGN` (protect the integrity), :value:`ENCRYPT` (protect the integrity and confidentiality). Default: :value:`ENCRYPT` .. list-table:: |RTI_SP_PRODUCT| Properties for Configuring Access Control :name: |RTI_SP_PRODUCT_HEADING| Properties for Configuring Access Control :widths: 40 60 :header-rows: 1 :class: longtable * - Property Name (prefix with :property:`com.rti.serv.secure.`) [#fPrefix]_ - Property Value Description * - :property:`access_control.alternative_permissions_authority_files` - :required:`Optional` A comma-separated list of alternative Permissions CA certificates. If verification of either the |PermissionsDoc| or the |GovernanceDoc| fails with the main certificate (:property:`dds.sec.access.permissions_ca`), verification will be retried with all of the corresponding alternative certificates. If none of the alternative certificates can be used to verify the file, the verification process will fail. If any of the alternative certificate files fail to be loaded, the |DP| creation will fail. This property value may optionally contain :value:`file:` (no space after the colon) as a prefix to any of the elements in the list. :type:`String`. Default: :value:`NULL` * - :property:`access_control.use_530_permissions_rules_precedence` - :required:`Optional` How to deal with conflicting allow/deny rules in a |PermissionsDoc| when checking for a |TOPIC|, |DW|, or |DR|'s permission to exist. * If :value:`TRUE`: the last rule will take precedence, which is consistent with the behavior in |CONNEXT| 5.3.0 and earlier versions. * If :value:`FALSE`: the first rule will take precedence, which is consistent with the intended behavior of the |SEC_SPEC| (see :ref:`p2_core/elements_dds_secure_system:How the Permissions are Interpreted`). :type:`Boolean`. Default: :value:`FALSE` * - :property:`access_control.use_530_logging_protection` - :required:`Optional` How to set the value of :xmltag:`metadata_protection_kind` for the |LoggingT|. * If :value:`TRUE`: the value will be :xmlval:`NONE`, which is consistent with |CONNEXT| 5.3.0 behavior. * If :value:`FALSE`: the value will be SIGN, which is consistent with the behavior of the |SEC_SPEC|. :type:`Boolean`. Default: :value:`FALSE` * - :property:`access_control.use_530_partitions` - :required:`Optional` How to determine a match between a |DW| or |DR|'s |PARTITIONs| and an "allowed partitions" condition in a |PermissionsDoc|. * If :value:`TRUE`: an |Entity| is matched if it has at least one partition in the condition; this is consistent with the behavior in |CONNEXT| 5.3.0 and earlier versions. * If :value:`FALSE`: an |Entity| is matched only if all of its |PARTITIONs| are in the condition; this is consistent with the behavior of the |SEC_SPEC| (see :ref:`p2_core/access_control:Partitions`). For example, if a |DW| has |PARTITIONs| [A, B], and a |PermissionsDoc| allows |PARTITIONs| [B, C], then when :property:`use_530_partitions` = :value:`TRUE`, the |DW| is allowed because B is allowed. When :property:`use_530_partitions` = :value:`FALSE`, the |DW| is not allowed because A is not allowed. :type:`Boolean`. Default: :value:`FALSE` * - :property:`access_control.use_610_permissions_rules_precedence` - :required:`Optional` How to deal with conflicting allow/deny rules in a |PermissionsDoc| when checking for a |DP|'s permission to exist. * If :value:`false`: the first rule will take precedence, which is consistent with the behavior of the |SEC_SPEC| (see :ref:`p2_core/elements_dds_secure_system:How the Permissions are Interpreted`). * If :value:`true`: the last rule will take precedence, which is consistent with the behavior in |CONNEXT| 6.1.0 and earlier versions. * If :value:`auto`: for the local |DP|, the first rule will take precedence. For discovered remote |DPs|, the last rule will take precedence only if the discovered |DP| is |CONNEXT| 6.1.0 or earlier. :type:`Enum`: :value:`false`, :value:`true` :value:`auto` Default: :value:`auto` .. [#fPrefix] Assuming you used :value:`com.rti.serv.secure` as the alias to load the plugin. If not, change the prefix to match the string used with :property:`com.rti.serv.load_plugins`, followed by the :value:`.` character.