Newer Version Available

This content describes an older version of this product. View Latest

RemoteKeyCalloutEvent

Represents an event for callouts that fetch encrypted key material from a customer endpoint. This object is available in API versions 45.0 and later.

The RemoteKeyCalloutEvent captures events related to the success or failure of a callout that fetches encrypted key material from an end point. Based on the Platform Events framework, a RemoteKeyCalloutEvent is published every time a callout is made to an external key service. This event lets you monitor your cache-only key callouts in real time, and receive alerts about any errors that might occur. You can subscribe to events with after insert Apex triggers and store events in custom objects, security information event management (SIEM), or other back-end systems.

Supported Calls

describeSObjects()

Special Access Rules

Access to RemoteKeyCalloutEvent data requires purchasing Salesforce Shield or Shield Platform Encryption. The RemoteKeyCalloutEvent only applies to callouts that fetch cache-only key material.

Fields

Field Details
Details
Type
textarea
Properties
Nillable
Description
A JSON representation with more information about the StatusCode. Not all status codes (for example, SUCCESS) show a populated Details field. Populated Details fields include key-value pairs that you can use to make Apex triggers and other programmatic assertions.
ReplayID
Type
string
Properties
Nillable
Description
A numeric ID that identifies the asset token event. Each ID is incremented automatically and guaranteed to be higher than the ID of the previous event, but not necessarily contiguous for consecutive events.
RequestIdentifier
Type
string
Properties
Nillable
Description
When Replay Detection for Cache-Only Keys is enabled, a unique marker automatically generated and sent with every callout. This marker includes the key identifier, a nonce generated for that callout instance, and the nonce required from the endpoint.

Available in API version 45.0 and later.

StatusCode
Type
picklist
Properties
Nillable, Restricted picklist
Description
A code that characterizes the error. The full list of status codes is available in the WSDL file for your org (see Generating the WSDL File for Your Organization).
TenantSecretID
Type
reference
Properties
Nillable
Description
The record ID of the tenant secret associated with the published event.

Usage

To view a RemoteKeyCalloutEvent and perform custom actions after your callout, create an after insert Apex trigger in Dev Console. These triggers let you assign custom actions for your event. You can set in-app alerts and send email alerts to people who maintain your key service, including users who don’t have a Salesforce login.

For longer-term monitoring, you can store RemoteKeyCalloutEvent data in custom objects and custom fields, SIEM, or other back-end systems. Then use business rules to send alerts. For example, you can set an alert that sends admins an email when something is wrong with a key service.

Here’s an example of an after insert trigger that stores RemoteKeyCalloutEvent results in a custom object called Key Service Callout Log. The custom object also draws data from the TenantSecret object.
Table 1. Sample Custom Object: Key Service Callout Log
Field Label Field Name Data Type
Key Service Callout Log ID Name Auto Number
Details Details__c Text(255)
Replay Detection Replay_Detection__c Text (255)
Status Code Status_Code__c Text(255)
Tenant Secret Id Tenant_Secret_Id__c Text(50)
Tenant Secret Status Tenant_Secret_Status__c Text(255)
Type Type__c Text(10)
Version Version__c Number(10,0)
If you use this trigger sample, adjust the field API names to suit your needs.
1trigger RemoteKeyCalloutEvent on RemoteKeyCalloutEvent (after insert){ 
2    List<Key_Service_Callout_Log__c> l = new List<Key_Service_Callout_Log__c>();
3    Set<ID> TenantSecretIds = new Set<ID>();
4    Map<ID, TenantSecret> TenantSecrets;
5    for(RemoteKeyCalloutEvent event : Trigger.new){
6        if(event.TenantSecretId != null && !TenantSecretIds.contains(event.TenantSecretId))
7            TenantSecretIds.add(event.TenantSecretId);
8    }
9    if(TenantSecretIds != null && !TenantSecretIds.isEmpty())
10      TenantSecrets = new Map<ID, TenantSecret>([SELECT Type, Version, Status FROM TenantSecret where Id In: TenantSecretIds]);
11    
12    for(RemoteKeyCalloutEvent event : Trigger.new){
13        Key_Service_Callout_Log__c log = new Key_Service_Callout_Log__c();
14      log.Status_Code__c = event.StatusCode;
15        log.Tenant_Secret_ID__c = event.TenantSecretId;
16          log.Replay_Detection__c = event.RequestIdentifier;
17      log.Details__c = event.Details;
18        if(TenantSecrets != null && TenantSecrets.containsKey(event.TenantSecretId)){
19            log.Type__c = TenantSecrets.get(event.TenantSecretId).Type;
20            log.Version__c = TenantSecrets.get(event.TenantSecretId).Version;
21            log.Tenant_Secret_Status__c = TenantSecrets.get(event.TenantSecretId).Status;
22        }
23        l.add(log);
24    }
25    
26    insert l;
27}
To troubleshoot callout errors, review the StatusCode and Details fields. These fields give you information about remote key callout errors or exceptions in raw JSON format. Successful, empty callout, and timeout responses return empty Details fields.
Table 2. Cache-Only Key Service Errors and Status Codes
RemoteKeyCalloutEvent Status Code Error Tips for Fixing the Problem
DESTROY_HTTP_CODE The remote key service returned an HTTP error: {000}. A successful HTTP response will return a 200 code. To find out what went wrong, review the HTTP response code.
ERROR_HTTP_CODE The remote key service returned an unsupported HTTP response code: {000}. A successful HTTP response will return a 200 code. To find out what went wrong, review the HTTP response code.
MALFORMED_CONTENT_ENCRYPTION_KEY The remote key service returned a content encryption key in the JWE that couldn’t be decrypted with the certificate’s private key. Either the JWE is corrupted, or the content encryption key is encrypted with a different key. Check that you set up your named credential properly and are using the correct BYOK-compatible certificate.
MALFORMED_DATA_ENCRYPTION_KEY The content encryption key couldn’t decrypt the data encryption key that was returned in the remote key service’s JWE. The data encryption key is either malformed, or encrypted with a different content encryption key. Check that you set up your named credential properly and are using the correct BYOK-compatible certificate. Named credentials must call out to an HTTPS endpoint.
MALFORMED_JSON_RESPONSE We can’t parse the JSON returned by your remote key service. Contact your remote key service for help. Contact your remote key service.
MALFORMED_JWE_RESPONSE The remote key service returned a malformed JWE token that can’t be decoded. Contact your remote key service for help. Contact your remote key service.
EMPTY_RESPONSE The remote key service callout returned an empty response. Contact your remote key service for help. Contact your remote key service.
RESPONSE_TIMEOUT The remote key service callout took too long and timed out. Try again. If your key service is unavailable after multiple callout attempts, contact your remote key service.
UNKNOWN_ERROR The remote key service callout failed and returned an error: {000}. Contact your remote key service.
INCORRECT_KEYID_IN_JSON The remote key service returned JSON with an incorrect key ID. Expected: {valid keyID}. Actual: {invalid keyID}. Check that you set up your named credential properly and are using the correct BYOK-compatible certificate.
INCORRECT_KEYID_IN_JWE_HEADER The remote key service returned a JWE header with an incorrect key ID. Expected: {valid keyID}. Actual: {invalid keyID}. Check that you set up your named credential properly and are using the correct BYOK-compatible certificate.
INCORRECT_ALGORITHM_IN_JWE_HEADER The remote key service returned a JWE header that specified an unsupported algorithm (alg): {algorithm}. The algorithm for encrypting the content encryption key in your JWE header must be in RSA-OAEP format.
INCORRECT_ENCRYPTION_ALGORITHM_IN_JWE_HEADER The remote key service returned a JWE header that specified an unsupported encryption algorithm (enc): {your enc}. The algorithm for encrypting the data encryption key in your JWE header must be in A256GCM format.
INCORRECT_DATA_ENCRYPTION_KEY_SIZE Data encryption keys encoded in a JWE must be 32 bytes. Yours is {value} bytes. Make sure that your data encryption key is 32 bytes.
ILLEGAL_PARAMETERS_IN_JWE_HEADER Your JWE header must use alg, enc, and kid parameters, but no others. Found: {parameter}. Remove the unsupported parameters from your JWE header.
AUTHENTICATION_FAILURE_RESPONSE Authentication with the remote key service failed with the following error: {error}. Check the authentication settings for your chosen named credential.
POTENTIAL_REPLAY_ATTACK_DETECTED The remote key service returned a JWE header with an incorrect nonce value. Expected: {0}. Actual: {1} Make sure that your JWE header includes the RequestID included in the callout.
UNKNOWN_ERROR The remote key service callout failed and returned an error: java.security.cert.CertificateExpiredException: NotAfter: {date and time of expiration} The certificate for your cache-only key expired. Update your cache-only key material to use an active BYOK-compatible certificate.