Newer Version Available
RemoteKeyCalloutEvent
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 |
|
| ReplayID |
|
| RequestIdentifier |
Available in API version 45.0 and later. |
| StatusCode |
|
| TenantSecretID |
|
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.
| 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) |
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}| 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. |