CMK Tenant Security Client

The Tenant Security Client is a Java SDK which provides a simplified interface for making requests to the Tenant Security Proxy. It provides method calls for encrypting and decrypting customer data as well as pushing auditable events to your customers' logging infrastructure.

All data passed to the SDK is encrypted directly within the SDK. Your customers' data is never transferred to the Tenant Security Proxy. Instead, the Tenant Security Proxy is responsible for generating document encryption keys (DEKs) and encrypted document encryption keys (EDEKs) and providing them to the client, which uses the key to do the encryption work. If these acronyms are confusing, envelope encryption will give you a better sense of how these keys are generated and used.

On an encrypt operation, the client sends a request to the Tenant Security Proxy to generate and encrypt a DEK using your customer's KMS. The Tenant Security Client then uses this DEK to AES encrypt the provided data. An Encrypted Document Encryption Key (EDEK) and the encrypted data are returned to your application to be persisted. The unencrypted DEK is immediately discarded.

TSClientTSProxyCustomer KMSrequest encryptGenerate (DEK, EDEK)return (DEK, EDEK)AES encrypt using DEKDelete(DEK)Store EDEK, CiphertextTSClientTSProxyCustomer KMS

The cardinal rule for CMK is that you, the vendor, are never given access to the unencrypted DEK. You store the encrypted DEK alongside encrypted application data. Since only the customer can unlock the EDEK, this pattern gives your customers independent access control and an independent audit log.

On a subsequent decrypt call, your application provides the encrypted DEK and the encrypted data to the Tenant Security Client, which will use the Tenant Security Proxy to decrypt this EDEK. The EDEK decryption, or unwrapping operation, is done in conjunction with your customer's KMS, producing the original DEK used to encrypt. This resulting DEK is passed back to the Tenant Security Client, where it is used to decrypt the data back to its original form.

TSClientTSProxyCustomer KMSrequest decrypt (EDEK)Decrypt EDEKreturn (DEK)AES decrypt using DEKDelete(DEK)Return plaintextTSClientTSProxyCustomer KMS


The Tenant Security client is published to Maven. Refer to their docs on how to add this library as a dependency to your existing JVM application. The minimum Java version supported by this library is Java 8 Update 152.


This is a minimal example of round tripping a document.

import java.util.Map;
import com.ironcorelabs.tenantsecurity.kms.v1.*;

// Initialize the client with a Tenant Security Proxy domain and API key.
// Typically this would be done once when the application or service initializes
client = TenantSecurityKMSClient.create(PROXY_ENDPOINT, API_KEY).get();

// Create a map containing your document data
Map<String, byte[]> documentMap = new HashMap<>();
documentMap.put("ssn", "000-12-2345".getBytes("UTF-8"));
documentMap.put("address", "2825-519 Stone Creek Rd, Bozeman, MT 59715".getBytes("UTF-8"));
documentMap.put("name", "Jim Bridger".getBytes("UTF-8"));

// Create metadata used to associate this document to a tenant, name the document, and
// identify the service or user making the call
DocumentMetadata metadata = new DocumentMetadata(TENANT_ID, "serviceOrUserId", "document label");

// Request a key from the KMS and use it to encrypt the document
EncryptedDocument encryptedResults = client.encrypt(documentMap, metadata).get();

/* … persist the encryptedResults.getEdek() and encryptedResults.getEncryptedFields() … */
String edek = encryptedResults.getEdek();
Map<String, byte[]> fields = encryptedResults.getEncryptedFields();
/* … retrieve the encrypted fields and EDEK from your persistence layer */

// Recreate the encrypted document from persisted data
EncryptedDocument recreated = new EncryptedDocument(fields, edek);

// Decrypt the document back to plaintext
PlaintextDocument decryptedResults = client.decrypt(recreated, metadata).get();
Map<String, byte[]> decryptedDocumentMap = decryptedResults.getDecryptedFields();

There is also a batch API that may be useful if you’re operating on many documents at once.


See the Javadocs for a more complete register of all exposed classes and methods.