The system SHALL maintain a ConcurrentDictionary<string, IKeyEncryptionKey> keyed by encryptionKeyId (the Customer Master Key URL) that caches the CryptographyClient returned by IKeyEncryptionKeyResolver.Resolve().
- WHEN
UnwrapKey(or prefetch) is called for a Customer Master Key URL not yet in the resolved-client cache - THEN the system SHALL call
Resolve(keyId)(orResolveAsync(keyId)on the async path), store the returnedIKeyEncryptionKeyin the cache, and use it for theUnwrapKeycall
- WHEN
UnwrapKeyis called for a Customer Master Key URL that is already in the resolved-client cache - THEN the system SHALL skip the
Resolve()call and use the cachedIKeyEncryptionKeydirectly for theUnwrapKeycall
- WHEN a
ProtectedDataEncryptionKeycache miss triggersUnwrapKeywith a warm resolved-client cache - THEN only one Key Vault HTTP call SHALL be made (
UnwrapKeyPOST) instead of two (ResolveGET +UnwrapKeyPOST)
The IKeyEncryptionKey object SHALL contain only the Key Vault URL, key name, key version, and HTTP pipeline configuration. It SHALL NOT contain any private key material.
- WHEN the resolved-client cache is inspected
- THEN each entry SHALL be a
CryptographyClient(or equivalent) containing only the Customer Master Key URL and auth pipeline reference — no RSA private key bytes
The resolved-client cache entry SHALL be invalidated when the Customer Master Key URL changes (key rotation where the Client Encryption Key is rewrapped to a different Customer Master Key).
- WHEN
ClientEncryptionKeyProperties.EncryptionKeyWrapMetadata.Valuereturns a different Customer Master Key URL than the one cached - THEN the system SHALL call
Resolve()with the new URL and update the cache entry