Skip to content

[Encryption] Set master key when creating an encrypted collection #2780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 13, 2025

Conversation

GromNaN
Copy link
Member

@GromNaN GromNaN commented Jun 12, 2025

The master key is required for all KMS exception "local" (doc).

The masterKey and kmsProvider configurations as set independently from the other autoEncryption options so that we can validate and transform them.
A single kmsProvider is allowed, and used as default when an encrypted collection is created.

@GromNaN GromNaN requested a review from alcaeus June 12, 2025 15:32
@GromNaN GromNaN mentioned this pull request Jun 12, 2025
6 tasks
Comment on lines 713 to 725
if (! is_array($options['kmsProviders'] ?? null) || count($options['kmsProviders']) === 0) {
throw new InvalidArgumentException('The "kmsProviders" encryption option is required and must be a non-empty.');
}

if (! isset($options['kmsProvider']) && count($options['kmsProviders']) > 1) {
throw new InvalidArgumentException('The "kmsProvider" encryption option is required when multiple KMS providers are specified.');
}

$options['kmsProvider'] ??= array_key_first($options['kmsProviders']);

if (! array_key_exists($options['kmsProvider'], $options['kmsProviders'])) {
throw new InvalidArgumentException(sprintf('The "kmsProvider" encryption option "%s" is not defined in the "kmsProviders" option.', $options['kmsProvider']));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion is to only expose a kmsProvider option, which we then normalise into a single kmsProviders element when passing the provider list to the client. This single provider would only have a type (e.g. local), which we can use as the name for the provider wherever needed. This would make the configuration simpler and still allow us to add support for multiple KMS providers in future.

// @todo Throw en exception if multiple KMS providers are defined. This is not supported yet and would require a setting for the KMS provider to use when creating a new collection
if (! isset($options['kmsProviders']) || ! is_array($options['kmsProviders']) || count($options['kmsProviders']) < 1) {
throw new InvalidArgumentException('The "kmsProviders" option is required.');
if ($options['kmsProvider'] !== 'local' && ! isset($options['masterKey'])) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: rename the option defaultMasterKey, as we'll eventually allow setting a different master key in encryption config.

Comment on lines +133 to +135
* kmsProvider?: KmsProvider,
* defaultMasterKey?: array<string, mixed>|null,
* autoEncryption?: array<string, mixed>,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extracted the kmsProvider and defaultMasterKey from the autoEncryption as they are not part of the driver options.


class ConfigurationTest extends BaseTestCase
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parent class was opening a connection to the mongodb server, which is not necessary for validating the configuration.

*
* @return array{keyVaultClient?: Client|Manager, keyVaultNamespace: string, kmsProviders: array<string, mixed>, tlsOptions?: array<string, mixed>}
*/
public function getClientEncryptionOptions(): array
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Configuration class is now responsible for creating the option arrays.

@GromNaN GromNaN merged commit 64cb384 into doctrine:feature/queryable-encryption Jun 13, 2025
20 checks passed
@GromNaN GromNaN deleted the master-key branch June 13, 2025 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants