ros2 / sros2

tools to generate and distribute keys for SROS 2
Apache License 2.0
91 stars 46 forks source link

Provide some granularity for individual topic protection #130

Open mikaelarguedas opened 5 years ago

mikaelarguedas commented 5 years ago

Feature request

Feature description

While DDS allows to pick any protection kind for the topics and associated discovery, it is currently not exposed by sros2 that uses a static governance file. Currently all data / discovery / liveliness is encrypted by default. Generating the governance file at the same time as generating the permission files would allow to pick the type of protection desired on a per-topic basis.

Implementation considerations

Modifying the SROS2 policy format to take an extra attribute protection for each topic/service/action list would allow to specify that information and leverage it to generate governance topic rules accordingly. Then create a governance.xsl template that would create an governance file with a TopicRule for each topic specified in the policy.

Trade-offs:

Providing full granularity of the governance parameters will be cumbersome and complex for maintainers to support and for users to use. At which point writing it by hand may be easier. The goal here would be to allow users to specify the protection of their topic in the high level policy file and generate a consistent set of governance/permission. Example of node configuration:

Some parameters apply to the participant globally and will impact the usefulness of setting other parameters on a per topic basis, some specific use-cases to explore (very sparse list):

This is a draft to gather initial feedback, if the approach seems sensible, the use cases to consider and trade-offs can be expanded later on.

Example of policy and governance files Policy: ```xml fibonacci add_two_ints chatter ``` Governance: ```xml 0 false true SIGN SIGN SIGN rt/chatter true true true true SIGN ENCRYPT rq/add_two_ints_Request true true true true SIGN SIGN rr/add_two_ints_Reply true true true true SIGN SIGN * true true true true SIGN SIGN ```
mikaelarguedas commented 5 years ago

@jacobperron @mjcarroll friendly :bellhop_bell: , any comment on this and connected PR ?

mjcarroll commented 5 years ago

I think that this makes sense, I'll have to think about the trade-offs a bit more.

I believe that @ruffsl or @emersonknapp may have some additional thoughts/opinions as well.

kyrofa commented 5 years ago

This approach seems sensible to me, but as you point out, exposing this ability also brings along a fair bit of complexity. I'm struggling to come up with solid use-cases for this that outweigh that maintenance cost, particularly considering that this (what I would call "advanced") use-case is already possible by manually tweaking the governance file.

ruffsl commented 5 years ago

I’ve been thinking about this and how to interleave protection configuration for a while, specifically in terms of the composability aspect. After I opened the sros2 policy design document PR https://github.com/ros2/design/pull/246 , @mikaelarguedas and I spoke a little offline about approaching this. A particular concern I wrote about in that design doc was on the separation of concern, and how mixing permissions and governance configuration could lead to interferences or limit composability. However, I think I have a decent approach that would retain both simplicity and flexibility.

An idea would be to introduce protection as an optional attribute to permissions as well as profiles, that could be used to set/override the scope defined by parent elements within the XML document tree. This allows permissions or entire unaltered profiles to inherit scopes of protection settings over the policy, while still allowing for specific element to be fine tuned.

<?xml version="1.0" encoding="UTF-8"?>
<policy version="0.2.0"
  xmlns:xi="http://www.w3.org/2001/XInclude">
  <!-- Scope default profiles protection (required) -->
  <profiles protection="ENCRYPT">
    <!-- Override profiles protection within profile scope (optional) -->
    <profile ns="/" node="talker" protection="SIGN">
      <!-- Override profile protection within permission scope (optional) -->
      <topics publish="ALLOW" protection="ENCRYPT">
        <topic>chatter</topic>
      </topics>
      <include package="sros2_common_assets"
        href="profile/node.xml"
        xpointer="xpointer(/profile/*)"/>
    </profile>
    <!-- Retain profiles protection within profile scope (optional) -->
    <profile ns="/" node="listener">
      <!-- Retain profile protection within permission scope (optional) -->
      <topics subscribe="ALLOW" >
        <topic>chatter</topic>
      </topics>
      <include package="sros2_common_assets"
        href="profile/node.xml"
        xpointer="xpointer(/profile/*)"/>
    </profile>
    <!-- Scope override in conditional upon imported attributes -->
    <include package="sros2_common_assets"
      href="profiles/sros2_common_policies.xml"
      xpointer="xpointer(/profiles/*)"/>
    <include package="sros2_common_assets"
      href="profiles/add_two_ints.xml"
      xpointer="xpointer(/profiles/*)"/>
  </profiles>
</policy>

In terms of how this maps to Secure DDS governance, I think it would be simplest, while satisfying most average use cases, if we use the projected protection scopes to set <data_protection_kind> setting per DDS topic in the governance file specific to each participant. The rest of the advance governance settings I think would be better configured by a global template that user could provide at design time, where we could ship a sensible/conservative default with sros CLI package.

However, that approach wouldn't afford any means of setting SIGN_WITH_ORIGIN_AUTHENTICATION or ENCRYPT_WITH_ORIGIN_AUTHENTICATION from within the policy file, given that controlled from the <metadata_protection_kind> tag in the governance. We could have some standard lookup mapping:

sros data_protection_kind metadata_protection_kind
NONE NONE NONE
SIGN SIGN SIGN
ENCRYPT ENCRYPT ENCRYPT
SIGN_OAUTH SIGN SIGN_WITH_ORIGIN_AUTHENTICATION
ENCRYPT_OAUTH ENCRYPT ENCRYPT_WITH_ORIGIN_AUTHENTICATION

Given that ORIGIN_AUTHENTICATION can't be used without setting properties like cryptography.max_receiver_specific_macs, like that in RTI DDS Connext v6.0, (Table 10.1), perhaps we could shelf ORIGIN_AUTHENTICATION until we know what we want. https://community.rti.com/static/documentation/connext-dds/6.0.0/doc/manuals/connext_dds/dds_security/RTI_SecurityPlugins_GettingStarted.pdf