In order to decrypt an existing encrypted document, you first define metadata that specifies the tenant ID that was used when the document was encrypted. Similar to encrypt, you must also provide the ID of the service or user that is performing the decryption and a label for the type of data being decrypted. These fields help build richer audit trails that provide more context to your customers about what data is being decrypted, by whom, and why.

The tenantID field of the provided metadata must be the same as the one specified when the data was encrypted so that the proper tenant key is used during decryption. The other metadata fields do not have to match and are only used to improve auditing.

DocumentMetadata metadata =
    new DocumentMetadata(TENANT_ID, "serviceId", "data label");

Create an EncryptedDocument from the EDEK and encrypted fields that you have persisted.

String edek = /* base64 encoded EDEK from your persistence layer */;
Map<String, byte[]> encryptedFields = /* fieldname and ciphertext pairs from your persistence layer */;
EncryptedDocument recreated = new EncryptedDocument(encryptedFields, edek);

Now decrypt the encrypted document map and retrieve the resulting plaintext document map. The client.decrypt call makes a request to the Tenant Security Proxy which in turn makes a request to the tenant's KMS to unwrap the EDEK that you've provided. Once the DEK has been returned to the client, it is used to decrypt the provided document bytes. The encrypted data is never transferred to the Tenant Security Proxy - all decryption happens locally within the client.

The decrypt call returns an instance of a CompletableFuture which will resolve with an instance of the PlaintextDocument class. This class contains the map of document id/name to decrypted bytes (getDecryptedFields()).

PlaintextDocument decryptedResults = client.decrypt(recreated, metadata).get();
Map<String, byte[]> decryptedDocumentMap = decryptedResults.getDecryptedFields();

See the Javadocs for more options and specifics.