All - I have tried to provide context in the google doc because resolving a technical issue over email is never optimal. Apologies in advance having to revert to this email thread to explain what is a complex topic and has design trade-offs that some might not be aware of.
That said, my primary concern that I have raised with the proposed approach (call it Approach A) is the complexity of introducing variables for the sole purpose of holding the values from standard parameters associated with a command.
I believe there should be a simpler way to refer to the output(s) of the command without having to introduce the burden of variables that then have to be assigned from those parameters. The primary motive for this belief is to simplify the job of writing playbooks.
Approach A (currently what is proposed):
1) define variable to hold command parameter results
2) define action step + command (that has predefined parameters already)
3) define how command parameters map to variable defined in step 1
4) use variables and their associated value content in subsequent processing
What I'm looking for is something like this:
Approach B (suggested simpler approach)
1) define action step + command (that has predefined parameters already)
2) use command.parameter.value in subsequent processing
So with Approach B you don't have to define variables where you don't need them just for the sole purpose of using the command's parameters (like stdout, stderr...etc)
Approach B: In Pseudo playbook language:
----------------------------
Action-step-1234
{
Cmds[1] = some-command-that-generates-stdout
}
If action-step-1234.cmds[1].stdout == "ok" then
....do something
------------
Approach A this pseudo code would be
--------------
Define VarA
Action-Step-1234
{
Mapping_table = { stdout maps to VarA }
Cmds[1] = some-command-that-generates-stdout
}
If VarA == "ok" then
....do something
-----------
In my opinion Approach A is more complicated to define as a playbook designer/writer because you have to think to create the variables that will hold returned parameters for commands whereas Approach B is simpler for playbook writers allowing them to just use the returned parameters of the commands without having to define variables to hold those values.
Approach B does make implementation of orchestrators more complicated (unclear how much) but I'm suggesting we should choose the path that makes it easier for playbook writers/designers over orchestration platform builders.
If you got this far in the email then thank you for reading through it.
Allan
Original Message:
Sent: 2/27/2025 2:52:00 PM
From: Luca Morgese Zangrandi
Subject: RE: Urgent Feedback
Hi All,
Thank you Bret for going thoroughly over these elements. My opinions on the two points.
Return schema. Conceptually I totally agree with the proposed solution of the dictionary. It satisfies the need to provide schemas of what kind of elements a command returns, and allows playbook developers to specify what variables should receive the elements that a command returns. If it helps understand the concept, in the bash example, you can think of the keys of the dictionary as "the stdout out arg is: <your variable here>" and "the stderr out arg is: <your variable here>".
Now, the returned_data dictionary implements exactly the improvements that we were supporting. Though, I am still wondering whether introducing this new dictionary object is better than simply specifying the returned keys as properties (e.g. return_stdout, return_stderr). In this, it could also be possible to add an extra property such as "return_unbound" to still give freedom to deviate from the return schema if needed. In my opinion, using properties instead of a dictionary is more in line with the rest of the CACAO spec, and gives a little bit of a more robust and explicitly defined mechanism for capturing return variables. But I am not necessarily strongly advocating for return properties over return dictionaries, just bringing my thoughts.
B64 return data property. In line with the comments in the working draft, my opinion is that this property might not be needed. Playbook developers could either use a custom return dictionary keys (or property) if they really need to, and otherwise they would know what type of data can be returned by a specific command in a specific environment. Perhaps it might make sense to instead add a boolean property like "output_is_b64", to just indicate whether plain text or b64 is in use/expected - and to make it known when sharing a playbook (or using a shared playbook). As a side note, this approach could also work for 'command' (and equivalent for 'content') - i.e. instead of having both 'command' and 'command_b64', we could just have 'command', and 'command_is_b64'. I think this would be easier and more intuitive to use (on the contrary if both 'command' and 'command_b64' are defined, which one should a CACAO executor pick? It would be an arbitrary choice with different consequences, which I don't think it's what we want to have).
These my thoughts on the two matters. On both I will discuss further with my team and get back on the topic in the next TC meeting.
Kind regards,
Luca
------------------------------
Luca Morgese Zangrandi
Cybersecurity Scientist
TNO
------------------------------