-
Notifications
You must be signed in to change notification settings - Fork 30
INTPYTHON-527 Add Queryable Encryption support #329
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
base: main
Are you sure you want to change the base?
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
django_mongodb_backend/management/commands/get_encrypted_fields_map.py
Outdated
Show resolved
Hide resolved
django_mongodb_backend/management/commands/get_encrypted_fields_map.py
Outdated
Show resolved
Hide resolved
django_mongodb_backend/management/commands/get_encrypted_fields_map.py
Outdated
Show resolved
Hide resolved
django_mongodb_backend/management/commands/get_encrypted_fields_map.py
Outdated
Show resolved
Hide resolved
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
a697cae to
a2d86ad
Compare
9748263 to
9f9507d
Compare
django_mongodb_backend/management/commands/showencryptedfieldsmap.py
Outdated
Show resolved
Hide resolved
| - name: Verify MongoDB installation | ||
| run: | | ||
| mongosh --eval 'db.runCommand({ connectionStatus: 1 })' | ||
| - name: Verify mongocryptd is running | ||
| run: | | ||
| pgrep mongocryptd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was your thinking here? Were these steps copied from another project? Wouldn't the start server / mongocryptd commands fail with a suitable exit code if they didn't start?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
POC developed here: https://github.com/aclark4life/test-supercharge-action. The verify steps can probably come out.
| - name: Start local Atlas | ||
| working-directory: . | ||
| run: bash .github/workflows/start_local_atlas.sh mongodb/mongodb-atlas-local:7 | ||
| run: bash .github/workflows/start_local_atlas.sh mongodb/mongodb-atlas-local:8.0.15 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we should have a separate job for Atlas 8 so we still test with Atlas 7, although it's useful to keep it like this for now so we can see the modifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we care about 7 outside of QE? If not, let's just test 8. Still thinking about going the other direction and supporting query, queryPreview, etc. But in this one case I think it's reasonable to cling to non-preview and versions that support query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. In fact, based on the driver policy, we have to support MongoDB 6 until July 2028. I've argued that since Django 5.2 is supported until April 2028, we could make Django 5.2 the last version to support MongoDB 6. This is similar to Django's version support for its built in databases. In any case, it would be nice to finalize and document a MongoDB version support policy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK in that case to remove as much ambiguity as possible, and to support as much MongoDB as we can, how about if we go back to 7 for QE and document rangePreview. I haven't thought about the MongoDB support policy in the context of this project, but what you propose sounds fine. Maybe open a PR to the docs with that policy defined so we can discuss there and merge.
| mongosh --version | ||
| - name: Install mongocryptd from Enterprise tarball | ||
| run: | | ||
| curl -sSL -o mongodb-enterprise.tgz "https://downloads.mongodb.com/linux/mongodb-linux-x86_64-enterprise-ubuntu2204-8.0.15.tgz" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a variable for 8.0.15 so it's not hardcoded in so many places? (I have to research to answer.) Same for ubuntu2204, probably. This action uses ubuntu-latest which is 24.04 I believe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Queryable Encryption can be used with MongoDB replica sets or sharded | ||
| clusters running version 8.0 or later. Standalone instances are not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users may wonder why it says 8.0 when the MongoDB documentation says 7.0. Even if we only test with 8 because of the range/rangePreview issue, I think our implementation should work on 7.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but I'm still inclined to steer away from Preview and only declare support when a query type makes it out of preview.
| "OPTIONS": { | ||
| "auto_encryption_opts": AutoEncryptionOpts( | ||
| key_vault_namespace="encryption.__keyVault", | ||
| kms_providers={"local": {"key": os.urandom(96)}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using os.urandom(96) generates a different key each time Python starts which is problematic in a local project, except when running tests. Need to explain this or use a different approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an admonition about it here: https://django-mongodb-backend--329.org.readthedocs.build/en/329/howto/queryable-encryption/#configuring-the-databases-setting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point here (as we've discussed) is that it's not appropriate to use a random key that changes each time the web server restarts, a management command, etc. Should we hardcode a particular bytestring that os.urandom(96) generates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b0f79ef to
f275f0a
Compare
c0b88bb to
a6d0bef
Compare
|
@timgraham FYI mongocryptd POC updated to include crypt shared: https://github.com/aclark4life/test-supercharge-action/actions/runs/19072288362 |
7cfe63c to
74feef6
Compare
| "auto_encryption_opts": AutoEncryptionOpts( | ||
| key_vault_namespace="djangotests_encrypted.__keyVault", | ||
| kms_providers={"local": {"key": os.urandom(96)}}, | ||
| crypt_shared_lib_path=os.environ["GITHUB_WORKSPACE"] + "/lib/mongo_crypt_v1.so", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest just using the POC:
# 🧩 Install Mongo Crypt Shared Library
- name: Install Mongo Crypt Shared Library
run: |
curl -sSL -o mongo_crypt_shared_v1.tgz https://downloads.mongodb.com/linux/mongo_crypt_shared_v1-linux-x86_64-enterprise-ubuntu2404-8.2.1.tgz
tar -xzf mongo_crypt_shared_v1.tgz
sudo mkdir -p /usr/local/lib/mongo_crypt_v1
sudo cp lib/mongo_crypt_v1.so /usr/local/lib/mongo_crypt_v1/
echo "✅ Installed Mongo Crypt Shared Library to /usr/local/lib/mongo_crypt_v1"
| - name: Verify mongocryptd is running | ||
| run: | | ||
| pgrep mongocryptd | ||
| wget https://downloads.mongodb.com/linux/mongo_crypt_shared_v1-linux-aarch64-enterprise-ubuntu2404-8.0.15.tgz |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want to use 8.2.1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MongoDB 8.2 is a rapid release with EOL March 30, 2026. Isn't it better to test with MongoDB 8.0 which enterprise are likely to be using?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine, there was a test failure that "failed less" (libmongocrypt wire version error vs . aggregation pipeline "let" command error) when I upgraded but IIUC those tests are expected to fail, so when those failures are asserted then 8.0 is probably OK (or 7.0 if you want to support "preview" query types or maybe add a matrix as you suggested somewhere.)
ec1fe5c to
cb555b5
Compare
django_mongodb_backend/schema.py
Outdated
| f"Encrypted fields found but DATABASES['{self.connection.alias}']['OPTIONS'] " | ||
| "is missing auto_encryption_opts." | ||
| "Encrypted fields found, but `auto_encryption_opts` " | ||
| "setting not found in `OPTIONS` setting for " | ||
| f"'{self.connection.alias}' database connection." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the old message could be improved by adding quotes around "auto_encryption_opts" and calling it a parameter. Would that address your concern? I wouldn't call it a setting. OPTIONS is described in Django's documentation as "Extra parameters to use when connecting to the database."
Referencing DATABASES['{self.connection.alias}']['OPTIONS'] in error messages has a precedent https://github.com/django/django/blob/2501958b5127020411df6271445ccfd0906df70e/django/db/backends/sqlite3/base.py#L189-L193
Incidentally, I've coincidentally added a test for this message in a local commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine. We should print the alias though, because the name will indicate "default" may not be the encrypted database.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not sure I understand what you mean by printing the alias (it does appear in both the old message and your suggested message as far as I can tell), but does something like this address your concern: "Tried to create model {app_label.Model} in '{self.connection.alias}' database. The model has encrypted fields but DATABASES['{self.connection.alias}']['OPTIONS'] is missing the "auto_encryption_opts" parameter. If this model should not be created in this database, add or fix a database router."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works, thanks. I was saying that the f" syntax wasn't working and the error message contained self.connection.alias instead of default.
6dc9766 to
c1cfc25
Compare
Previous attempts and additional context here:
INTPYTHON-527 Add Queryable Encryption config #318
INTPYTHON-527 Add queryable encryption support #319
INTPYTHON-527 Add Queryable Encryption support #323
Add test for "Encrypted fields found" error (ensure this exception still happens)
Add check for model schema not matching encrypted fields
Document key_vault_namespace must be encrypted db
Document that fields within EmbeddedModelArrayField can't be encrypted
Document workflow: