feat(encryption) [5/N] Support encryption: Encryption Manager#2383
feat(encryption) [5/N] Support encryption: Encryption Manager#2383xanderbailey wants to merge 5 commits intoapache:mainfrom
Conversation
b7fe819 to
74f9e2f
Compare
| default = moka::future::Cache::builder().time_to_live(DEFAULT_CACHE_TTL).build(), | ||
| setter(skip) | ||
| )] | ||
| kek_cache: moka::future::Cache<String, SensitiveBytes>, |
There was a problem hiding this comment.
Put a cache here for the same reason Java does, KMS is not aware of the key_id and since we populate the cache when we create_kek it would be hard to do this purely within a CachingKmsService
|
Thanks @xanderbailey! Here's my summary of reviewing with Claude:
|
|
We don't have |
Do we think we actually need a comment here? The code seems self documenting here? |
I think UUID is fine here maybe? both are 16 bytes and random |
Agreed. |
Agreed. |
Yeah, seems fine. |
Which issue does this PR close?
Part of #2034
What changes are included in this PR?
Stacked on #2340. Adds
EncryptionManager— handles two-layer envelope encryption (master key → KEK → DEK) for Iceberg tables.New files
encryption_manager.rs—EncryptionManagerwithtyped_builderconstruction:encrypt()/decrypt()— AGS1 stream file encryptiongenerate_native_key_metadata()— generatesStandardKeyMetadata(DEK + AAD prefix) for Parquet Modular Encryption (PME). Callers pass this directly to the Parquet writer'sFileEncryptionPropertiesand serialize it for manifest storage.wrap_key_metadata()/unwrap_key_metadata()— KEK envelope wrapping for manifest list key metadataencrypted_io.rs—EncryptedInputFile,EncryptedOutputFilewrappers for transparent AGS1 stream encrypt/decrypt on read/writeDesign decisions
NativeEncryptedInputFile/NativeEncryptedOutputFilewrappers — For PME,StandardKeyMetadataalready carries the DEK and AAD prefix. Wrapper types that just bundle anInputFile/OutputFilewith the same data are unnecessary indirection. Readers deserializeStandardKeyMetadatadirectly from key_metadata bytes; writers receive(OutputFile, &StandardKeyMetadata)separately.generate_native_key_metadata()is sync — unlike AGS1 encryption, PME key generation doesn't touch KMS. It just generates random bytes locally.How this differs from Java's
StandardEncryptionManageraddManifestListKeyMetadata()mutates an internal map and callers need to downcast toStandardEncryptionManagerto access the keys. Ourwrap_key_metadata()returns(wrapped_key, Option<new_kek>)directly. no hidden mutation, no downcasting. JavaEncryptionUtilgrab-bag: Java needs a static utility class (decryptManifestListKeyMetadata,encryptManifestListKeyMetadata, etc.) because the interface is too narrow. Here those are just methods onEncryptionManager.table_key_idenforced at compile time: Required viatyped_builder, can't forget it. Unencrypted tables useOption<EncryptionManager>instead of Java'sPlaintextEncryptionManager.Notes on usage for how this is used:
load_manifest_listdoes:load_manifestdoes:Are these changes tested?
Yes