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.
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 GCP
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.0.0 clean packageArtifacts
- With
-Drevision=1.0.0: target/akeyless-servicenow-credential-resolver-1.0.0.jar - Without a revision property, Maven will produce
akeyless-servicenow-credential-resolver-null.jar.
Install the Resolver on the MID Server
- Upload the JAR to the MID Server via 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. 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)
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/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)
- 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" />
<!-- 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 restartOr on Windows (from an elevated Command Prompt):
net stop mid
net start midConfigure a Discovery Credential to Use This Resolver
- Create a new credential
- Navigate: Discovery → Credentials → New
- Choose a credential Type (For example, Windows, SSH Password, SSH Private Key, VMware, JDBC, JMS, SNMPv3)
- Select “External credential store”
- Fully Qualified Class Name (FQCN): com.snc.discovery.CredentialResolver
- Credential ID: The Akeyless secret path (For example, /prod/app/db) to fetch
- Save and test
- Click “Test credential”, 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
Default mapping (can be overridden via 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
- SNMPv3:
- Uses JSON fields: username, auth_protocol, auth_key, privacy_protocol, privacy_key
- Mapped to ServiceNow fields: username, auth-protocol, auth-key, privacy-protocol, privacy-key
- Any other type:
- Best-effort: username and password if present
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 via 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 username = alice, password = secret.
CloudID Notes (Aws_iam / Azure_ad / Gcp)
- When ext.cred.akeyless.access_type (or AKEYLESS_ACCESS_TYPE) is aws_iam, azure_ad, or gcp, the resolver fetches a CloudID and sends it to Akeyless during auth.
- 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_key when using CloudID-based methods.
Troubleshooting
- HTTP 400 “Missing required parameter - timestamp” on /auth:
- Usually indicates the wrong auth flow or missing parameters. Verify access_type is set correctly. For CloudID flows, do not set an access_key. For access_key flows, ensure both access_id and access_key are set.
- HTTP 404 from /v2/* endpoints:
- The resolver automatically falls back to the non-/v2 endpoints. If both fail, verify the gateway URL and network reachability.
- “Secret value not found for name …”:
- Confirm the Credential ID (secret path) is correct and the Akeyless identity has permission to read it.
- Logging:
- Resolver logs go through Commons Logging. Check the MID Server logs for entries containing “Akeyless resolver”.
Local/dev Testing (Optional)
You can run unit tests locally:
mvn testTo 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 about 2 hours ago
