Accessing API Key Stored in External Vault (CyberArk/CCP) from Script Include
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
I have a requirement where an API key is stored in an external CCP vault (for example, CyberArk), and ServiceNow has a corresponding credential record in the discovery_credential table.
The actual API key is not stored in ServiceNow. Instead, the credential record contains the credential reference/ID, and during execution the MID Server resolves the secret from the vault and injects it into the REST request (Authorization header).
This setup works successfully in Flow Designer, where the credential is resolved automatically.
However, I now need to call the same API from a Script Include as part of a custom integration and I'm not sure what the recommended approach is.
If the credential were stored directly in ServiceNow, I could use credential provider APIs such as sn_cc.StandardCredentialsProvider. But since the secret resides in the external vault and only the credential reference exists in ServiceNow, I'm unsure how to retrieve or use it in script.
My questions are:
- How can I use a vault-backed credential from a Script Include?
- Is there a supported API to resolve the secret at runtime from the credential record?
- Should I be using a Connection & Credential Alias instead of directly accessing the credential?
- Does anyone have an example of making a REST call from script using a credential whose secret is stored in CyberArk/CCP?
Any guidance or best practices would be greatly appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago - last edited 2 weeks ago
Hello @bandarunave ,
Unfortunately you won't be able to pull the CyberArk secret back onto the instance. That's intentional. With External Credential Storage, the record in discovery_credentials is really just a pointer (the Credential ID). The actual secret only gets resolved on the MID Server, against CCP, at the moment the call goes out. That's why StandardCredentialsProvider comes back empty in your Script Include. It's looking in the instance credential store, and there's nothing there for these records.
Your flow works because the REST step goes through a Connection & Credential Alias on the MID that's set up for CyberArk. The easiest fix is to reuse that from your Script Include and call the action directly, instead of trying to rebuild the call yourself:
try {
var outputs = sn_fd.FlowAPI.getRunner()
.action('x_your_scope.your_rest_action') // the action that already works in your flow
.inForeground()
.withInputs({ /* your action inputs */ })
.run()
.getOutputs();
var status = outputs['status_code'];
var body = outputs['response_body'];
} catch (e) {
gs.error('CyberArk-backed call failed: ' + e.getMessage());
}
This way the alias, MID selection and vault lookup all behave exactly as they do in your flow, and you don't have to handle any of them in code.
A few things worth knowing:
- I'd avoid trying to get the API key into a variable and setting it with setAuthorization or setRequestHeader. There's no supported way to return a vault secret to the instance, and it would defeat the point of using CCP anyway.
- RESTMessageV2 with setMIDServer() looks like it should work, but in my experience it doesn't always go through the same external credential resolution that IntegrationHub uses, especially for API key headers. Calling the action has been the more reliable route.
- Use inForeground() if you need the response back in the same transaction. A background run won't return outputs to you. Also make sure cross-scope access lets your Script Include call the action.
- Keep the alias as the reference point instead of hard-coding a discovery_credentials sys_id. That way you can change the vault object or MID later without touching the code.
- If the action works in the flow but fails from script, first check which MID it's actually running on. It needs to be the one configured for CCP (App ID, client cert, endpoint). Then confirm the Credential ID on the credential record matches the object path your resolver expects.
If this response helped, please mark it as correct and close the thread ✅ — it helps future readers find the solution faster.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago
Hi @Shahjay
Thanks for your reply , But I'm not supposed to use flow designer as it costs the transaction of the flow designer
Strictly we need to use only script include .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a week ago
Hi @bandarunave,
If Flow Designer is not an option, I would first validate whether the integration can be implemented using a configured Outbound REST Message executed from a Script Include via sn_ws.RESTMessageV2.
ServiceNow documents CyberArk External Credential Storage as supporting REST-based integrations, with credential resolution occurring on the MID Server rather than on the instance. The instance should not retrieve or expose the underlying secret.
CyberArk credential storage integration • Brazil Platform security • Docs | ServiceNow
I have not found documentation confirming whether your specific API-key credential type can be resolved when invoked from RESTMessageV2, so I'd test that supported path before building a custom solution.
If there is no supported way to execute the call through RESTMessageV2 while leveraging the CyberArk-resolved credential, then a custom MID Server approach (ECC Queue / JavascriptProbe / custom MID code) could be considered, with the understanding that it introduces additional maintenance and support considerations.
If this response helped, please mark it as correct and close the thread ✅ — it helps future readers find the solution faster.
Thanks
