Salesforce Shield Platform Encryption setup, key management, encrypted field limitations, and Apex Crypto class usage
From claude-sfdx-iqnpx claudepluginhub bhanu91221/claude-sfdx-iq --plugin claude-sfdx-iqThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Salesforce Shield Platform Encryption provides encryption at rest for data stored in Salesforce. It operates at the platform level, encrypting data before it is written to disk and decrypting it when authorized users access it.
Shield Encryption is separate from Classic Encryption (which uses Encrypted Text field type and a 128-bit key). Shield uses 256-bit AES encryption with a tenant-specific key hierarchy.
Master Secret (Salesforce HSM)
|
+-- Tenant Secret (customer-generated, stored encrypted)
|
+-- Data Encryption Key (derived, per-record or per-field type)
The same plaintext always produces the same ciphertext. This enables certain query operations.
Supported operations on deterministic fields:
= and != comparisons in WHERE clausesIN clausesGROUP BY and ORDER BYDISTINCTLimitations:
Each encryption produces a different ciphertext (uses random initialization vector). More secure but limits query operations.
Supported operations on probabilistic fields:
Not supported on probabilistic fields:
LIKE operatorGROUP BYORDER BYDISTINCTSUM, AVG, etc.)| Requirement | Deterministic | Probabilistic |
|---|---|---|
Filter with = in SOQL | Yes | Limited |
Use in GROUP BY | Yes | No |
Use in ORDER BY | Yes | No |
Use LIKE operator | No | No |
| Maximum security | No | Yes |
| Formula field reference | Limited | No |
| Unique enforcement | Yes | No |
| Report grouping | Yes | No |
Rule: Use deterministic encryption when you need to filter or group by the field. Use probabilistic when the field is display-only and maximum security is required.
| Object | Fields |
|---|---|
| Account | Name, Description, Phone, Fax, Website, BillingAddress, ShippingAddress |
| Contact | Name, Email, Phone, MailingAddress, Description |
| Case | Subject, Description |
| Lead | Name, Email, Phone, Company, Address |
| Opportunity | Name, Description, Amount (deterministic only) |
Not encryptable:
Setup > Platform Encryption > Key Management > Generate Tenant Secret
Select the type:
Rotate tenant secrets periodically for compliance. Rotation does not re-encrypt existing data immediately.
Rotation process:
Archived (still used to decrypt old data)Setup > Platform Encryption > Key Management > Generate Tenant Secret
Setup > Platform Encryption > Encryption Statistics > Encrypt Now (sync existing data)
Rules:
Upload your own key material instead of having Salesforce generate it.
Setup > Platform Encryption > Key Management > Bring Your Own Key
Upload a 256-bit AES key encrypted with a Salesforce-provided certificate. This gives you control over key material while Salesforce manages the encryption operations.
Cache-only keys are stored only in memory (Salesforce cache), never persisted to disk. They are used for encrypting external data temporarily stored in Salesforce.
Use cases:
Limitations:
// Deterministic encryption -- exact match works
List<Contact> contacts = [
SELECT Id, Name, Email
FROM Contact
WHERE Email = 'user@example.com'
WITH SECURITY_ENFORCED
];
// Deterministic -- GROUP BY works
AggregateResult[] results = [
SELECT BillingCity, COUNT(Id) cnt
FROM Account
GROUP BY BillingCity
];
// LIKE is never supported on encrypted fields
// This will throw a runtime error
List<Contact> contacts = [
SELECT Id, Email
FROM Contact
WHERE Email LIKE '%@example.com'
];
// Probabilistic -- GROUP BY fails
// This will throw a runtime error if the field is probabilistic
AggregateResult[] results = [
SELECT EncryptedField__c, COUNT(Id) cnt
FROM MyObject__c
GROUP BY EncryptedField__c
];
// For LIKE-style searches on encrypted fields, use a non-encrypted derived field
// Store a hashed domain for email searches
// Or use Salesforce Search (SOSL) which works on encrypted fields if search index is also encrypted
List<List<Contact>> searchResults = [
FIND 'example.com' IN EMAIL FIELDS
RETURNING Contact(Id, Name, Email)
];
The Crypto class provides encryption, decryption, hashing, and MAC generation for custom encryption needs (separate from Shield Platform Encryption).
Blob key = Crypto.generateAesKey(256); // 128 or 256 bits
// Store this key securely (Named Credential, Protected Custom Metadata, etc.)
// Never hardcode keys in Apex
public class EncryptionService {
// Encrypt plaintext
public static Blob encryptData(String plaintext, Blob key) {
Blob data = Blob.valueOf(plaintext);
// AES-256-CBC with random IV (prepended to ciphertext)
Blob encrypted = Crypto.encryptWithManagedIV('AES256', key, data);
return encrypted;
}
// Decrypt ciphertext
public static String decryptData(Blob ciphertext, Blob key) {
Blob decrypted = Crypto.decryptWithManagedIV('AES256', key, ciphertext);
return decrypted.toString();
}
}
encryptWithManagedIV vs encrypt:
encryptWithManagedIV -- Salesforce generates and manages the initialization vector (IV). Easier and recommended.encrypt -- You provide your own IV. Use when interoperating with external systems that require a specific IV.// Verify data integrity with HMAC
Blob hmacKey = Crypto.generateAesKey(256);
Blob data = Blob.valueOf('sensitive data');
Blob mac = Crypto.generateMac('HmacSHA256', data, hmacKey);
// Verify
Blob expectedMac = Crypto.generateMac('HmacSHA256', data, hmacKey);
Boolean isValid = (mac == expectedMac);
// One-way hash (no key, cannot decrypt)
Blob hashedData = Crypto.generateDigest('SHA256', Blob.valueOf('data to hash'));
String hexHash = EncodingUtil.convertToHex(hashedData);
| Operation | Algorithms |
|---|---|
| Encryption | AES128, AES192, AES256 |
| Hashing | MD5, SHA1, SHA256, SHA512 |
| HMAC | HmacSHA1, HmacSHA256, HmacSHA512, HmacMD5 |
| Digital Signature | RSA-SHA1, RSA-SHA256, RSA, ECDSA |
Shield Event Monitoring tracks user activity for security and compliance auditing.
Key event types:
Querying Event Logs:
List<EventLogFile> logs = [
SELECT Id, EventType, LogDate, LogFileLength
FROM EventLogFile
WHERE EventType = 'Login'
AND LogDate = LAST_N_DAYS:7
];
Integration with external SIEM:
# Download event log files via SF CLI
sf data query --query "SELECT Id, EventType, LogFile FROM EventLogFile WHERE EventType='Login' AND LogDate=TODAY" --target-org myOrg --result-format csv