Secret Parameter Actions

When using the “Secret Parameters” in a fixlet, this requires the user to input the text into the text boxes in the fixlet description. Can the fixlet be executed via the BES REST API and the parameters be passed as well, or can the parameter values only be captured in the fixlet description?

Yes, when sending a <SourceFixletAction> or <Action>, you’d add the values in a <SecureParameter> element.

<xs:complexType name="SourcedFixletAction">
    <xs:sequence>
      <xs:element name="SourceFixlet" type="BESActionSourceFixlet" />
      <xs:element name="Target" type="BESActionTarget" minOccurs="0" />      
      <xs:element name="Parameter" type="BESActionParameter" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="SecureParameter" type="BESActionParameter" minOccurs="0" maxOccurs="unbounded" />      
      <xs:element name="Settings" type="ActionSettings" minOccurs="0" />
      <xs:element name="IsUrgent" type="xs:boolean" minOccurs="0" />
      <xs:element name="Title" type="ObjectName" minOccurs="0" />
    </xs:sequence>
      <xs:attribute name="SkipUI" type="xs:boolean"/>
  </xs:complexType>



<xs:complexType name="Action">
    <xs:sequence>
      <xs:element name="Title" type="ObjectName" />
      <xs:element name="Relevance" type="RelevanceString" />
      <xs:element name="ActionScript" type="ActionScript" />
      <xs:element name="SuccessCriteria" type="ActionSuccessCriteria" minOccurs="0" />
      <xs:element name="SuccessCriteriaLocked" type="xs:boolean" minOccurs="0" />
      <xs:element name="Parameter" type="BESActionParameter" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="SecureParameter" type="BESActionParameter" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="MIMEField" type="MIMEFieldType" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
1 Like

thanks. And pushing it via the API is just “as secure” as pushing it from the console? The BES Root doesn’t record those parameter values or the xml that was POSTed correct?

Correct, just ensure you’re using the HTTPS url rather than HTTP for the REST API connection to ensure it’s encrypted on-the-wire as well.

1 Like

as we are. thanks much

1 Like

which values in your xml SourceFixletAction are the parameter name and the parameter value? And if I wanted multiple secure parameters, would that be a new element for each or would they all be within the same single ?

In SourcedFixletAction, it would come after the <Target> and (if any) <Parameter> elements, and would look like

<SecureParameter Name="Username">Administrator</SecureParameter>
<SecureParameter Name="Password">ThisIsNotAGoodPassword</SecureParameter>

edit: fixed incorrect closing tags for </SecureParameter>

1 Like

It doesn’t seem like the parameters are coming through to the actionscript. This is an example from https://developer.bigfix.com/rest-api/api/action.html where I’ve added the SecureParameter elements but where does the code <xs:complexType name="Action"> ... you provided above come into play?

<?xml version="1.0" encoding="UTF-8"?>
<BES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BES.xsd">
 <SourcedFixletAction>
   <SourceFixlet>
     <Sitename>TestSite</Sitename>
     <FixletID>83</FixletID>
     <Action>Action1</Action
   </SourceFixlet>
   <Target>
     <ComputerID>0123456</ComputerID>
   </Target>
   <SecureParameter Name="param1name">param1value</SecureParameter>
   <SecureParameter Name="param2name">param2value</SecureParameter>
 </SourcedFixletAction>
</BES>

That was just a snippet from the best.xsd schema file to show the names and order of elements - SourcedFixletAction and Action are two separate things that both accept SecureParameters, but if you’re using SourcedFixletAction you shouldn’t need to use Action at all, it’s an either/or thing.

I’ll see if I can repro an example a bit later today but I think you should be on the right path already

Maybe this is just a copy/paste thing but you seem to be missing the last > on the closing tag </Action>

The missing “>” on /Action looks to be a bug in the sample code here - https://developer.bigfix.com/rest-api/api/action.html Know who maintains that to fix it?

Ok, well we’ve pushed the sample POST above (with a good “< /Action>” and BES creates the action, but we don’t see the actionscript doing anything with the parameters as expected. When we push the task from the console and populate the parameters in the fixlet description, it works.

sample actionscript:

dos echo "param1name={parameter "param1name"}" >> c:\temp\output.txt
dos echo "param2name={parameter "param2name"}" >> c:\temp\output.txt

Ok, I managed to put together an example, and it’s working as I expected…hopefully some of this may help? It may be as simple as how the parameters are used in the actionscript, but the Description tab HTML & javascript shouldn’t matter from an API post.

The Description tab of the fixlet appears as this:

The important bit (for the Console) is the textbox and the javascript, it creates a parameter named “secret”

<LABEL for=secret>Test Secret:</LABEL> 
<INPUT id=secret type=password name=secret> 
<script>
document.body.ontakeaction = function() {
  var theSecret = document.getElementById( "secret" ).value;
  if (theSecret==null || theSecret=="") {
      alert("Hey, you forgot to enter a secure parameter! Please enter one on the Description tab before taking the action.");
	  }
  else {
    TakeSecureFixletAction( Relevance('id of current fixlet'), Relevance('id of current bes site'), "Action1", {}, { secret: theSecret } );
	}
  return false;
  }
</script> 

None of that script matters when using XML Import or REST API though. It’s just used by the thick console to create the XML that ends up being posted.

For my test, the Action Script is pretty simple, it just generates a file with the parameters:

//insecure parameter
action parameter query "username" with description "Please specify the name of an existing local user account"
//secure parameter:
//  {parameter "secret" of action}

delete __createfile
createfile until EOF_MARKER
username: {parameter "username" of action as string}
secret: {parameter "secret" of action as string}
EOF_MARKER

When I take the action interactively with the thick console, I can see it creates the file I expected:

C:\BES\Client\__BESData\CustomSite_Test_Content>type __createfile
username: ClearTextValue
secret: my test secret

I have a dashboard I use to post generic XML. If I post the XML in this form it works:

<?xml version="1.0" encoding="UTF-8"?>
<BES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BES.xsd">
 <SourcedFixletAction>
   <SourceFixlet>
     <Sitename>Test Content</Sitename>
     <FixletID>14315</FixletID>
     <Action>Action1</Action>
   </SourceFixlet>
   <Target>
   <ComputerID>1080572761</ComputerID>
   </Target>
   <Parameter Name="username">Cleartext Username from XML Import</Parameter>
   <SecureParameter Name="secret">My Test Secret Value from XML Import</SecureParameter>
 </SourcedFixletAction>
</BES>

Reading back the content:

C:\BES\Client\__BESData\CustomSite_Test_Content>type __createfile
username: Cleartext Username from XML Import
secret: My Test Secret Value from XML Import

I built a very short Python script to POST it to api/actions:

import requests

# to suppress SSL "untrusted certificate" warnings
import warnings

operation = "POST"
certverify = False
url = "https://my-root-server:52311/api/actions"
username = "sorry-not-gonna-share-that"
password = "sorry-not-gonna-share-that"

# Suppress InsecureRequestWarning warnings from requests module
#  These are generated when we do not have a trusted CA certificate on the BES Server
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# normally build XML with xml.ElementTree or lxml but...no time for that now...
myXML = """<?xml version="1.0" encoding="UTF-8"?>
<BES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BES.xsd">
 <SourcedFixletAction>
   <SourceFixlet>
     <Sitename>Test Content</Sitename>
     <FixletID>14315</FixletID>
     <Action>Action1</Action>
   </SourceFixlet>
   <Target>
   <ComputerID>1080572761</ComputerID>
   </Target>
   <Parameter Name="username">Cleartext Username from API post</Parameter>
   <SecureParameter Name="secret">My Test Secret Value from API post</SecureParameter>
 </SourcedFixletAction>
</BES>
"""

# Note that on any of these Exception handlers, we could either raise our own error and quit the script, or handle the error
# and move on to the next query or next server or ...
try:
    response = requests.request(
        operation,
        url,
        data=myXML,
        headers=None,
        verify=certverify,
        auth=(username, password),
        params=None,
    )

except Exception as e:
    # This could be an exception such as "server unreachable"
    print("Error encountered connecting to the API: " + str(e))
else:
    if not response.ok:
        # This could be an error such as "We connected to the server and got HTTP response, but the RESPONSE is "Access Denied" or "Page not Found")
        print("HTTP " + str(response.status_code) + " " + response.reason)
    else:
        print("Action sent:")
        print(response.text)

When I POST that, I get back the response I expect from Python…

Action sent:
<?xml version="1.0" encoding="UTF-8"?>
<BESAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BESAPI.xsd">
        <Action Resource="https://my-root-server:52311/api/action/14319" LastModified="Wed, 04 Aug 2021 20:39:47 +0000">
                <Name>Test Secure Parameter Fixlet</Name>
                <ID>14319</ID>
        </Action>
</BESAPI>

And on the endpoint it created the file I expected…

C:\BES\Client\__BESData\CustomSite_Test_Content>type __createfile
username: Cleartext Username from API post
secret: My Test Secret Value from API post

I went back and referenced a second parameter, “newsecret”, but only in the ActionScript - I didn’t add it to the Description form, Javascript, or anything. I was able to reference that parameter the same way, with an additional <SecureParameter> entry and just adding it to the __createfile with the others.

3 Likes

Also, for what it’s worth, the Console view of this action history shows the clear-text parameter “username”, but does not display either of the SecureParameter values

2 Likes

Thanks @cstoneba for pointing out that documentation issue. I have raised it with the team. For future reports, you can submit support tickets at support.bigfix.com

1 Like

thanks @brolly33

@JasonWalker - this is a great writeup. It would be nice to see this posted somewhere on developer.bigfix.com
Not sure what we were doing wrong yesterday but today it works with in the action POST and the actionscript is able to see the secure parameter values.
Also, either SecureParameter in the API action POST or from the fixlet description xml javascript, client mailboxes are still the only propagation method and the parameter isn’t stored anywhere in cleartext correct?

2 Likes

Correct - any method using SecureParameter options are mailboxed and encrypted to each individual target, and the cleartext of the parameter is not stored.

Slightly unrelated but when I push the action via the API POST, on some of our bigfix environments it works and some it doesn’t. When it doesn’t work, an HTTP 400 is returned. It seems like if I cut out some of the target computers (targeted by computer ID) it will then work. Test of 759 target Computer IDs in bigfix env A failed, but removing 300 from the target list returned an http200 and the action was created. But in BigFixEnvB, 2000 were targeted without an issue. There is no logging on the root server that I know of that would explain the 400 error. Would non existing computer IDs cause the error? the XML formatting is proper between failure and success.

case CS0252201 opened.

I suspect that error may come from targeting a computer id that doesn’t exist…I’ll try to repro that on mine.

I thought that was maybe the issue too, but there is no problem pushing an action to a computer ID that doesn’t exist. The action still is created.

latest testing:
test 1) works, http200 response, targetlist = 1 computer ID), secretparameter included
test2) Doesn’t work, http 400 response, targetlist = 753 computer IDs, secretparameter included
test3) works, http 200 response, targetlist = 753 computer IDs, secureparameter excluded.