Using Encrypted credentials for scripted outbound web service calls

evanlw
Kilo Contributor

Hi,

I have an Integration problem that I was hoping the community could help with.

I need to have:

  • an outbound SOAP web service call
  • which uses Basic authentication
  • and is executed via a MID server
  • while either:
    • making sure the credentials are encrypted within ServiceNow (to prevent casual viewing)
    • or ideally not even stored on our ServiceNow instance - but credentials are obtained locally via the MID server

These are scripted web service calls (based currently on a SOAPRequest).

Initially, I thought that the External Credential Store would meet these needs directly:

http://wiki.servicenow.com/index.php?title=External_Credential_Storage

But from what I can tell, this is limited to Discovery Probes and logons to host operating systems.

Another potential solution may be to use Credential tagging ...

http://wiki.servicenow.com/index.php?title=Assigning_Credentials_to_Orchestration_Activities

but, it's also unclear if this would work when attached to a simple SOAP request.

Finally, if none of these options are feasible, my thoughts are that the most straightforward method is to:

  • define a system property - which is 'Password (2 Way Encrypted)' type field, then to decrypt it:
  • and then decrypt it via the SOAP invocation script, with something like this:

var unencryptedPassword = (new GlideEncrypter()).decrypt(item.getValue("basic_auth_password"))

Some obvious issues to consider are:

  • need to make sure that any logging of this does not include the password
  • ensure the appropriate read/write roles are assigned

I do also see that Fuji may be able to offer some help here as well.

http://wiki.servicenow.com/index.php?title=Outbound_SOAP_Web_Service

This gives an example of creating a SOAP record - and assigning the basic auth credentials, and then being able to invoke that via a script:

http://wiki.servicenow.com/index.php?title=Scripting_Outbound_SOAP

Can anyone offer any experiences of solutions in this area?

thanks,

Evan

1 ACCEPTED SOLUTION

Evan,



There are a few ways to tackle this.   One, you could first have a Web Service Call that reaches out to your credential store to get the credential first and then use that credential in your next web service call.



Another option is to write a MID Server Script Include that leverages a Java JAR file   and have a Javascript Probe call into the Java libraries on the MID Server to grab the credential from your internal credential store and then you execute the web service call directly from that MID Server script using the credential you got from the store.  



Here is a video example of leveraging a JAR file:


http://www.john-james-andersen.com/blog/service-now/video-use-custom-jar-files-on-a-mid-server.html



Also an article on MID Server Script Includes and Javascript Probes:


JavascriptProbe and MID Server Script Includes-John Andersen



It is considerably more javascript coding, but that would work and it would be an alternative if you feel that the password encryption in ServiceNow is insufficient for you.


View solution in original post

5 REPLIES 5

john_andersen
Tera Guru

Evan,



The platform actually takes care of this for you neatly without much complicated scripting.



The approach that I typically take is to store both username and password in a system property on the instance. Then, in my code, I use this setBasicAuth()   function to apply those credentials from the properties to the soap request that making.   this all then get posted on the ECC Queue   and executed from the MID server.



var s = new SOAPMessage('MyThirdPartyService', 'WebServiceFunctionOfChoice');


s.setParameter('parameterNameGoesHere', 'paramterValueGoesHere');


var user = gs.getProperty("jja.mypropertyprefix.integrationname.username");


var password = gs.getProperty("jja.mypropertyprefix.integrationname.password");


s.setBasicAuth(user, password);



The credentials are never posted in plain text, and they only exist on the ECC Queue   in encrypted form:



<?xml version="1.0" encoding="UTF-8"?>


<parameters>


  <parameter name="source" value="https://demoi1.service-now.com/incident.do?SOAP"/>


  <parameter name="soap_username" value="admin"/>


  <parameter name="soap_password" value="enc:+0EcPxqDnts="/>


  <parameter name="name" value="&quot;http://www.service-now.com/incident/getKeys""/>


  <output>YOUR_SOAP_BODY_WILL_BE_HERE</output>


  <httpHeaders/>


</parameters>




This way you do not have to go through complicated MID Server specific scripting to dynamically grab credentials from the instance.



John


Hi John,



Thanks for your thoughtful response.



In our case, we are using the SOAPRequest API ... but am I correct in thinking that we should be able to do something very similar?



var s = new SOAPRequest("http://something.com/something.asmx");


...


var user = gs.getProperty("jja.mypropertyprefix.integrationname.username");


var password = gs.getProperty("jja.mypropertyprefix.integrationname.password");


...


s.setBasicAuth(user, password);



Also, there was another point in the post - around using External credentials.



To provide some more background, we have a sensitive system that we're looking at invoking via Web Services from ServiceNow.


As part of a risk review, we looked at whether we could actually NOT store the credentials in ServiceNow at all.



I understand that there may be a very small difference between:



  • having the credentials encrypted and stored on an instance - so that only an Admin could retrieve them
  • having the credentials stored and accessed on our side of the firewall - with say a Credential ID used to retrieve them


Since, in each case, a rogue actor could either:



  • retrieve the credentials
  • initiate the workflow, which would trigger the Web Services in question.


Could you offer any views as to whether this is actually possible?


That is, able to use something like the external Credential Store, but in conjunction with Web Services.



thanks,
Evan


Evan,



There are a few ways to tackle this.   One, you could first have a Web Service Call that reaches out to your credential store to get the credential first and then use that credential in your next web service call.



Another option is to write a MID Server Script Include that leverages a Java JAR file   and have a Javascript Probe call into the Java libraries on the MID Server to grab the credential from your internal credential store and then you execute the web service call directly from that MID Server script using the credential you got from the store.  



Here is a video example of leveraging a JAR file:


http://www.john-james-andersen.com/blog/service-now/video-use-custom-jar-files-on-a-mid-server.html



Also an article on MID Server Script Includes and Javascript Probes:


JavascriptProbe and MID Server Script Includes-John Andersen



It is considerably more javascript coding, but that would work and it would be an alternative if you feel that the password encryption in ServiceNow is insufficient for you.


I've marked this as correct - thanks.



The answer has definitely provided an alternate way of addressing this, and that's what I was after.



thanks again,


Evan