Skip to content

Add support for Field-Level Automatic and Queryable Encryption #2759

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

Draft
wants to merge 15 commits into
base: feature/queryable-encryption
Choose a base branch
from

Conversation

GromNaN
Copy link
Member

@GromNaN GromNaN commented Apr 25, 2025

Q A
Type feature
BC Break no
Fixed issues PHPORM-317

Summary

⚠️ This feature requires a MongoDB Atlas or Enterprise license.

Client-Side Field Level Encryption (CSFLE) is a feature that enables you to encrypt data in your application before you send it over the network to MongoDB. With CSFLE enabled, no MongoDB product has access to your data in an unencrypted form.

Queryable Encryption gives you the ability to perform the following tasks:

  • Encrypt sensitive data fields from the client-side.
  • Store sensitive data fields as fully randomized encrypted data on the database server-side.
  • Run expressive queries on the encrypted data.

Implementation:

The encrypted collection must be created using the schema manager (odm:schema:create command)

@GromNaN GromNaN changed the base branch from 2.11.x to 2.12.x April 28, 2025 20:08
@GromNaN GromNaN changed the base branch from 2.12.x to feature/queryable-encryption May 5, 2025 13:48
Copy link
Member

@alcaeus alcaeus left a comment

Choose a reason for hiding this comment

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

Left some questions, and phpstan seems to be unhappy about some of the mapping types.

The logic and tests for it look solid.

#[Encrypt]
----------

The `#[Encrypt]` attribute is used to define an encrypted field mapping for a document property. It allows you to configure fields for encryption and queryable encryption in MongoDB.
Copy link
Member

Choose a reason for hiding this comment

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

RST syntax requires two backticks for inline code:

Suggested change
The `#[Encrypt]` attribute is used to define an encrypted field mapping for a document property. It allows you to configure fields for encryption and queryable encryption in MongoDB.
The ``#[Encrypt]`` attribute is used to define an encrypted field mapping for a document property. It allows you to configure fields for encryption and queryable encryption in MongoDB.

public string $name;
}

For more details, refer to the MongoDB documentation on [Queryable Encryption](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/encrypt-and-query/).
Copy link
Member

Choose a reason for hiding this comment

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

Wrong link syntax:

Suggested change
For more details, refer to the MongoDB documentation on [Queryable Encryption](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/encrypt-and-query/).
For more details, refer to the MongoDB documentation on `Queryable Encryption <https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/encrypt-and-query/>`_.

@@ -16,7 +16,7 @@
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="document" type="odm:document" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="embedded-document" type="odm:document" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="embedded-document" type="odm:embedded-document" minOccurs="0" maxOccurs="unbounded" />
Copy link
Member

Choose a reason for hiding this comment

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

Noted that this change will disappear when #2766 is merged.

@@ -225,6 +220,21 @@ public function getClient(): Client
return $this->client;
}

public function getClientEncryption(): ClientEncryption
Copy link
Member

Choose a reason for hiding this comment

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

We may want to mark this method as internal:

Suggested change
public function getClientEncryption(): ClientEncryption
/** @internal **/
public function getClientEncryption(): ClientEncryption

* @param positive-int|null $contention
*/
public function __construct(
public ?string $queryType = null,
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to use a backed enum for this?

<xs:element name="field" type="odm:field" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="embed-one" type="odm:embed-one" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="embed-many" type="odm:embed-many" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="encrypt" type="odm:encrypt-field" minOccurs="0" maxOccurs="1" />
Copy link
Member

Choose a reason for hiding this comment

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

Why is this an element instead of an attribute? Is it to future-proof this in case there will be options for encrypting entire documents in future?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I plan to add a "key" attribute to the element.

$this->dm->getClientEncryption(),
$this->dm->getConfiguration()->getKmsProvider(),
null, // @todo when is it necessary to set the master key?
$options,
Copy link
Member

Choose a reason for hiding this comment

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

Should you be using $this->getWriteOptions here like below and add the encrypted field config?


public function testCreateAndQueryEncryptedCollection(): void
{
// @todo skip if not using MongoDB < 7, single node or not enterprise
Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

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