Closed romanojd closed 8 years ago
Problem could be addressed as part of the language, as part of the application layer, or in the transport layer.
Two main relationships I see being an issue: grouping and linking.
Grouping would be bundling several actions so they can be processed atomically. Example: bundle(RESTORE(firewall), ALLOW(CIDR), DENY(IP)). Grouping may be important to avoid race conditions. In the bundle example above, the network will not use default firewall rules in the time between RESTORE and DENY -- so no traffic leaks through. (Edit: Also, the orchestrator can wait for the bundle as a whole to complete before issuing a SAVE(firewall) to record the new default ruleset.)
Linking is more like the action-response relationship. It simply allows one message to reference another message, either forward in time or backward.
Option 1: Implement grouping/linking in the transport. Whatever medium transports the messages assigns a unique identifier to each message. Identifiers are stripped from responses before they are returned by the medium to the requestor. I don't like this option because it assumes each participant gets a stream or channel of synchronous message actions/responses. In other words, it assumes a streaming abstraction. This is the "method abstraction" approach used by protocols like RMI and CORBA.
Option 2: Integrate it into the language. Create a message id modifier for each action that may expect a response, and provide a message id in each response. Add a BUNDLE or GROUP directive to OpenC2 if needed, and possibly allow a single atomic RESPONSE for the entire bundle.
Option 3: address it in the application layer. You can see an example of this in the SDN profile at the moment. Actions have an optional report-to modifier that contains a URL. Orchestrators have the ability to specify different URLs or parameters inside the URL, allowing it to differentiate action responses without explicitly specifying an OpenC2 language construct. This is the "cookie" approach. The major downside of this approach is that the URL might assume knowledge of the message transport.
It seems like Option 2 above, integrating it into the language, would be the most flexible. Each relationship would need some "relationship-type" associated with it, which could have global meaning. The relationship-type could be extended for local environments as well.
As for "grouping", you're right. That's definitely a different kind of relationship. We've been treating this one as an external dependency for a while. It might simplify things a lot if it was embedded directly into the language. Maybe not all devices on the network would be able to support it, but some form of "collection", "group", or "container" would definitely scratch everyone's itch.
Agree Option 2 is a good option, but it does place more burden on OpenC2 as a language. Who guarantees uniqueness among message identifiers?
Not offering any answers here, rather just trying to identify the bounds of the problem.
Also worth noting that Option 3 has the exact same problem, but leaves it out of the language and entirely for the sender or transport to solve. As an example of Option 3, the SDN report-to modifier is simply a URL. The sender is responsible for specifying the medium (e.g. "https://", "mira://", or "taxii://"), sender identity (e.g. hostname, port, and path), and message identifier (e.g. path suffix and/or query string). This works out because if nothing else, the sender knows they are uniquely addressable on at least one medium.
Would be ideal if we can find a solution that avoids requiring the action sender to specify the medium, but also doesn't create a complicated addressing/uniqueness scheme.
Optional support for grouping is viable. Actuators with grouping support can bundle their responses in a group when responding. Actuators without group support would still ingest bundles of messages, but would not support atomic scheduling and would send individual responses.
It might be possible to allow Actuators with grouping support to report success/failure of the bundle as a whole as well -- failure of any action within the bundle causes the entire bundle to fail. Alternately we could allow partial failure or even and-like behavior where any failure cancels all subsequent actions in the bundle. I don't think any of these behaviors should be standard or required, though.
Really I think the simplest approach is best-effort, where actuators behave as atomically as they can and report responses describing the outcome if they can't.
I am late to this issue, apologies in advance if these matters were discussed/ resolved offline: A strong case can be made for the datagram or 'best-effort' approach. Consider, if there is a bundle of actions, and there is a different behaviour based on the order of the commands, then this will impact the abilty of thecommands to be executed asynchronously. Granted, this would not be an issue for a single firewall or small number of actuators, but consider if we were trying to patch a large number of hosts and were using a bundle of commands. Would each command in the bundle need ot be completed prior to commencing the next? If that is the case, then will the command for all of the hosts be delayed while waiting for one or more hosts to complete earlier actions in the bundle? We will also need to document that commands cannot be split in transit.
I have a comment regarding linking approach: How do we handle the case where a command is 'linked' when it was issued, but is appended as it moves through the domain? Does this become a new command, or is the original link in place?
@jmbrule I think it depends on the intended purpose when linking or appending messages. If we're talking about adding modifiers to an action before passing it down to an actuator, then I don't think any linking is necessary.
Example:
In this example, all documents with the same XID number are "linked". The DENY was "extended" by the Tier 3 orchestrator, but each version was really tracked as a separate message. Tier 3 managed the "link" between outer (inter-enclave) and inner (intra-enclave) actions. No extra link ID had to go over the wire because the Tier 3 orchestrator remembered the association internally.
Does this match the case you've described?
For now, we've added a universal modifier called "context" that provides a means to relate an action to an undefined context. For example, the context could be an associated cyber-incident. The universal modifier will be a freeform string to allow for maximum flexibility when referencing a context. Possible context references could be a unique identifier or a URL.
If the need is shown in the future, possibly through reference implementations, that a more robust grouping and linking mechanism is needed, we may revisit this topic at that point. For now, I am closing this issue.
PROBLEM
The ability to define relationships between actions is missing from the language description document. Similar functionality exists only in the RESPONSE action, which relates back to the specific command that requested a response, but this functionality doesn't exist for any other actions.
POTENTIAL SOLUTION
Expand the RESPONSE action command reference for all actions. It could become a universal modifier. Having a universal action relationship could also facilitate workflow definitions through conditional logic mechanisms.
(This was first proposed by Jyoti Verma (@jvoverma) at the 2016-03-31 workshop.)