Repository navigation
feat: add KeyManagementClient, KmsRegistry and InMemoryKms - #1031
shangxinli wants to merge 1 commit into
Conversation
4852f34 to
78d5a09
Compare
wgtmac
left a comment
There was a problem hiding this comment.
Please update this branch after #1030 and add key_management_client.h to the unconditional install list and in_memory_kms.h to the bundle+encryption list. The merged code now uses explicit PATTERN lists, so the new public headers would otherwise be omitted from installed packages. Please preserve the AES source rename and the fixes already merged in #1030.
| } | ||
| factory = it->second; | ||
| } | ||
| ICEBERG_ASSIGN_OR_RAISE(auto client, factory()); |
There was a problem hiding this comment.
Could Load reject an empty factory before invoking it, or document a non-empty factory as a Register precondition? An empty std::function currently throws std::bad_function_call instead of returning a Result error.
There was a problem hiding this comment.
Load now rejects an empty factory before invoking it, with a regression test.
There was a problem hiding this comment.
Good catch - Load now rejects an empty factory with an invalid-argument error instead of invoking it, with a regression test that fails with bad_function_call without the guard.
78d5a09 to
c84d169
Compare
- KeyManagementClient (core): wraps and unwraps keys with master keys held in a KMS, mirroring Java's interface, including optional key generation. - KmsRegistry (core): creates the catalog's KMS client from the same catalog properties as Java, `encryption.kms-type` (aws, gcp, azure) or `encryption.kms-impl` (a registered name). As in Java, a property that is present but empty is a misconfiguration rather than "no KMS". Clients are initialized with the catalog properties. - InMemoryKms (bundle): master keys in memory, for tests and local use. Wire compatible with Java's MemoryMockKMS, so it unwraps keys written by Java tests. Master keys can be given as catalog properties (encryption.in-memory-kms.key.<id> = Base64).
c84d169 to
8fd564f
Compare
Summary
Step 5 of #988. Adds the KMS client interface and the registry that creates one from catalog properties, plus an in-memory client for tests and local development.
KeyManagementClient(core): wraps and unwraps secret keys with a master key held in a KMS, mirroring Java's interface including the optional in-KMS key generation path. The core library stays free of crypto dependencies — this is an interface only.KmsRegistry(core): resolves the catalog's KMS client from the same property names as Java,encryption.kms-type(aws,gcp,azure) orencryption.kms-impl(a name registered withKmsRegistry::Register). Built-in clients register themselves when their library is linked; applications register custom ones before creating catalogs. Returns a null client when neither property is set, so an unencrypted catalog is not an error.InMemoryKms(bundle,ICEBERG_ENCRYPTION): master keys held in memory, wire compatible with Java'sMemoryMockKMS— AES-GCM wrap under the master key with no AAD. Master keys can also come from catalog properties asencryption.in-memory-kms.key.<id>= Base64.Stacked on #1030 (step 4), which
InMemoryKmsuses for the AES-GCM primitives; the first commit here is that PR. Review only the second commit, or wait for #1030 to land.Java parity
Ported against
KeyManagementClient.javaandEncryptionUtil.createKmsClient, withMemoryMockKMS/UnitestKMSas the reference for the in-memory client. Deliberate differences, both flagged in the code:encryption.kms-implto a class name and instantiates it reflectively. C++ has no reflection, so the registry maps a name to a factory; the property keys and their meaning are unchanged.aliyun. Support Iceberg table encryption (Java-compatible) #988 scopes the built-in clients to AWS, GCP and Azure, soaliyunis not built in here; the doc comment says to register one and select it throughencryption.kms-impl. The type list is otherwise identical.One behavior is matched on purpose rather than "improved": a property that is present but empty counts as set, as in Java, so a misconfigured catalog fails instead of silently loading with no KMS.
Test plan
encryption_testpasses: registry loads a custom implementation and initializes it with the catalog properties, resolves a built-in type case-insensitively, and rejects setting both type and impl, an unsupported type, an unregistered name, and a present-but-empty value.crypto_testpasses:InMemoryKmsunwraps a key encryption key that Iceberg Java'sUnitestKMSwrapped under itskeyAmaster key, which is what makes the Java wire compatibility claim testable rather than a C++ round trip. The same works throughKmsRegistrywith a Base64 master key supplied as a catalog property.cpp20_compatibility_testpasses.key_management_client.his core and unconditional;in_memory_kms.his bundle plus encryption, so it joinsaes_gcm_stream.hbehindICEBERG_PUBLIC_HEADERS_ENCRYPTION.pre-commitclean, including the generated public-header check.