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.

      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:
              2 Start watching this issue

                Created:
                Updated: