-
Notifications
You must be signed in to change notification settings - Fork 194
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
Expand ROS Specific Namespace Prefix for Actions #203
Conversation
To better secure and segment access control of the different ROS subsystems, specifically to avoid the mapping of ROS2 actions to DDS topics from colliding with those of ROS2 topics and services, actions are to be allocated their own prefix to facilitate simpler policy profile permissions. Additionally, this and helps to prevent crossover of information flow in the case of more general permission prefix expressions. Contex: #193 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, would the _action token still then need to be embedded in DDS topic mapped by action namespace? We already have hardcoded postfix tokens in the DDS topics mapped by ROS2 services; e.g Request, Reply. I'd rather we drop _action in the rmw, rather than having to interlace this _action token string into the rest of the mappings, and then have to moderate that translation in the access control permission provisioning :<
If that makes it easier, I recommend adding a paragraph here saying the /_action/
token will be dropped in favor of a topic or service prefix.
@ruffsl Your comment link doesn't work for me, just loads the page and doesn't go to the comment. Perhaps it's worth summarizing the issue here, for example what's wrong with This change (or actually enforcing the At the time, I thought |
I checked the link on my browser, and it scrolled down to the comment; it's a bit slow to load as the PR thread is so long. The review comment thread started with @gbiggs comment on
The gist is that if we want to provide user the ability to create access control permissions that are beholden to ROS2 actions, then the manner in which ROS2 actions are mapped at the middleware layer greatly influences the fedelty as which permission expression are matched with the ROS2 subsystems governed. For example, the sharing of the Take this highlevel comarmor profile defining the minimal permissions for ROS 2 action client server pair: <?xml version="1.0" encoding="UTF-8"?>
<profiles xmlns:xi="http://www.w3.org/2001/XInclude">
<profile name="My Talker Profile">
<attachments>
<attachment>/spam/fibonacci_client</attachment>
</attachments>
<ros_action qualifier="ALLOW">
<attachments>
<attachment>/foo/bar/fibonacci</attachment>
</attachments>
<permissions>
<ros_call/>
</permissions>
</ros_action>
</profile>
<profile name="My Listener Profile">
<attachments>
<attachment>/foo/bar/fibonacci_server</attachment>
</attachments>
<ros_action qualifier="ALLOW">
<attachments>
<attachment>/foo/bar/fibonacci</attachment>
</attachments>
<permissions>
<ros_execute/>
</permissions>
</ros_action>
</profile>
</profiles> This intermediate representation would then be compiled down one-one to the middleware permissions: <?xml version="1.0" encoding="utf-8"?>
<dds>
<permissions>
<grant name="fibonacci_client">
<subject_name>CN=/spam/fibonacci_client</subject_name>
<validity>
<not_before>2013-10-26T00:00:00</not_before>
<not_after>2023-10-26T22:45:30</not_after>
</validity>
<allow_rule>
<domains>
<id>0</id>
</domains>
<subscribe>
<topics>
<!-- subscribe to action topics -->
<topic>rt/foo/bar/fibonacci/_action/feedback</topic>
<topic>rt/foo/bar/fibonacci/_action/status</topic>
<!-- subscribe to action replys -->
<topic>rr/foo/bar/fibonacci/_action/cancelReply</topic>
<topic>rr/foo/bar/fibonacci/_action/get_resultReply</topic>
<topic>rr/foo/bar/fibonacci/_action/send_goalReply</topic>
</topics>
</subscribe>
<publish>
<topics>
<!-- publish to action requests -->
<topic>rq/foo/bar/fibonacci/_action/cancelRequest</topic>
<topic>rq/foo/bar/fibonacci/_action/get_resultRequest</topic>
<topic>rq/foo/bar/fibonacci/_action/send_goalRequest</topic>
</topics>
</publish>
</allow_rule>
<default>DENY</default>
</grant>
<grant name="fibonacci_server">
<subject_name>CN=/foo/bar/fibonacci_server</subject_name>
<validity>
<not_before>2013-10-26T00:00:00</not_before>
<not_after>2023-10-26T22:45:30</not_after>
</validity>
<allow_rule>
<domains>
<id>0</id>
</domains>
<publish>
<topics>
<!-- publish to action topics -->
<topic>rt/foo/bar/fibonacci/_action/feedback</topic>
<topic>rt/foo/bar/fibonacci/_action/status</topic>
<!-- publish to action replys -->
<topic>rr/foo/bar/fibonacci/_action/cancelReply</topic>
<topic>rr/foo/bar/fibonacci/_action/get_resultReply</topic>
<topic>rr/foo/bar/fibonacci/_action/send_goalReply</topic>
</topics>
</publish>
<subscribe>
<topics>
<!-- subscribe to action requests -->
<topic>rq/foo/bar/fibonacci/_action/cancelRequest</topic>
<topic>rq/foo/bar/fibonacci/_action/get_resultRequest</topic>
<topic>rq/foo/bar/fibonacci/_action/send_goalRequest</topic>
</topics>
</subscribe>
</allow_rule>
<default>DENY</default>
</grant>
</permissions>
</dds> However should the user wish to use permission expression to wildcard all action under the allocated <?xml version="1.0" encoding="utf-8"?>
<dds>
<permissions>
<grant name="fibonacci_client">
<subject_name>CN=/spam/fibonacci_client</subject_name>
<validity>
<not_before>2013-10-26T00:00:00</not_before>
<not_after>2023-10-26T22:45:30</not_after>
</validity>
<allow_rule>
<domains>
<id>0</id>
</domains>
<subscribe>
<topics>
<!-- subscribe to action topics -->
<!-- subscribe to action replys -->
<topic>rt/foo/bar/*</topic>
</topics>
</subscribe>
<publish>
<topics>
<!-- publish to action requests -->
<topic>rq/foo/bar/*</topic>
</topics>
</publish>
</allow_rule>
<default>DENY</default>
</grant>
<grant name="fibonacci_server">
<subject_name>CN=/foo/bar/fibonacci_server</subject_name>
<validity>
<not_before>2013-10-26T00:00:00</not_before>
<not_after>2023-10-26T22:45:30</not_after>
</validity>
<allow_rule>
<domains>
<id>0</id>
</domains>
<publish>
<topics>
<!-- publish to action topics -->
<!-- publish to action replys -->
<topic>rt/foo/bar/*</topic>
</topics>
</publish>
<subscribe>
<topics>
<!-- subscribe to action requests -->
<topic>rq/foo/bar/*</topic>
</topics>
</subscribe>
</allow_rule>
<default>DENY</default>
</grant>
</permissions>
</dds> Granted the inclusion or omission for the
I think that would be better than having to rely on a hard coded
Specifically, I'd like to ensure we are sufficiently partitioning the fundamental objects to be protected, so I would argue it is entirely justified to treat topics and services that are part of an action differently from a normal topic/service. In fact, I'd like to do the same for the services that are used by parameters (I could make another PR to address this as well). To reference JH Saltzer et al, "The Protection of Information in Computer Systems", 1975:
I think keeping the action namespace unmared from tokens and colliding subsystems would help simplify policy equivalency between higher level intermediate representations of ROS2 permission; especially in regards to the access control model checker I'm working to help attest or refute validity proofs wrt the information flow control of ROS 2 computation graphs. |
I understand your interest in using the I assume you cannot change On balance, allowing for a custom prefix in Ultimately, it should be possible in the future to add a new concept like actions or parameters which builds on the primitives of |
One could introduce more advance interlacing expressions, but then this would not only obscure the permission mapping across the set of all valid topic strings from the administrator (human readability), and also cripple the use of many formal verification techniques (model based checking) when auditing policy for correctness. In general, termination proofs for arbitrary expression expansion is difficult, so the more more complex you make the expression in the permission structures, the harder it may be to solve the underlying propositional satisfiability problem. I think ensuring ROS2 connectivity behaviour remains readily auditable using computer security methods is important in ensuring the maturity and soundness of the systems that will be built upon our abstractions. I'd argue it's worthwhile we do this at the design level to cater to formal static analysis of security mechanisms used in ROS2, as many other engineering domains have: e.g. Verified iptables Firewall Analysis and Verification.
Forgive my ignorance; how are topics and services distinguished presently if they aren't providing custom prefix in rmw_create_publisher() et al? Wouldn't it be reasonable to expect actions to mimic the same pattern? I would think if actions and parameters are truly meant to be a first class primitive in ROS2, then they should be given the same degree of independent access control from the other subsystems.
That does sound awesome, and I agree! My only caution would be that it be made to include an orthogonal handle for the Policy Decision Point, something to strongly label the type (topic/service/action/parameter/etc) and origin (FQN/URI/robot/swarm/etc) of the data channel, and sufficiently partition the fundamental objects to be protected. Thus my stated affinity for annotating the interfaces using something like DDS data tags, as I mentioned in my prior comments linked here:#193 (comment) . Perhaps one aspect of the problem now is that we are overloading origin of the data channel to also include aspects about its type. |
I'm not talking about anything categorically different from what is currently supported, i.e. I think your concerns about complexity and readability are valid, but I don't think the suggestion of support more than "suffix only globing" is unreasonable or too complicated. Also, all of this only matters if you want to "allow all topics and services that are part of an action within a namespace". That is a super complicated expression, and if readability and auditability are your main concerns then I'd argue that the specifications should not support globing at all and instead should require the user to specify exactly which actions they want to allow. In that case, there is no benefit for
Topics are always assigned
Perhaps, but the reality is that they do not, and that is because actions and parameters only exist as concepts in
I believe it's incorrect to equate "is a concept in rmw" with "is a first class citizen in ROS". One simply does not imply the other.
This is the crux of the issue for me, your argument, as I understand it, is that putting all topics and services related to an action in It appears to me that the only argument against only using However, that reason by itself is not enough to convince me personally that we need to change how we discriminate actions from normal topics and services and in the process complicate the rmw API or even worse introduce additional primitives to the rmw API. I'm sorry to disagree with you, but I'm not convinced the argument so far. But going along with what I said before, if it is technically impossible to improve the wildcard matching and dropping wildcard matching is unreasonable, then I would be ok with changing rmw so that you can specify the prefix to be used when creating a publisher/subscription or service client/server. But as I also said above, its more complicated that it sounds, because you need to handle things like:
And that's just what I can think of off the top of my head, so from my perspective it's everything but simple. |
And just to clarify here, I am not opposed to giving actions "the same degree of independent access control from the other substems" -- I just take issue with the technical proposal for how to accomplish it. I still think either making the globing slightly more powerful or having rcl pass extra information into rmw are valid solutions, though I would personally prefer to see the former because it requires no changes to |
The control flow for both may be simple to forward evaluate, but they are not equivalent in complexity wrt to reverse inference. Doing the same for fuzzy string searching is much more involved and no longer tractable at the scale of ROS graphs found on a turtlebot, say 💯 topics; then think of the rqt graph I showed you on the one HSR at TRI that froze SVG viewer, like 💯e2 topics.
I think that's confounding the static logic of the Policy Enforcement Point (PEP) that is being used to intercept a subjects access request to a resource, and the configurable Policy Decision Point (PDP) which evaluates access requests against authorization policies before issuing access decisions. If the subsystems are independently addressable by the PEP, then there is no need for a 'super complicated expression' to be given to the PDP. In the default Secure DDS plugin, the PEP is achieved by simply iterating over the structured DOM of the permissions.xml file with a static finite state machine, i.e. like an traditional ordered rule based filter. The PDP is basically a function call to the POSIX fnmatch(pattern, string). If the subsystems are not independently addressable then, yes you'd have to write a cryptic pattern to arbitrate the difference between namespaces of services vs actions as an ugly pattern.
Pattern expressions could be safely used as long as integrity of the input is well forme, and may even be required as fixed string matching may not always suffice in balancing flexibility with security.
But when would it be appropriate to access control one subsystems but not the other? Having to tiptoe with one subsystem to guarantee security of the other seem seem like a gamble. We could reuse topic and serves functions to define heyer level interfaces, but let's not forgo separation of privilege.
How would one provision a transparency data logger to record all normal topics but no actions that may be session confidential, or permit a action server to host only it own action namespace yet be denied from using any normal topic? This would be mutually exclusive under a unioned
Nay, it impedes static analysis of permissions using expressions which is important for general security. The making it harder to write correct and sound expressions mainly ebbs usability.
I'll concede on the
Thanks for being patient with me @wjwwood , I appreciate gaining a better grasp on the severity of changes that such an extension as this would inevitably require throughout the codebase. |
I'm not sure where the discussion ended.
@ruffsl Is sounds like you might not be interested in adding a topic prefix to the rmw api anymore. Does this mean this PR can be closed, or will it be updated at some point with an alternative? |
I'd still prefer to have a means to differentiate between ROS2 subsystems types for security policy guarantees, but atm there doesn't seem to be a reliable manner for doing that with the present namespacing. As I currently lack the in-depth rmw knowledge to recommend an attractive alternative (as well as the time to dive deeper alone, as a full-time student) I'm not sure I'd have more to offer given my expertise remains under the rmw layer and with the DDS security plugin system. However, I'd accept any mentorship from anyone who is more familiar with the present rmw architecture and API roadmap. |
@ruffsl It sounds like the next step is brainstorming for a different approach. I'll close this for now. |
To better secure and segment access control of the different ROS subsystems, specifically to avoid the mapping of ROS2 actions to DDS topics from colliding with those of ROS2 topics and services, actions are to be allocated their own prefix to facilitate simpler policy profile permissions. Additionally, this and helps to prevent crossover of information flow in the case of more general permission prefix expressions.
Contex: #193 (comment)