Implementation Guide for Customer Endpoint for Database Encryption Customer Controlled Switch (DBE CCS)Summary Since the customer retains the customer supplied Key Encryption Key (KEK) when CCS is chosen, the customer needs to periodically provide that secret key to their ServiceNow database instance, so the encrypted data can be accessed. The customer provides the secret to ServiceNow via its CCS Customer Endpoint. The CCS Customer Endpoint is an HTTPS service that responds to a simple GET request for a customer's proprietary key, with a "wrapped" version of said key. This Endpoint will be polled regularly by ServiceNow, typically every 15 minutes. Partner-provided Customer Endpoint Typically a customer will work with a ServiceNow Technology Partner, Fortanix or Llave.io. These partners have implemented the Customer Endpoint on customer's behalf, so the CCS customer need not undertake the endpoint implementation on their own. The Fortanix integration document is here: Using Fortanix Data Security Manager with ServiceNow and you can reach Llave.io at https://www.llave.io/. Self Implemented Customer Endpoint Legacy CCS customers have internally implemented their Customer Endpoint based on the specification contained herein. In addition to this specification, ServiceNow can provide our reference implementation of Customer Endpoint (written in Java and Spring Boot); the customer can use the reference implementation as a basis for developing their own proprietary application customized for their needs. One can request it at email: dev-customer-controlled-switch. The reference implementation is not enterprise ready; the customer would typically use it as a starting point for their proprietary development. Customer Endpoint Specification Request: HTTPS Get, version TLS 1.2 Endpoint: https://<host>/kek/<instance>/<key_id> Instance must be identical to the first component of the ServiceNow instance host. For example, if the instance host is 'ccsdemo.service-now.com' then the instance is 'ccsdemo'. Key id is an integer representing the chain of customer secret key rotations. In other words, 1 is the key id of the first secret key, 2 the second etc. At this time key rotation is not supported. Thus key id should always be 1. HTTP Header: Name: X-DB-Certificate, Value: The ServiceNow customer database instance X-509 public certificate, encoded as bytes based on ASN.1 DER scheme, and then encoding those bytes as a string using base64 encoding. Request Example: https://ccs-rest.democorp.com/kek/ccsdemo/1 Header: X-DB-Certificate: MIIFITCCAwmgAwIBAgIEBuQamjANBgkqhkiG9w0BAQsFADCBvzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTYW4gRGllZ28xGTAXBgNVBAoTEFNlcnZpY2VOb3csIEluYy4xHTAbBgNVBAsTFFNlY3VyaXR5IEVuZ2luZWVyaW5nMS8wLQYDVQQDEyZTZXJ2aWNlTm93IERhdGFiYXNlIEVuY3J5cHRpb24gUm9vdCBDQTEkMCIGCSqGSIb3DQEJARYVc2VjZW5nQHNlcnZpY2Vub3cuY29tMB4XDTIxMTIwODIyNDQyMFoXDTI0MTIwODIyNDQyMFowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQHDAtTYW50YSBDbGFyYTEZMBcGA1UECgwQU2VydmljZU5vdywgSW5jLjEdMBsGA1UECwwUU2VjdXJpdHkgRW5naW5lZXJpbmcxFDASBgNVBAMMC3RzZV9jY3NkZW1vMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwzPKBQZB+YDTSxuwBzokaKuFIxGBXo6mcUigRdxT6TZ4T8FYetpsTGUTpVaqXU7MAROTACs5k5ktd7EFrVutI3oliTL7An5tRgR5agfbvV6x8NWzNUNqVcsFn+omgIdCGCiDbm2aM0MrzL/HKSm5Fh7EDguFdwiv7mu6DbxrA6lSQFAifk7shzcxLwnnaCERXwXB3LDaEAuA4kybJvYNPmCwGroXJxA+k5Jd9g2n9GRP1+LTW1XdNC7CiWFCjIhIrm66Rh+87+/dndnJsxIv/BSfL1kWD0rNiClJZgwhhRBAWTkeaQNZ3Un3M0hLk6O4xhL5+faNcc1yfJpPpDQJAwIDAQABo1owWDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIHgDALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwIwFgYDVR0RBA8wDYILdHNlX2Njc2RlbW8wDQYJKoZIhvcNAQELBQADggIBAAKkUiusARz+Ezf6iSkJubeCa6L4Hsq+pi/2efR2jspWy78EidpvM1C+ozYy1Ze5+HgH+Y60znGUmFohP1wcOwUr8HfFDN1ewVNhdieyGfTuQRn8spY49uuK8Eju53dzinG5ico5gH1WVcFRIwFzxIXuKcvI2NpXIfW9Hh5WGELo147oWe6O9heCC9PlPQghzq15T5gjTOrN04wvwcRkFG3e1Sm6zinY/879hOsVPjJVW+dKPvgB4rQx6gmg6W+Vg5woaK1FIqTphcfZhzT6jt+w6ujFe1NPHNfvS0xG/TOAyZLXvVFzysHBcsIUUgSlIxxa4avFD2roW69VWgL5i8nuHm1t6QxAswMatNODFqX7eUqi1qw0BZXRYHzdRTZkuQQBg6uKwS5jM41NahEcpDA861XIbysywrNySD9DNhCLBm7zyxYq1e0VFDZPgEfyTAcC+ALXMAhTWZyqo95uEhAV3g/K6+ABrgBRUPfIDXqyJkKfEgrGXyMnkWXFf3jsUbYtU8Qjhc19QGG9tgqvtRMjbIgLsPoeaO+Efli7XWB+t2bd6lfeFJ0jfzI1zNrABAmRQiExXBHNV5WyoPP/QdeB1OwwRBzWQOcIKoUQMAGojbRUhxCqUGfOh3RMk/z5T6ZUqCbE77Joq1oYe9xXDXsZ18k3znNrngmhNvhc001D Note: that header value above is the actual header value to use in client requests to the endpoint for the instance ccsdemo. It is the double encoding (as specified above) of the database certificate for the ccsdemo instance. That database certificate is attached to this article, and you can use it in client calls for QA testing of your endpoint. If for some reason you need to test your endpoint for a different instance name, please open a case requesting the corresponding database certificate from customer support. Response (Success) HTTP Status: 200 Content Type: JSON The wrappedKey is the customer's secret key, encrypted as detailed in the "Operation Logic" section below Body: {"keyId":1, "validUntil":"<yyyy-MM-DDThh:mm:ss.sssZ>", "wrappedKey":"<base64(rsa_public_encrypt(kek))>" } Body Example: { "keyId": 1, "validUntil": "2021-12-31T00:00:00Z", "wrappedKey": "XaAenWmlWhdkhklzYSwDzrWUiE3JnhUAMD1HvNOjUqq7IZ8tmrUURkAsv4cgFF4a7gLLbxDmFlaG/M4j+gXMPlvJieMQfOquZ0o+QhbV8ujTzleCAeFCAfXVRgHjkh7mDFbdmIFWT/NC5epMIc9cQEb0UF4OC0sbW4xAegq9ZDHWKtkzlK/xMTHkhyhW4oPUXuDmA92FagHJlFAe86nHhK9Fy8v4mpiwofssUIG5QyhLpEwBuZggsZo/MKLTkTkJEiiIdwpLN/JL3NbVczGIskUpAS92EwM8HvnjumGfJNlpHb4TBsw9N0cFGWsGn0dsG5N+iQmunTTYn95Xzk01Q==" } Response (Bad Request) HTTP Status: 400 When The URI does not match the /kek/<instance>/<key_id> pattern Content Type: JSON Body : {"error": "<message>"} Response Example: {"error": "The operation is not supported"} Response (Not Authorized) HTTP Status: 401 When X-DB-Certificate is invalid as detailed in the "Operation Logic" section below Body : {"error": "<message>"} Body Example: {"error": "The Database certificate is invalid, reason: expired validity date"} Response (Not Found) HTTP Status: 404 Expected when the instance name is not known by the endpoint, or the keyId is not known by the endpoint. Body : {"error": "<message>"} Body Examples: {"error": "The requested instance doesn't match the expected instance: requestedInstance=vvsdemo"} {"error": "The keyId=5 is invalid"} Response (Server Error) HTTP Status: 500 Operation failed for some reason, other than user error Body : {"error": "<message>"} Response Example: {"error": "There was a system error. Please contact Acme corp IT support. Quote error id E666687 when contacting support"} Operation Logic Customer Secret Key The Customer Endpoint must have read access to the customer's secret key (KEK), which must have the following characteristics: Key can't be changed (because there is no rotation support at this time)Key must be 64 hexadecimal characters. Generally, this means generating a random 32 bytes (or 256 bits) and expressing it in hexadecimal. Database Certificate Validation The database Certificate in the header must fulfill the following: It must be parsable as an X-509 certificateThe Common Name (CN) attribute must equal "tse_<instance >" where <instance > is the name of the instance for which a key is being requested. For example, if your instance is ccsdemo.service-now.com, the CN must be tse_ccsdemo. The database certificate must be issued and signed by either of the ServiceNow root certificates (attached to this article as 'snc-db-encrypt.ca.pem.txt' and 'snc-db-ejbca-root.pem.txt').The database certificate expiration date must be in the future. It is ServiceNow's responsibility to provide a newer certificate in requests, before the older certificate expires. Process for Encrypting the Customer Secret Key Extract the Public Key from the Database certificate that was passed in the HTTPS header Use that public key to encrypt the customer secret key, using the padding algorithm referred to by OpenSSL as PKCS1_OAEP_PADDING. In Java, using Castle's encryption library, this padding algorithm is identified as "RSA/NONE/OAEPWithSHA-1AndMGF1Padding". The encrypted result will be a byte array. Base64 encode that encrypted byte array as a string. That string must be returned as the wrappedKey in the JSON response body. This encryption ensures that the customer secret key can only be decrypted by the customer's ServiceNow instance database, which alone has the private key. The validUntil timestamp in the response body must follow the ISO8601 timestamp format, expressed in the Zulu time zone with a z at the end of the timestamp. The validUntil timestamp is the time after which ServiceNow must shut down the database on your instance. Your customer endpoint must always specify a future timestamp on each response to the periodic key poll, to signify that the database should remain running. If the validUntil time returned is in the past, then database must be shut down immediately. Consider using a date calculated from today, such as seven days from today. Reference Java Code Snippet class RSAPublicKeyWrapper { private final PublicKey publicKey; RSAPublicKeyWrapper(HttpServletRequest request) throws Exception { byte[] x509EncodedCertificate = Base64.getDecoder().decode(request.getHeader("X-DB-Certificate")); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); InputStream in = new ByteArrayInputStream(x509EncodedCertificate); X509Certificate cert = (X509Certificate)certFactory.generateCertificate(in); X509EncodedKeySpec spec = new X509EncodedKeySpec(cert.getPublicKey().getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); this.publicKey = keyFactory.generatePublic(spec); } byte[] wrap(String proprietaryKey) { try { return getCipher(Cipher.ENCRYPT_MODE).doFinal(proprietaryKey.getBytes()); } catch (Exception e) { throw new RuntimeException(e); } } private Cipher getCipher(int mode) throws Exception { // This example relies on the presence of the BouncyCastle encryption library Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA-1AndMGF1Padding", "BC"); cipher.init(mode, publicKey); return cipher; }} Optional Features Some customers implement features that are not part of the customer endpoint specification, but don't prevent it functioning correctly. Allow Lists As an extra layer of security, some customers restrict endpoint access to a defined set of IP addresses. When this is done, the following global IP ranges (owned and operated exclusively by ServiceNow ) must be included in that set:37.98.232.0/21103.23.64.0/22149.96.0.0/16199.91.136.0/21148.139.0.0/16