Rekey

Rekeying an encrypted document changes which customer KMS is required to access the document without touching the encrypted data. It is a faster, simpler alternative to decrypting data and encrypting it again. Rekeying is possible because of envelope encryption and is done by unwrapping just the encrypted document encryption key (EDEK) and then re-wrapping it using a new KMS config. The EDEK can be re-wrapped using a different tenant’s KMS configuration, or using a different KMS config for its existing tenant; this provides a way to update documents to use a new KMS config so the old KMS config can be removed. This can be useful for migrating a tenant’s data from one KMS config to another or for merging/splitting tenant accounts.
In order to rekey 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 rekeyed. These fields help build richer audit trails that provide more context to your customers about what data is being rekeyed, 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 KMS config is used to unwrap the EDEK. The other metadata fields do not have to match and are only used to improve auditing.
DocumentMetadata metadata =
    new DocumentMetadata("TENANT_ID", "serviceOrUserId", "data label");
const metadata = new RequestMetadata("TENANT_ID", "serviceOrUserId", "data label");
Create the encrypted document structure 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);
const encryptedDoc = {
    edek: /* base64 encoded EDEK from your persistence layer */,
    encryptedDocument: /* fieldname and ciphertext pairs from your persistence layer */
}
Now rekey the encrypted document map by retrieving the encrypted document map and providing that along with the target tenant ID (the tenant whose KMS should now be used to protect the document). The rekey call makes a request to the Tenant Security Proxy which in turn makes a request to the original tenant’s KMS to unwrap the EDEK that you’ve provided. The Tenant Security Proxy then makes an additional call to the new tenant’s KMS (using the KMS config currently marked as primary for the new tenant) to re-wrap the decrypted DEK. The new EDEK is returned to the client as a new encrypted document. No encryption or decryption of the encrypted fields take place at any time.
client.rekeyDocument(recreated, metadata, newTenantId).thenCompose(rekeyed -> {
    String edek = rekeyed.getEdek();
    //Store the updated edek in your persistence layer.
    //The encrypted fields are unchanged from the initial encryption.
})
client.rekeyDocument(encryptedDoc, newTenantId, metadata).then((rekeyed) => {
    const edek = encrypted.edek;
    //Store the updated edek in your persistence layer.
    //The encrypted fields are unchanged from the initial encryption.
});

Products

Documentation

Trust Center

Find Us