.. include:: ../vars.rst

.. _chapter-best-practices:

**************
Best Practices
**************

Choosing the Granularity of Your Permissions Documents for DomainParticipants
=============================================================================

For better performance and reduced network usage, use individual
|PermissionsDocs| for each |DP| in your secure system. A |PermissionsDoc|
should only specify the permissions for the |DP| loading it.

When you use |SP_BUILTIN|, the |PermissionsDoc| specifies what a |DP| is allowed to
do, such as what |DOMAINs|/partitions it can join and what topics it can
read/write. This |PermissionsDoc| is always sent during Authentication so that
every |DP| knows about every other |DP|’s permissions. The |PermissionsDoc| is
signed by the Permissions CA, which guarantees its authenticity.

Although a single |PermissionsDoc| could technically be used to specify the
permissions of every |DP| in the system, this approach comes with a high
overhead:

#. **Storage overhead**: the shared |PermissionsDoc| will have multiple entries
   (corresponding to the permissions of multiple |DPs|). Thus, every |DP| will
   need to store a bigger |PermissionsDoc|.
#. **Network usage overhead**: when two |DPs| discover each other, the shared
   |PermissionsDoc| still needs to be sent both ways, and it’s large.
   Individual |PermissionsDocs| are smaller.
#. **Processing and memory consumption overhead**: the signature in the received
   |PermissionsDoc| needs to be verified against the Permissions CA’s digital
   certificate. The bigger the |PermissionsDoc|, the more computational power
   needed to verify its signature. Searching through a |PermissionsDoc| with
   multiple entries also increases the computational cost.

To avoid this overhead, we recommend using individual |PermissionsDocs| for
each |DP| in your system, containing only the grants for that |DP|. Security
will not be affected by this implementation; since the Permissions CA signs the
|PermissionsDoc|, any |DP| trusting that Permissions CA can verify whether
another |DP| has the permissions it claims. For more information, see
:ref:`p3_advanced/design_considerations:Contents of your Permissions Documents`.


Using Serialized Data Protection Along with Submessage/RTPS Protection
======================================================================

Depending on what parts of the communication you want to protect, you could
enable |DataProtection| (to protect just user data), |SubmsgProtection| (to
protect both user data and metadata sent by your user endpoints), or
|RTPSProtection| (to protect all the RTPS traffic sent by your participants).

One valid configuration would be to configure :xmlval:`SIGN` |RTPSProtection|,
so we ensure the integrity of all the messages exchanged, and then configure
:xmlval:`ENCRYPT` |SubmsgProtection| so the confidentiality of the necessary topics is protected.

Depending on the protection you configure at one level, subsequent level
protections could be redundant. For instance, if you set
:xmltag:`metadata_protection_kind` to :xmlval:`ENCRYPT`, the confidentiality of
both data and metadata sent by your user endpoints will be protected, hence
there is no point in also having :xmltag:`data_protection_kind` at the same
time. However, there are some use cases where you may want to enable multiple
protection kinds at the same time.

For example, if you use |PERSISTENCESERVICE| and want to store samples in an
encrypted format, you need to enable encryption for the
:xmltag:`data_protection_kind`. Suppose you also want to encrypt sequence
numbers, GUIDs, ACKNACKs, and HEARTBEATs – then you will also need to enable
encryption for the :xmltag:`metadata_protection_kind`.

In conclusion, often, you don't need both settings enabled -- but there are some
use cases where you need both settings enabled.


Using Separate Domains for Secure and Unsecure Participants
===========================================================

You can use |ROUTINGSERVICE| to address the use case where secure and unsecure
participants need to talk to each other.


Keeping Governance and Permissions Compatibility Across Different |RTI_SP_PRODUCT_HEADING| Versions
===================================================================================================

Use the ``must_interpret`` attribute with a value of :xmlval:`FALSE` when a
|CONNEXT| release introduced an XML tag that is not supported in previous
versions. XML tags that have ``must_interpret="false"`` will not trigger a
parser error during XML validation.

For example, if a future version supports a hypothetical
:xmltag:`my_own_algorithms` tag in the Governance Document, you could have:

  .. code-block:: xml

    ...
    <allowed_security_algorithms>
        <symmetric_cipher>
            <algorithm>AES128+GCM</algorithm>
            <algorithm>AES256+GCM</algorithm>
        </symmetric_cipher>

        <my_own_algorithms must_interpret="false">
            <algorithm>CUSTOM+VALUE</algorithm>
        </my_own_algorithms>
    </allowed_security_algorithms>
    ...

Other |CONNEXT| releases that do not understand the :xmltag:`my_own_algorithms`
tag will not fail during validation of the |GovernanceDoc|. The XML parser will
ignore :xmltag:`my_own_algorithms` and all its children.

Read :ref:`p2_core/elements_dds_secure_system:How the Governance Document is Interpreted`
and :link_connext_dds_pro_um:`How the XML is Validated in the Core Libraries
User's Manual <#users_manual/How_the_XML_is_Validated.htm>` for more information
on the ``must_interpret`` attribute.
