ServiceNow Credential Resolver
Overview
This project provides a ServiceNow MID external credential resolver that retrieves secrets from Akeyless and maps them to ServiceNow Discovery credential fields. The resolver class is com.snc.discovery.CredentialResolver.
Source repository: https://github.com/akeylesslabs/akeyless-servicenow-credential-resolver
Prerequisites
- ServiceNow instance (Quebec+ recommended) with Discovery and External Credentials enabled.
- MID Server installed and connected to your instance.
- Network access from the MID Server host to the Akeyless Gateway (default
https://api.akeyless.io, or your private gateway URL). - An Akeyless Access ID and one of the supported authentication methods listed below.
Supported Akeyless Authentication Methods
access_key: Access ID + Access Keyaws_iam: CloudID from AWSazure_ad: CloudID from Azuregcp: CloudID from GCPuniversal_identity(or aliasuid): Access ID + UID tokencert(or aliascertificate): Access ID + client certificate and private key material
For cloud-based methods, the resolver detects CloudID using the cloud environment. Ensure the MID Server is running where a CloudID can be obtained (For example, EC2 with an instance profile, Azure VM with a managed identity, GCP VM with default credentials). For local/dev use, prefer access_key.
Build the JAR
This is a Maven project. Build a versioned JAR so the filename is stable in MID:
mvn -Drevision=1.1.0 clean package
The default build runs Maven Shade so the main JAR includes Jackson JR and CloudID lightweight dependencies (required on the MID). For a thin JAR only, use mvn -Pthin -Drevision=1.1.0 clean package.
Artifacts
- With
-Drevision=1.1.0:target/akeyless-servicenow-credential-resolver-1.1.0.jar - Without a revision property, Maven produces
akeyless-servicenow-credential-resolver-null.jar. - The file in
target/is the shaded artifact.target/original-*.jaris the pre-shade JAR.
Install the Resolver on the MID Server
- Upload the JAR to the MID Server by using the instance UI.
- Navigate: MID Server → JAR files → New
- Set a descriptive Name (For example, akeyless-servicenow-credential-resolver)
- Manage Attachments → upload the built JAR from
target/ - Submit
- Ensure the MID downloads the JAR.
- The MID will sync and place the JAR in its agent lib cache.
- If not picked up, restart the MID service to force a sync.
Configure MID Properties (Akeyless Parameters)
Set the following MID properties on your instance (System Properties or MID Properties). Property names are case-sensitive.
ext.cred.akeyless.gw_url(string): Akeyless Gateway. Default:https://api.akeyless.ioext.cred.akeyless.access_type(string): One ofaccess_key,aws_iam,azure_ad,gcp,universal_identityoruid,certorcertificate. Default:access_keyext.cred.akeyless.access_id(string): Your Akeyless Access ID (required)ext.cred.akeyless.access_key(string): Your Akeyless Access Key (required foraccess_keyonly)ext.cred.akeyless.uid_token(string): Required foruniversal_identityoruidext.cred.akeyless.cert_data(string): Inline certificate PEM content forcertext.cred.akeyless.key_data(string): Inline private key PEM content forcertext.cred.akeyless.cert_file_name(string): Path to the certificate PEM file on the MID host forcertext.cred.akeyless.key_file_name(string): Path to the private key PEM file on the MID host forcertext.cred.akeyless.ignore_cache(booleantrueorfalse): For rotated secrets only, passesignore-cachewhen fetching values. Default:false
Optional field mapping overrides for JSON secrets (see Mapping section below):
ext.cred.akeyless.map.username(default:username)ext.cred.akeyless.map.password(default:password)ext.cred.akeyless.map.private_key(default:private_key)ext.cred.akeyless.map.passphrase(default:passphrase)
Environment and System Property Alternatives
- The resolver also supports the following system properties or environment variables:
AKEYLESS_GW_URLAKEYLESS_ACCESS_TYPEAKEYLESS_ACCESS_ID(required)AKEYLESS_ACCESS_KEY(when usingaccess_key)AKEYLESS_UID_TOKEN(when usinguniversal_identityoruid)AKEYLESS_CERT_DATAandAKEYLESS_KEY_DATA(inline certificate authentication)AKEYLESS_CERT_FILE_NAMEandAKEYLESS_KEY_FILE_NAME(file-based certificate authentication)
- As a fallback for any
ext.cred.*property, an environment variable with the uppercase name and dots replaced by underscores is also read (for example,EXT_CRED_AKEYLESS_GW_URL). - Precedence: MID properties override environment/system variables.
Configure MID config.xml (Secure Local Parameters)
config.xml (Secure Local Parameters)Add sensitive Akeyless credentials in the MID’s config.xml.
Edit the file on each MID host:
- Linux:
/opt/agent/config.xml - Windows:
C:\ServiceNow\agent\config.xml
Insert your parameters inside the <parameters> block:
<parameters>
...
<!-- Akeyless secure credentials -->
<parameter name="ext.cred.akeyless.gw_url" value="https://api.akeyless.io" />
<parameter name="ext.cred.akeyless.access_type" value="access_key" />
<parameter name="ext.cred.akeyless.access_id" value="AKEYLESS_ACCESS_ID" />
<parameter name="ext.cred.akeyless.access_key" value="AKEYLESS_SECRET_KEY" secure="true" />
<!-- Universal Identity example -->
<!-- <parameter name="ext.cred.akeyless.access_type" value="uid" /> -->
<!-- <parameter name="ext.cred.akeyless.uid_token" value="UID_TOKEN" secure="true" /> -->
<!-- Certificate authentication with inline material -->
<!-- <parameter name="ext.cred.akeyless.access_type" value="certificate" /> -->
<!-- <parameter name="ext.cred.akeyless.cert_data" value="-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----" secure="true" /> -->
<!-- <parameter name="ext.cred.akeyless.key_data" value="<PRIVATE_KEY_PEM_CONTENT>" secure="true" /> -->
<!-- Certificate authentication with file-based material -->
<!-- <parameter name="ext.cred.akeyless.cert_file_name" value="/opt/agent/certs/client.crt" /> -->
<!-- <parameter name="ext.cred.akeyless.key_file_name" value="/opt/agent/certs/client.key" secure="true" /> -->
<!-- Optional JSON mapping overrides -->
<parameter name="ext.cred.akeyless.map.username" value="username" />
<parameter name="ext.cred.akeyless.map.password" value="password" />
<parameter name="ext.cred.akeyless.map.private_key" value="private_key" />
<parameter name="ext.cred.akeyless.map.passphrase" value="passphrase" />
</parameters>
Then restart the MID service:
sudo service mid restart
Or on Windows (from an elevated Command Prompt):
net stop mid
net start mid
Configure a Discovery Credential to Use This Resolver
- Navigate to Discovery → Credentials → New.
- Choose a credential Type (For example, Windows, SSH Password, SSH Private Key, VMware, JDBC, JMS, or SNMPv3).
- Select External credential store.
- Set the fully qualified class name (FQCN) to
com.snc.discovery.CredentialResolver. - Set the Credential ID to the Akeyless secret path (For example,
/prod/app/db). - Click Test credential, then select a MID Server and a target if required by the type.
What to Store in Akeyless and How It’s Mapped
The resolver accepts either:
- A plain string secret → mapped as a password/token
- A JSON object → fields are mapped to ServiceNow credential fields as per the credential Type
Item types (Static, Rotated, Dynamic)
- The resolver first calls
describe-itemto determineitem_type. - Based on
item_type, it then calls:STATIC_SECRET→get-secret-valueROTATED_SECRET→get-rotated-secret-value(also sendsignore-cachewhenext.cred.akeyless.ignore_cache=true)DYNAMIC_SECRET→get-dynamic-secret-value
- If ServiceNow provides an
ipargument for the credential test or run, the resolver passes it ashostwhen fetching rotated secrets.
Default mapping (can be overridden by way of ext.cred.akeyless.map.*):
- Username field:
username - Password field:
password - Private key field:
private_key - Passphrase field:
passphrase
Per-Type mapping summary
- Windows, Basic, SSH Password, VMware, JDBC, JMS:
- Uses JSON fields: username, password (or your overridden names)
- SSH Private Key:
- Uses JSON fields: username, private_key, passphrase
- The same mapping also applies to
sn_cfg_ansible,sn_disco_certmgmt_certificate_ca,cfg_chef_credentials,infoblox, andapi_key.
- SNMPv3:
- Uses JSON fields: username, auth_protocol, auth_key, privacy_protocol, privacy_key
- Mapped to ServiceNow fields:
user,authprotocol,authkey,privprotocol,privkey
- Other unlisted types:
- The resolver attempts to map
usernameandpasswordwhen those fields are present in the secret JSON. If one or both fields are missing, only available fields are mapped (for example,ldap).
- The resolver attempts to map
Examples
Basic / Windows / SSH Password (JSON in Akeyless):
{
"username": "alice",
"password": "secret"
}
SSH Private Key:
{
"username": "ssh-user",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"passphrase": "optional"
}
SNMPv3:
{
"username": "snmpu",
"auth_protocol": "SHA",
"auth_key": "authKeyHere",
"privacy_protocol": "AES",
"privacy_key": "privacyKeyHere"
}
Custom field names by way of mapping overrides (example):
- Set
ext.cred.akeyless.map.username = user_name - Set
ext.cred.akeyless.map.password = pwd
Then a JSON like:
{
"user_name": "alice",
"pwd": "secret"
}
will map to ServiceNow user = alice and pswd = secret.
CloudID Notes (Aws_iam / Azure_ad / Gcp)
- When
ext.cred.akeyless.access_type(orAKEYLESS_ACCESS_TYPE) isaws_iam,azure_ad, orgcp, the resolver fetches a CloudID and sends it to Akeyless during authentication. - Ensure the MID Server host is running in the target cloud with the appropriate identity, or that cloud SDK environment is present to retrieve a CloudID.
- Do not set
access_keywhen using CloudID-based methods.
Universal Identity and Certificate Authentication Notes
- When
ext.cred.akeyless.access_typeisuniversal_identityoruid, setext.cred.akeyless.uid_tokenorAKEYLESS_UID_TOKEN. - When
ext.cred.akeyless.access_typeiscertorcertificate, provide both the certificate and private key. - Certificate authentication supports either inline material with
ext.cred.akeyless.cert_dataandext.cred.akeyless.key_data, or file paths withext.cred.akeyless.cert_file_nameandext.cred.akeyless.key_file_name. - The resolver base64-encodes certificate and key material before sending it to Akeyless.
Troubleshooting
- HTTP 400 "Missing required parameter - timestamp" on
/auth:- This usually indicates the wrong auth flow or missing parameters. Verify
access_typeis set correctly. For CloudID flows, do not set anaccess_key. Foraccess_keyflows, ensure bothaccess_idandaccess_keyare set. Foruid, ensureuid_tokenis set. Forcert, provide both certificate and key material, either inline or by file path.
- This usually indicates the wrong auth flow or missing parameters. Verify
- HTTP 404 from
/v2/*endpoints:- The resolver automatically falls back to the non-
/v2endpoints. If both fail, verify the gateway URL and network reachability.
- The resolver automatically falls back to the non-
- “Secret value not found for name …”:
- Confirm the Credential ID (secret path) is correct and the Akeyless identity has permission to read it.
- JSON secret looks correct but everything maps to a single password field:
- This can happen when certificate or key content is stored in JSON with literal line breaks inside quoted strings. Prefer
\ninside the JSON string values.
- This can happen when certificate or key content is stored in JSON with literal line breaks inside quoted strings. Prefer
- JSON secret looks correct but everything maps to
pswdas one blob:- This often means the secret is not strict JSON because PEM or key content was pasted with real line breaks inside quoted values. Prefer
\ninside JSON string values. If PEM markers are still present, the resolver retries parsing with a lenient Jackson mode.
- This often means the secret is not strict JSON because PEM or key content was pasted with real line breaks inside quoted values. Prefer
- Logging:
- Resolver logs go through Commons Logging. Check MID Server logs for entries containing "Akeyless resolver".
Local/dev Testing (Optional)
You can run unit tests locally:
mvn test
To quickly sanity-check end-to-end against Akeyless, set environment variables and create a Discovery credential that points to a known secret path. For cloud-based auth types, run the MID on a host with a valid cloud identity.
Updated 12 days ago
