logo

NJP

Bring Your Own Key (BYOK) : Encrypting Integration Payloads with ServiceNow KMF - Part 2

New article articles in ServiceNow Community · Sep 13, 2026 · article

Bring Your Own Key to ServiceNow KMF — Part 2: Importing Your Key

 

This is Part 2 of a three-part series on using your own encryption key inside ServiceNow's Key Management Framework. Part 1 covered the mental model, the role you need, and setting up the instance's RSA unwrapping key. Part 3 covers encrypting from script.

With the instance able to accept imported keys, we can build a module and get your own AES key into it.

 

Build your module

Key Management > Cryptographic Modules > Create New , then add a Specification:

Field Value
Purpose Symmetric Data Encryption/Decryption
Algorithm AES 256 GCM (or CBC)
Origin Import from web service
Key alias must be unique across all modules

 

Then set the module to Published and Default module access policy to Track.

⚠️ Key operations silently do nothing on a Draft module. No error, no message, key version stays -1. Publish first. A duplicate key alias produces the same silent failure — worth checking if key generation appears to do nothing at all.

 

Note that module records cannot be deleted , and non-Enterprise instances cap at five. Name them deliberately the first time.

 

Wrap your key

 

Encrypt your AES key against the certificate from Part 1:

openssl pkeyutl -encrypt -pubin \
  -inkey <(openssl x509 -in kmf_import.crt -pubkey -noout) \
  -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 \
  -in your_aes.key -out aes_wrapped.bin # 512 bytes for RSA-4096

Verify the digest was not silently downgraded — some OpenSSL builds ignore an unsupported -pkeyopt and fall back to SHA-1 OAEP. Decrypt the result back with the .pem and compare hashes before going further. A mismatch here surfaces much later as an unexplained decryption failure.

 

Post it

POST /api/sn_kmf/key/import?cryptoSpecSysID=<spec sys_id>
Content-Type: application/octet-stream
Body: the wrapped bytes (raw, not base64)

 

⚠️ cryptoSpecSysID is mandatory and appears in no documentation. Without it you get "No cryptoSpecSysID specified in request params". The endpoint declares consumes: application/octet-stream, so send raw bytes rather than base64.

 

If your instance uses SSO, basic auth on REST may be disabled — in which case the simplest route is your browser's console on a logged-in session, passing window.g_ck as the X-UserToken header.

 

Activate it

A successful POST creates the key in generated state. It is not in use yet.

⚠️ KMF will not activate a second key of the same type while one is active. Suspend the existing key first, then activate yours. Confirm with:

var k = new GlideRecord('sys_kmf_module_key');
k.addQuery('crypto_module.name', 'CONTAINS', 'your_module');
k.query();
while (k.next()) {
  gs.print(k.getUniqueValue() + ' | ' + k.getValue('key_lifecycle_state') +
           ' | ' + k.getValue('origin'));
}

 

You want exactly one active, with origin import_from_webservice.

This same suspend-then-activate step is how key rotation works later, so it is worth getting comfortable with now.


Part 3: encrypting from script, the output envelope, and a reusable Script Include.

View original source

https://www.servicenow.com/community/servicenow-ai-platform-articles/bring-your-own-key-byok-encrypting-integration-payloads-with/ta-p/3597343