Get explicit encryption parameters from schema

XMLWordPrintableJSON

    • Type: New Feature
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Component/s: Client Side Encryption
    • None
    • Needed

      Summary

      Add explicit encryption API that finds parameters from the encryption schema.

      Motivation

      ClientEncryption.encrypt requires a caller to pass all relevant encryption parameters to exactly match the server-side schema. Otherwise, the user risks quiet incorrect results: Here is a runnable example. Relevant snippet:

      # Create the collection with contention_factor=1
      coll = db.create_collection("coll", encryptedFields=encrypted_fields)
      
      # Insert with contention_factor=2
      payload = client_encryption.encrypt(
          "foo", Algorithm.INDEXED, key_id, contention_factor=2
      )
      coll.insert_one({"encrypted": payload})  # No error!
      
      # Find with contention_factor=1
      find_payload = client_encryption.encrypt(
          "foo",
          Algorithm.INDEXED,
          key_id,
          query_type=QueryType.EQUALITY,
          contention_factor=1,
      )
      
      doc = coll.find_one({"encrypted": find_payload})
      print(f"Got document: {doc}") # Sometimes 'None'!
      

      This may be partially addressed by SERVER-91887, which requests the server reject payloads generated with mismatched parameters.

      With the addition of range and text algorithms, more parameters are required:

      range_payload = client_encryption.encrypt(
          12.0, Algorithm.RANGE, key_id, contention_factor=1, range_opts=RangeOpts(min=0.0, max=200.0, sparsity=1, trim_factor=1, precision=2)
      )
      

      ClientEncryption does not currently have access to the encryption schema. One idea for an API improvement could be to add an encrypt helper to MongoCollection:

      encrypted_client = MongoClient(auto_encryption_opts=aeo)
      coll = encrypted_client["db"]["coll"]
      # Explicitly encrypt "foo" to insert on field "secret".
      payload = coll.encrypt("foo", field="secret", type="insert")
      coll.insert_one ({"secret": payload })
      

      Pros:

      • Simpler user API.
      • Less error-prone.
      • Cheaper to implement future algorithms for explicit encryption (would likely not require new options).

      Cons:

      • A significant API change. May motivate deprecating encrypt|encrypt_expression|decrypt on ClientEncryption.

      Who is the affected end user?

      Users of CSFLE / QE using explicit encryption. Explicit encryption is the only option when not using mongocryptd/crypt_shared. mongocryptd/crypt_shared require using Atlas or having an enterprise license.

      Discussion during the DBX off-site in 2025 suggested an opinion that explicit encryption is not commonly used. Instead it serves as an escape hatch and a way to audit CSFLE / QE without enterprise or Atlas. However, explicit encryption may be a first-touch experience for users. It is taught in the QE course M054.

      How does this affect the end user?

      Confused.

      How likely is it that this problem or use case will occur?

      I expect likely for anyone using explicit encryption.

      If the problem does occur, what are the consequences and how severe are they?

      The usability difficulties might deter users from trying QE/CSFLE. Passing incorrect parameters results in quiet mismatches.

      Is this issue urgent?

      No.

      Is this ticket required by a downstream team?

      No?

      Is this ticket only for tests?

      No.

      Acceptance Criteria

      TBD. I expect this project (if acceptable) would need a scope document.

            Assignee:
            Unassigned
            Reporter:
            Kevin Albertson
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: