For AI agents: a documentation index is available at https://www.mongodb.com/ja-jp/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.
Docs Menu

Configure Queryable Encryption

In this guide, you can learn how to use the EF Core Provider to encrypt specific document fields by using Queryable Encryption (QE).

Queryable Encryption encrypts sensitive document fields at the application layer before writing data to MongoDB, while still allowing your application to query those fields. Only applications that have access to your encryption keys can read the plaintext data. If an attacker gains access to the database, they can only see only ciphertext because they lack access to the encryption keys.

For example, you can use Queryable Encryption to encrypt fields that contain:

  • Social Security numbers

  • Credit card numbers

  • Health or medical information

  • Financial information

  • Any other sensitive or personally identifiable information

The EF Core Provider supports Queryable Encryption through a fluent model API. You configure which entity properties to encrypt by using the OnModelCreating() method, and the provider handles encryption automatically when reading and writing data.

Before configuring Queryable Encryption with the EF Core Provider, ensure that you have the following:

  • A MongoDB Enterprise or MongoDB Atlas cluster running MongoDB 7.0 or later.

  • Access to a Key Management Service (KMS). Supported KMS providers include Amazon Web Services, Azure, Google Cloud Platform, the Key Management Interoperability Protocol (KMIP), and local key providers.

  • The Automatic Encryption Shared Library (CRYPT_SHARED) or mongocryptd installed in your environment. To learn how to install the shared library, see Install a Query Analysis Component in the MongoDB Server documentation.

The following sections describe how to configure encryption options on your context and mark entity properties for encryption in your model:

Before you configure any context that uses Queryable Encryption, you must register the automatic encryption provider once for your application by running the following code:

MongoClientSettings.Extensions.AddAutoEncryption();

Then, create a MongoOptionsExtension instance and chain the following methods before passing the instance to the UseMongoDB() method:

  • WithKmsProviders() — specifies your KMS provider and credentials.

  • WithKeyVaultNamespace() — specifies the collection used to store data encryption keys.

  • WithCryptProvider() — specifies the encryption library to use and its path.

The following example configures a local KMS provider for development use:

var kmsProviders = new Dictionary<
string, IReadOnlyDictionary<string, object>>
{
{
"local",
new Dictionary<string, object>
{
{ "key", localMasterKey }
}
}
};
var keyVaultNamespace = CollectionNamespace.FromFullName(
"encryption.__keyVault");
var mongoOptions = new MongoOptionsExtension()
.WithConnectionString(connectionString)
.WithDatabaseName("myDatabase")
.WithKmsProviders(kmsProviders)
.WithKeyVaultNamespace(keyVaultNamespace)
.WithCryptProvider(
CryptProvider.AutoEncryptSharedLibrary,
Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH"));
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>()
.UseMongoDB(mongoOptions);

To use mongocryptd instead of the shared library, pass CryptProvider.Mongocryptd and the path to the mongocryptd binary to the WithCryptProvider() method.

Warning

Do not use a local KMS provider in production. Without a remote KMS, you risk unauthorized access to the master key or permanent loss of the key needed to decrypt your data.

In the OnModelCreating() method, call an encryption method on each property you want to encrypt. The method you choose controls which query types are available on that field:

Method
Query support
Notes

IsEncrypted(dataKeyId)

None

Encrypts the field without query support. Use for fields you store but never filter on directly.

IsEncryptedForEquality(dataKeyId)

Equality (==)

Not available for Decimal128, Double, Document, or Array BSON storage types.

IsEncryptedForRange(min, max, dataKeyId)

Range (>, <, >=, <=)

Supported only for DateTime, Decimal128, Double, Int32, and Int64 BSON storage types.

To encrypt an owned entity rather than a scalar property, call IsEncrypted(dataKeyId) on the OwnedNavigationBuilder or OwnershipBuilder returned from OwnsOne() or OwnsMany().

For a complete example that uses the preceding methods, see the Example: Encrypt Patient Data section.

The following Patient entity defines the document model, with the SSN and DateOfBirth fields to encrypt:

public class Patient
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public string SSN { get; set; } = null!;
public DateTime DateOfBirth { get; set; }
}

The following HospitalContext marks those fields for encryption in the OnModelCreating() method. SSN is encrypted without query support, and DateOfBirth is encrypted with range query support. The constructor accepts the IDs of two data encryption keys, which you create in your key vault before you initialize the context:

public class HospitalContext : DbContext
{
public DbSet<Patient> Patients { get; set; } = null!;
private readonly Guid _ssnDataKeyId;
private readonly Guid _dobDataKeyId;
public HospitalContext(
DbContextOptions options,
Guid ssnDataKeyId,
Guid dobDataKeyId)
: base(options)
{
_ssnDataKeyId = ssnDataKeyId;
_dobDataKeyId = dobDataKeyId;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Patient>(entity =>
{
entity.ToCollection("patients");
entity.Property(p => p.SSN)
.IsEncrypted(_ssnDataKeyId);
entity.Property(p => p.DateOfBirth)
.IsEncryptedForRange(
new DateTime(1900, 1, 1),
new DateTime(2100, 12, 31),
_dobDataKeyId);
});
}
}

The following code configures the encryption options, instantiates the HospitalContext with the data key IDs, and inserts and queries a Patient document:

var mongoOptions = new MongoOptionsExtension()
.WithConnectionString("<connection string URI>")
.WithDatabaseName("hospitalDb")
.WithKmsProviders(kmsProviders)
.WithKeyVaultNamespace(keyVaultNamespace)
.WithCryptProvider(
CryptProvider.AutoEncryptSharedLibrary,
Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH"));
using var context = new HospitalContext(
new DbContextOptionsBuilder<HospitalContext>()
.UseMongoDB(mongoOptions)
.Options,
ssnDataKeyId,
dobDataKeyId);
context.Database.EnsureCreated();
context.Patients.Add(new Patient
{
Name = "John Doe",
SSN = "123-45-6789",
DateOfBirth = new DateTime(1985, 6, 15)
});
context.SaveChanges();
var results = context.Patients
.Where(p => p.DateOfBirth > new DateTime(1980, 1, 1))
.ToList();

By default, the EF Core Provider applies your field encryption configuration only to the client. Client-only encryption is appropriate during development, when your encryption schema may still be evolving.

For production deployments, register the encryption schema on the server when you create the collection. Once the server holds the schema, it enforces encryption independently of the client configuration, protecting against accidental plaintext writes from misconfigured clients. After registering the schema on the server, you cannot change which fields are encrypted without recreating the collection.

To create a collection with a server-side schema, pass your context's Model to QueryableEncryptionSchemaGenerator.GenerateSchemas(). Then, pass the result to the CreateCollection() method, as shown in the following example:

var encryptedSchemas =
QueryableEncryptionSchemaGenerator.GenerateSchemas(
context.Model);
using var client = new MongoClient(
"<connection string URI>");
var database = client.GetDatabase("hospitalDb");
foreach (var entityType in context.Model
.GetEntityTypes()
.Where(e => e.IsDocumentRoot()))
{
var collectionName = entityType.GetCollectionName();
if (encryptedSchemas.TryGetValue(
collectionName, out var schema))
{
database.CreateCollection(
collectionName,
new CreateCollectionOptions
{
EncryptedFields = schema
});
}
}
context.Database.EnsureCreated();

After the encrypted collection exists on the server, you can configure new context instances to use only the server schema. Set QueryableEncryptionSchemaMode.Ignore on the MongoOptionsExtension, as shown in the following example:

var mongoOptions = new MongoOptionsExtension()
.WithConnectionString("<connection string URI>")
.WithDatabaseName("hospitalDb")
.WithKmsProviders(kmsProviders)
.WithKeyVaultNamespace(keyVaultNamespace)
.WithCryptProvider(
CryptProvider.AutoEncryptSharedLibrary,
Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH"))
.WithQueryableEncryptionSchemaMode(
QueryableEncryptionSchemaMode.Ignore);

In Ignore mode, any IsEncrypted configuration in the OnModelCreating() method has no effect on encryption. The server schema controls which fields are encrypted.

To learn more about Queryable Encryption, see the Queryable Encryption and Queryable Encryption Use Cases sections in the MongoDB Server manual.

For complete implementation details, see the EF Core Provider API documentation.