Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial draft for ROS 2 Security Contexts #1

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a299714
Add initial draft for ROS 2 Security Contexts
ruffsl Feb 22, 2020
85f1e96
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
5f4a64b
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
b43e4d3
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
39c5aac
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
f5e07e7
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
77a21f4
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
4c13826
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
ffe489f
Update articles/ros2_security_contexts.md
ruffsl Feb 22, 2020
95f75b6
Use 1 sentence per line
ruffsl Feb 22, 2020
5995840
Revert Symbolic links for now
ruffsl Feb 22, 2020
a461e4c
Extend multiple contexts per process section
ruffsl Feb 22, 2020
97ae7e1
Clerify specification
ruffsl Feb 22, 2020
70b59f7
Cite additional reference
ruffsl Feb 22, 2020
19e6004
fix article name
mikaelarguedas Feb 23, 2020
b3f50fb
add Participant concept
mikaelarguedas Feb 23, 2020
b17032a
use absolute instead of FQN
mikaelarguedas Feb 23, 2020
226bc24
typo
mikaelarguedas Feb 23, 2020
24ef462
attempt to rephrase concerns section
mikaelarguedas Feb 23, 2020
0c04706
Merge pull request #2 from ruffsl/mikael/security-contexts
ruffsl Feb 23, 2020
d50c3d8
Update policy schema for contexts
ruffsl Feb 25, 2020
20ccb00
Update DDS-Security integration for contexts
ruffsl Feb 25, 2020
2ac697c
Add composable concerns
ruffsl Feb 25, 2020
a972685
Add concern for RMW migration
ruffsl Feb 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion articles/ros2_access_control_policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,28 @@ Attributes:
- **version**: declared version of schema version in use
- Allows for advancing future revisions of the schema

### `<contexts>` Tag

Encapsulates a sequence of unique contexts.
This method of nesting sequences allows for additional tags to be extended to the `<policy>` root.

### `<context>` 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 `<profile>` Tag for more info on MAC is applied.

### `<profiles>` Tag

Encapsulates a sequence of unique profiles.
This method of nesting sequences allows for additional tags to be extended to the `<policy>` root.
This method of nesting sequences allows for additional tags to be extended to the `<context>` root.

### `<profile>` Tag

Expand Down
15 changes: 14 additions & 1 deletion articles/ros2_access_control_policies/policy.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,24 @@
<xs:element name="policy" type="Policy" />
<xs:complexType name="Policy">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="profiles" type="Profiles" />
<xs:element name="contexts" type="Contexts" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required" />
</xs:complexType>

<xs:complexType name="Contexts">
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="context" type="Context" />
</xs:sequence>
</xs:complexType>

<xs:complexType name="Context">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="profiles" type="Profiles" />
</xs:sequence>
<xs:attribute name="path" type="xs:string" use="required" />
</xs:complexType>

<xs:complexType name="Profiles">
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="profile" type="Profile" />
Expand Down
57 changes: 29 additions & 28 deletions articles/ros2_dds_security.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -125,62 +125,63 @@ 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:

<root>
└── 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 `<root>/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 `<root>/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 `<root>/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. `<root>/foo/bar/baz_12/`, or `<root>/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 `<root>/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. `<root>/contexts/foo/bar/baz_12/`, or `<root>/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.


#### 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.

Expand All @@ -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.


Expand Down
Loading