diff --git a/articles/ros2_access_control_policies.md b/articles/ros2_access_control_policies.md index 948bc5238..6d1914b69 100644 --- a/articles/ros2_access_control_policies.md +++ b/articles/ros2_access_control_policies.md @@ -99,10 +99,28 @@ Attributes: - **version**: declared version of schema version in use - Allows for advancing future revisions of the schema +### `` Tag + +Encapsulates a sequence of unique contexts. +This method of nesting sequences allows for additional tags to be extended to the `` root. + +### `` Tag + +Encapsulates a collection of profiles. +This is specific to a context as determined by associative attributes. + +Attributes: +- **path**: Fully qualified context path + +Given that multiple nodes can be composed into a single process, a context is used to contain the collection of profiles of all respective nodes. +A context may therefor be considered the union of contained profiles. +Note that the union of profiles within a context will result in denied privileges of any profile to supersede all allowed privileges for every profile. +See section `` Tag for more info on MAC is applied. + ### `` Tag Encapsulates a sequence of unique profiles. -This method of nesting sequences allows for additional tags to be extended to the `` root. +This method of nesting sequences allows for additional tags to be extended to the `` root. ### `` Tag diff --git a/articles/ros2_access_control_policies/policy.xsd b/articles/ros2_access_control_policies/policy.xsd index 8086516e9..0e8bf77bf 100644 --- a/articles/ros2_access_control_policies/policy.xsd +++ b/articles/ros2_access_control_policies/policy.xsd @@ -10,11 +10,24 @@ - + + + + + + + + + + + + + + diff --git a/articles/ros2_dds_security.md b/articles/ros2_dds_security.md index ef82e6c71..5250eb802 100644 --- a/articles/ros2_dds_security.md +++ b/articles/ros2_dds_security.md @@ -45,7 +45,7 @@ Let's delve a little further into those first three plugins. ## Authentication -The **Authentication** plugin (see section 8.3 of the [DDS-Security spec][dds_security]) is central to the entire SPI architecture, as it provides the concept of a confirmed identity without which further enforcement would be impossible (e.g. it would be awfully hard to make sure a given ROS node could only access specific topics if it was impossible to securely determine which node it was). +The **Authentication** plugin (see section 8.3 of the [DDS-Security spec][dds_security]) is central to the entire SPI architecture, as it provides the concept of a confirmed identity without which further enforcement would be impossible (e.g. it would be awfully hard to make sure a given ROS context could only access specific topics if it was impossible to securely determine which context it was). The SPI architecture allows for a number of potential authentication schemes, but ROS 2 uses the builtin authentication plugin (called "DDS:Auth:PKI-DH", see section 9.3 of the [DDS-Security spec][dds_security]), which uses the proven Public Key Infrastructure (PKI). It requires a public and private key per domain participant, as well as an x.509 certificate that binds the participant's public key to a specific name. @@ -114,7 +114,7 @@ Let's discuss each of these in turn. ### Security files for each domain participant As stated earlier, the DDS-Security plugins require a set of security files (e.g. keys, governance and permissions files, etc.) per domain participant. -Domain participants map to a specific instance of a node in ROS 2, so each node requires a set of these files. +Domain participants map to a specific instance of a context in ROS 2, so each context requires a set of these files. RCL supports being pointed at a directory containing security files in two different ways: - Directory tree of all security files. @@ -125,41 +125,42 @@ Let's delve further into these. #### Directory tree of all security files -RCL supports finding security files in one directory that is the root of a directory structure corresponding to the fully-qualified names of every node instance (i.e. namespace + node name). -For example, for the `/front/camera` node, the directory structure would look like: +RCL supports finding security files in one directory that is the root of a directory structure corresponding to the fully-qualified names of every context (e.g. namespace + context name). +For example, for the `/front/camera` context, the directory structure would look like: - └── front - └── camera - ├── cert.pem - ├── key.pem - ├── ... + └── contexts + └── front + └── camera + ├── cert.pem + ├── key.pem + ├── ... To be clear: this directory structure needs to reflect the state of the running system. -In other words, it does not contain a set of files per node on disk, but per node instance _in the ROS graph_. +In other words, it does not contain a set of files per context on disk, but per context instance _in the ROS graph_. -The set of files expected within each node instance directory are: +The set of files expected within each context instance directory are: - **identity_ca.cert.pem**: The x.509 certificate of the CA trusted by the **Authentication** plugin (the "Identity" CA). -- **cert.pem**: The x.509 certificate of this node instance (signed by the Identity CA). -- **key.pem**: The private key of this node instance. +- **cert.pem**: The x.509 certificate of this context instance (signed by the Identity CA). +- **key.pem**: The private key of this context instance. - **permissions_ca.cert.pem**: The x.509 certificate of the CA trusted by the **Access control** plugin (the "Permissions" CA). - **governance.p7s**: The XML document that specifies to the **Access control** plugin how the domain should be secured (signed by the Permissions CA). -- **permissions.p7s**: The XML document that specifies the permissions of this particular node instance to the **Access control** plugin (also signed by the Permissions CA). +- **permissions.p7s**: The XML document that specifies the permissions of this particular context instance to the **Access control** plugin (also signed by the Permissions CA). This can be specified by setting the `$ROS_SECURITY_ROOT_DIRECTORY` environment variable to point to the root of the directory tree. ##### Support security files lookup methods -If using the directory tree approach to organize security files, RCL supports two different methods for looking up a given node instance's security files in the tree: +If using the directory tree approach to organize security files, RCL supports two different methods for looking up a given context instance's security files in the tree: -- **Exact**: Only load security files from a directory exactly matching the fully-qualified name of the node instance. -For example, given a node named "baz_123" within the "/foo/bar/" namespace, only load security files from `/foo/bar/baz_123/`. +- **Exact**: Only load security files from a directory exactly matching the fully-qualified name of the context. +For example, given a context "baz_123" within the "/foo/bar/" namespace, only load security files from `/contexts/foo/bar/baz_123/`. This is the default behavior. -- **Prefix**: Attempt to load the most specific set of security files, but if they can't be found, check for security files under a less-specific node name. -For example, given a node named "baz_123" within the "/foo/bar/" namespace, load security files from `/foo/bar/baz_123/`. -However, if that directory doesn't exist, find the most specific (i.e. longest) node name that _does_ have security files within that namespace (e.g. `/foo/bar/baz_12/`, or `/foo/bar/baz/`, etc.). +- **Prefix**: Attempt to load the most specific set of security files, but if they can't be found, check for security files under a less-specific context path. +For example, given a context "baz_123" within the "/foo/bar/" namespace, load security files from `/contexts/foo/bar/baz_123/`. +However, if that directory doesn't exist, find the most specific (i.e. longest) context path that _does_ have security files within that namespace (e.g. `/contexts/foo/bar/baz_12/`, or `/contexts/foo/bar/baz/`, etc.). Note that it will not search higher in the namespace hierarchy. The desired lookup method can be specified by setting the `$ROS_SECURITY_LOOKUP_TYPE` environment variable to "MATCH_EXACT" (case-sensitive) for the **Exact** method, or "MATCH_PREFIX" (case-sensitive) for the **Prefix** method. @@ -167,20 +168,20 @@ The desired lookup method can be specified by setting the `$ROS_SECURITY_LOOKUP_ #### Manual specification -RCL supports specifying the path to a directory containing the set of security files for the exact node instance that needs to be launched. -The set of files expected within that directory are the same as outlined in the "Directory tree of all security files" section above for individual node instance directories. +RCL supports specifying the path to a directory containing the set of security files for the exact context instance that needs to be launched. +The set of files expected within that directory are the same as outlined in the "Directory tree of all security files" section above for individual context instance directories. -This can be specified by setting the `$ROS_SECURITY_NODE_DIRECTORY` environment variable to point to the directory containing the security files. +This can be specified by setting the `$ROS_SECURITY_CONTEXT_DIRECTORY` environment variable to point to the directory containing the security files. Note that this setting takes precedence over `$ROS_SECURITY_ROOT_DIRECTORY`. ### Support for both permissive and strict enforcement of security -Nodes with the security features enabled will not communicate with nodes that don't, but what should RCL do if one tries to launch a node that has no discernable keys/permissions/etc.? It has two options: +Contexts with the security features enabled will not communicate with contexts that don't, but what should RCL do if one tries to launch a context that has no discernable keys/permissions/etc.? It has two options: -- **Permissive mode**: Try to find security files, and if they can't be found, launch the node without enabling any security features. +- **Permissive mode**: Try to find security files, and if they can't be found, launch the context without enabling any security features. This is the default behavior. -- **Strict mode**: Try to find security files, and if they can't be found, fail to run the node. +- **Strict mode**: Try to find security files, and if they can't be found, fail to run the context. The type of mode desired can be specified by setting the `$ROS_SECURITY_STRATEGY` environment variable to "Enforce" (case-sensitive) for strict mode, and anything else for permissive mode. @@ -202,9 +203,9 @@ However, the [SROS 2 CLI](https://github.com/ros2/sros2) should include a tool ` - Create Identity and Permissions CA. - Create directory tree containing all security files. -- Create a new identity for a given node instance, generating a keypair and signing its x.509 certificate using the Identity CA. +- Create a new identity for a given context instance, generating a keypair and signing its x.509 certificate using the Identity CA. - Create a governance file that will encrypt all DDS traffic by default. -- Support specifying node instance permissions [in familiar ROS terms](/articles/ros2_access_control_policies.html) which are then automatically converted into low-level DDS permissions. +- Support specifying context instance permissions [in familiar ROS terms](/articles/ros2_access_control_policies.html) which are then automatically converted into low-level DDS permissions. - Support automatically discovering required permissions from a running ROS system. diff --git a/articles/ros2_security_contexts.md b/articles/ros2_security_contexts.md new file mode 100644 index 000000000..a8f56431c --- /dev/null +++ b/articles/ros2_security_contexts.md @@ -0,0 +1,307 @@ +--- +layout: default +title: ROS 2 Security Contexts +permalink: articles/ros2_security_contexts.html +abstract: + This article specifies the integration between security and contexts. +author: > + [Ruffin White](https://github.com/ruffsl), + [Mikael Arguedas](https://github.com/mikaelarguedas) + +published: false +categories: Security +--- + +{:toc} + + +# {{ page.title }} + +
+{{ page.abstract }} +
+ +Original Author: {{ page.author }} + + +TODO: Some concise overview introduction here + +## Concepts + +Before detailing the SROS 2 integration of the contexts, the following concepts are introduced. + +### Participant + +Participant is the object representing a single entity on the network, in the case of DDS the ``Participant`` is a DDS DomainParticipant and the object to which a set of access control and security identity apply. + +### Namespaces + +Namespaces are a fundamental design pattern in ROS and are widely used to organize and differentiate many types of resources as to be uniquely identifiable; i.e. for topics, services, actions, and node names. +As such, the concept of namespaceing is well know and understood by current users, as well as strongly supported with the existing tooling. +Namespaces are often configurable at runtime via command line arguments or statically/programmatically via launch file declarations. + +Previously, the Fully Qualified Name (FQN) of a node was used directly by a selected security directory lookup strategy to load the necessary key material. +However, with the advent of contexts, such a direct mapping of FQN to security artifacts may no longer suffice. + +### Contexts + +With the advent of ROS 2, multiple nodes may now be composed into one process for improved performance. +Previously however, each node would retain it's one to one mapping to a separate middleware ``Participant``. +Given the non-negligible overhead incurred of multiple ``Participant``s per process, a concept of contexts was introduced. +Contexts permit a many-to-one mapping of nodes to ``Participant`` by grouping many nodes per context, and one ``Participant`` per context. + +Based on the DDS Security specification v1.1, a ``Participant`` can only utilise a single security identity; consequently the access control permissions applicable to every node mapped to a given context must be consolidated and combined into a single set of security artifacts. +As such, additional tooling and extensions to SROS 2 are necessary to support this new paradigm. + + +## Keystore + +With the additional structure of contexts, it’s perhaps best to take the opportunity to restructure the keystore layout as well. +Rather than a flat directory of namespaced node security directories, we can push all such security directories down into a designated `contexts` sub-folder. +Similarly, private and public keystore materials can also be pushed down into their own respective sub-folders within the root keystore directory. +This is reminiscent of the pattern used earlier Keymint [1]. + + +``` +$ tree keystore/ +keystore +├── contexts +│ └── ... +│ └── ... +├── private +│ ├── ca.csr.pem +│ └── ca.key.pem +└── public + ├── ca.cert.pem + ├── identity_ca.cert.pem + └── permissions_ca.cert.pem +``` + + +### ``public`` + +The ``public`` directory contains anything permissable as public, such as public certificates for the identity or permissions certificate authorities. +As such, this can be given read access to all executables. +Note that in the default case, both the `identity_ca` and `permissions_ca` are the same CA certificate. + +### ``private`` + +The ``private`` directory contains anything permissable as private, such as private key material for aforementioned certificate authorities. +This directory should be redacted before deploying the keystore onto the target device/robot. + +### ``contexts`` + +The ``contexts`` directory contains the security artifacts associated with individual contexts, and thus node directories are no longer relevant. +Similar to node directories however, the `contexts` folder may still recursively nest sub-paths for organizing separate contexts. + + +## Runtime + +TODO: Some transition paragraph here about ros launch + +### Unqualified context path + +For nodes with unqualified context paths, the context directory will subsequently default to the root level context. + +``` xml + + + + +``` + +``` +$ tree contexts/ +contexts/ +├── cert.pem +├── governance.p7s +├── identity_ca.cert.pem +├── key.pem +├── permissions_ca.cert.pem +└── permissions.p7s +``` + +### Pushed unqualified context path + +For nodes with unqualified context paths pushed by a namespace, the context directory will subsequently be pushed to the relative sub-folder. + +``` xml + + + + + + + +``` + +``` +$ tree --dirsfirst contexts/ +contexts/ +├── foo +│ ├── cert.pem +│ ├── governance.p7s +│ ├── identity_ca.cert.pem +│ ├── key.pem +│ ├── permissions_ca.cert.pem +│ └── permissions.p7s +├── cert.pem +├── governance.p7s +├── identity_ca.cert.pem +├── key.pem +├── permissions_ca.cert.pem +└── permissions.p7s +``` + +### Relatively pushed qualified context path + +For nodes with qualified context paths pushed by a namespace, the qualified context directory will subsequently be pushed to the relative sub-folder. + +``` xml + + + + + + +``` + +``` +$ tree --dirsfirst contexts/ +contexts/ +└── foo + └── bar + ├── cert.pem + ├── governance.p7s + ├── identity_ca.cert.pem + ├── key.pem + ├── permissions_ca.cert.pem + └── permissions.p7s +``` + +### Fully qualified context path + +For nodes with absolute context paths, namespaces do not subsequently push the relative sub-folder. + +``` xml + + + + + + +``` + +``` +$ tree --dirsfirst contexts/ +contexts/ +└── bar + ├── cert.pem + ├── governance.p7s + ├── identity_ca.cert.pem + ├── key.pem + ├── permissions_ca.cert.pem + └── permissions.p7s +``` + + +## Alternatives + +### Context path orthogonal to namespace + +An alternative to reusing namespaces to hint the context path could be to completely disassociate the two entirely, treating the context path as it's own unique identifier. +However, having to book keep both identifier spaces simulations may introduce to many degrees of freedom that a human could groc or easily introspect via tooling. + +#### `` + +TODO: Describe added `context` attribute to `push_ros_namespace` element. +Keeps pushing contexts close/readable to pushing of namespaces. + +#### `` + +TODO: Describe added `push_ros_context` element. +Keeps pushing context path independent/flexable from namespaces. + + +## Concerns + +### Multiple namespaces per context + +For circumstances where users may compose multiple nodes of dissimilar namespaces into a single context, the user must subsequently specify a common fully qualified context path for each node to compose, as the varying different namespaces would not push to a common context. +For circumstances where the context path is orthogonal to node namespace, the use of fully qualifying all relevant nodes is could be tedious, but could perhaps could still be parametrized via the use of ``, and `` substitution and expansion. + + +### Modeling permissions of nodes in a process v.s. permission of the middleware ``Participant`` + +Before the use of contexts, multiple nodes composed into a single process where each mapped to a separate ``Participant``. +Each ``Participant`` subsequently load a security identity and access control credential prevalent to its' respective node. +However, all nodes in that process share the same memory space and can thus access data from other nodes. +There is a mismatch between the middleware credentials/permissions loaded and the resources accessible within the process. + +By using contexts, all nodes in a context share the same security identity and access control credentials. +This inevitably means that code compiled to node ``foo`` can access credentials/permissions only trusted to node ``bar``. +This consequence of composition could unintendedly subvert the minimal spanning policy as architected by the policy designer or measured/generated via ROS 2 tooling/IDL. + +With the introduction of contexts, it becomes possible to describe the union of access control permission by defining a collection of SROS 2 policy profiles as element within a specific context. +This would allow for formal analysis tooling [2] to check for potential violations in information flow control given the composing of nodes at runtime. +If a process contains a single context, this reconciles the permissions of a ``Participant`` and the ones of the process. + +However, should multiple contexts be used per process, then such security guaranties are again lost because both contexts will share the same memory space. +Thus it should be asked whether if multiple contexts per process should even be supported. + + +In summary, the distinction here is that before, the composition of multiple permissions could not be conveyed to the tooling. +Whether nodes could gain the permission of others in the same process space is not the hinge point of note; it's the fact that such side effects could not be formally modeled or accounted for by the designer. +It will now be possible with contexts, however allowing for multiple contexts per process will reintroduce and exacerbates the same modeling inaccuracies. + +### Composable launchfile includes + +A particular challenge in using launchfiles with security contexts is that of keeping the include hierarchy composable. +An inherit tradeoff between simplicity and configurability can arise when writing launchfiles for downstream use. +Authors can selectively choose what attributes to expose as input arguments, while users may implicitly override provided defaults. + +In case of contexts, it is not inherently clear what best practices either package authors or users should employ to retain a composable and intuitive launchfile structure. E.g: +Should authors parametrize context paths for each node as input arguments? +Should users push namespaces of included launchfiles to separate contexts? +Should the setting of security environment variables be discouraged from within launchfiles, limiting the use of simple static analysis of launchfiles combined with Node IDL for procedural context generation? + +### Composable nodes in container + +Given that containers can be dynamic, where nodes can be added or removed at runtime, there is perhaps some question as to how containers should integrate with secure contexts. +The most straightforward approach is perhaps only specifying the context wherever the container is first defined/launched, applying to the container participant, thus to all nodes/components inside that container. +This should be further deliberated when eventually extending the launch API for containers. + +### Migration for RMW implementations + +As it may take time before all RMW implementations implement the new system of contexts, a defined fallback behavior should still be designated. +For such implementations, the context security directory determined by RCL should be loaded for the participant as per the priority of context setting specified in the "ROS 2 DDS-Security integration" design doc. +This primarily desists the use of including the node name in the default lookup path, consequently getting users in the habit of creating separate contexts for separate processes, or explicitly specifying unique context names via launchfiles. + +## References + +1. [Procedurally Provisioned Access Control for Robotic Systems](https://doi.org/10.1109/IROS.2018.8594462) + +``` bibtex +@inproceedings{White2018, + title = {Procedurally Provisioned Access Control for Robotic Systems}, + author = {White, Ruffin and Caiazza, Gianluca and Christensen, Henrik and Cortesi, Agostino}, + year = 2018, + booktitle = {2018 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)}, + doi = {10.1109/IROS.2018.8594462}, + issn = {2153-0866}, + url = {https://arxiv.org/pdf/1810.08125.pdf}} +``` + + +2. [Network Reconnaissance and Vulnerability Excavation of Secure DDS Systems](https://doi.org/10.1109/EuroSPW.2019.00013) + +``` bibtex +@inproceedings{White2019, + title = {Network Reconnaissance and Vulnerability Excavation of Secure DDS Systems}, + author = {White, Ruffin and Caiazza, Gianluca and Jiang, Chenxu and Ou, Xinyue and Yang, Zhiyue and Cortesi, Agostino and Christensen, Henrik}, + year = 2019, + booktitle = {2019 IEEE European Symposium on Security and Privacy Workshops (EuroS PW)}, + doi = {10.1109/EuroSPW.2019.00013}, + pages = {57-66}, + url = {https://arxiv.org/abs/1908.05310.pdf}} +```