Newer Version Available

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

RemoteKeyCalloutEvent (Beta)

Represents an event for callouts that fetch encrypted key material from a customer endpoint. This object is available in API versions 44.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.

As a beta feature, Shield Platform Encryption Cache-Only Key Service is a preview and isn’t part of the “Services” under your master subscription agreement with Salesforce. Use this feature at your sole discretion, and make your purchase decisions only from generally available products and features. Salesforce doesn’t guarantee general availability of this feature within any particular time frame or at all, and we can discontinue it at any time. This feature is for evaluation purposes only. It’s offered as is, and Salesforce has no liability for any harm or damage arising out of or in connection with it. All restrictions, Salesforce reservation of rights, obligations concerning the Services, and terms for related Non-Salesforce Applications and Content apply equally to your use of this feature. You can provide feedback and suggestions for Shield Platform Encryption Cache-Only Key Service in the IdeaExchange and through the Trailblazer Community. For information about enabling this feature in your organization, contact Salesforce.

Note

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
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.
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. If you use this 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.Details__c = event.Details;
17        if(TenantSecrets != null && TenantSecrets.containsKey(event.TenantSecretId)){
18            log.Type__c = TenantSecrets.get(event.TenantSecretId).Type;
19            log.Version__c = TenantSecrets.get(event.TenantSecretId).Version;
20            log.Tenant_Secret_Status__c = TenantSecrets.get(event.TenantSecretId).Status;
21        }
22        l.add(log);
23    }
24    
25    insert l;
26}
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 1. Status Codes and Details
Status Code Corresponding Details
SUCCESS NONE
EMPTY_RESPONSE NONE
MALFORMED_JSON_RESPONSE "error":"com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $"
MALFORMED_JWE_RESPONSE "error":"org.jose4j.lang.JoseException: Parsing error: org.jose4j.json.internal.json_simple.parser.ParseException: Unexpected character (�) at position 16."
MALFORMED_CONTENT_ENCRYPTION_KEY "error":"javax.crypto.BadPaddingException: Decryption error"
MALFORMED_DATA_ENCRYPTION_KEY "error":"javax.crypto.BadPaddingException: Decryption error"
ILLEGAL_PARAMETERS_IN_JWE_HEADER "expect": "alg, enc, kid", "actual":"alg, enc, zip, jku"
INCORRECT_DATA_ENCRYPTION_KEY_SIZE "expect":"32", "actual":"16"
INCORRECT_KEYID_IN_JSON "expected":"34998291-3d55-4d8c-a93b-39f9f672b4e6", "actual":"55b0eb3d-37f8-4739-ac62-24527a4b80c1"
INCORRECT_KEYID_IN_JWE_HEADER "expected":"34998291-3d55-4d8c-a93b-39f9f672b4e6", "actual":"55b0eb3d-37f8-4739-ac62-24527a4b80c1"
INCORRECT_ALGORITHM_IN_JWE_HEADER "expected":"RSA-OAEP","actual":"RSA1_5"
INCORRECT_ENCRYPTION_ALGORITHM_IN_JWE_HEADER "expected":"A256GCM", "actual":"A192GCM"
RESPONSE_TIMEOUT NONE
UNKNOWN_ERROR "error":"UNKNOWN???"
ERROR_HTTP_CODE "code":"305", "message":"fail"
AUTHENTICATION_FAILURE_RESPONSE "error":"DataSourceAuthMissingException: please reconfigure your authentication mechanism"
DESTROY_HTTP_CODE "code":"403","message":"Access Denied"