> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  other tabs: csharp-v3, csharp-v2
-->

# Use Automatic Client-Side Field Level Encryption with GCP

## Overview

This guide shows you how to build a Client-Side Field Level Encryption (CSFLE)-enabled application using Google Cloud Key Management Service.

After you complete the steps in this guide, you should have:

- A CMK (Customer Master Key) hosted on Google Cloud Key Management Service.

- A client application that inserts documents with encrypted fields using your CMK (Customer Master Key).

## Before You Get Started

Before you begin this tutorial, complete the following prerequisite steps:

1. Download the Automatic Encryption Shared Library from the [MongoDB Download Center](https://www.mongodb.com/try/download/enterprise?tck=docs). Navigate to the MongoDB Enterprise Server Download section and select the follow options:

   - In the Version dropdown, select the version marked as `"current"`.

   - In the Platform dropdown, select your platform.

   - In the Package dropdown, select `crypt_shared`.

   Extract the archive and save the path to the shared library file for future use.

   **Note: Query Analysis Component**

   The Automatic Encryption Shared Library is a preferred alternative to `mongocryptd` and does not require spawning a new process to perform automatic encryption. This tutorial uses the Automatic Encryption Shared Library.

2. Configure a MongoDB Atlas cluster or a local replica set deployment, and save your connection string for future use. To learn more, see the [Get Started](https://www.mongodb.com/docs/get-started.md#std-label-unified-get-started) tutorial.

Throughout this guide, code examples use placeholder text. Before you run the examples, substitute your own values for these placeholders.

For example:

```go
dek_id := "<Your Base64 DEK ID>"
```

You would replace everything between quotes with your DEK (Data Encryption Key) ID.

```go
dek_id := "abc123"
```

### Full Application Code

To see the complete code for the sample application, select your programming language in the language selector.

[Complete Java Application](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/java/gcp/reader/)

[Complete Node.js Application](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/node/gcp/reader/)

[Complete Python Application](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/python/gcp/reader/)

[Complete C# Application](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/dotnet/gcp/reader/CSFLE/)

[Complete Go Application](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/go/gcp/reader/)

## Set Up the KMS

1. Register a GCP Service Account

   Register or log into your existing account on [Google Cloud](https://cloud.google.com)

   Create a service account for your project

   To create a service account on Google Cloud, follow the [Creating a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) guide in Google's official documentation.

   Add a service account key

   To add a service account key on Google Cloud, follow the [Managing service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) guide in Google's official documentation.

   **Important:**

   When creating your service account key, you receive a one-time download of the private key information. Unless you are using an attached service account, make sure to download this file in either the PKCS12 or JSON format for use later in this tutorial.

2. Create a GCP Customer Master Key

   Create a new Customer Master Key

   Create a key ring and a symmetric key by following the [Create a key](https://cloud.google.com/kms/docs/creating-keys) guide from Google's official documentation.

   This key is your Customer Master Key (CMK (Customer Master Key)).

   Record the following details of your CMK (Customer Master Key) for use in a future step of this tutorial.

   | Field | Required | Description |
   | --- | --- | --- |
   | key_name | Yes | Identifier for the CMK (Customer Master Key). |
   | key_ring | Yes | Identifier for the group of keys your key belongs to. |
   | key_version | No | The version of the named key. |
   | location | Yes | Region specified for your key. |
   | endpoint | No | The host and optional port of the Google Cloud KMS. The default value is `cloudkms.googleapis.com`. |

1) Register a GCP Service Account

   Register or log into your existing account on [Google Cloud](https://cloud.google.com)

   Create a service account for your project

   To create a service account on Google Cloud, follow the [Creating a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) guide in Google's official documentation.

   Add a service account key

   To add a service account key on Google Cloud, follow the [Managing service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) guide in Google's official documentation.

   **Important:**

   When creating your service account key, you receive a one-time download of the private key information. Make sure to download this file in either the PKCS12 or JSON format for use later in this tutorial.

2) Create a GCP Customer Master Key

   Create a new Customer Master Key

   Create a key ring and a symmetric key by following the [Create a key](https://cloud.google.com/kms/docs/creating-keys) guide from Google's official documentation.

   This key is your Customer Master Key (CMK (Customer Master Key)).

   Record the following details of your CMK (Customer Master Key) for use in a future step of this tutorial.

   | Field | Required | Description |
   | --- | --- | --- |
   | key_name | Yes | Identifier for the CMK (Customer Master Key). |
   | key_ring | Yes | Identifier for the group of keys your key belongs to. |
   | key_version | No | The version of the named key. |
   | location | Yes | Region specified for your key. |
   | endpoint | No | The host and optional port of the Google Cloud KMS. The default value is `cloudkms.googleapis.com`. |

1. Register a GCP Service Account

   Register or log into your existing account on [Google Cloud](https://cloud.google.com)

   Create a service account for your project

   To create a service account on Google Cloud, follow the [Creating a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) guide in Google's official documentation.

   Add a service account key

   To add a service account key on Google Cloud, follow the [Managing service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) guide in Google's official documentation.

   **Important:**

   When creating your service account key, you receive a one-time download of the private key information. Make sure to download this file in either the PKCS12 or JSON format for use later in this tutorial.

2. Create a GCP Customer Master Key

   Create a new Customer Master Key

   Create a key ring and a symmetric key by following the [Create a key](https://cloud.google.com/kms/docs/creating-keys) guide from Google's official documentation.

   This key is your Customer Master Key (CMK (Customer Master Key)).

   Record the following details of your CMK (Customer Master Key) for use in a future step of this tutorial.

   | Field | Required | Description |
   | --- | --- | --- |
   | key_name | Yes | Identifier for the CMK (Customer Master Key). |
   | key_ring | Yes | Identifier for the group of keys your key belongs to. |
   | key_version | No | The version of the named key. |
   | location | Yes | Region specified for your key. |
   | endpoint | No | The host and optional port of the Google Cloud KMS. The default value is `cloudkms.googleapis.com`. |

1) Register a GCP Service Account

   Register or log into your existing account on [Google Cloud](https://cloud.google.com)

   Create a service account for your project

   To create a service account on Google Cloud, follow the [Creating a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) guide in Google's official documentation.

   Add a service account key

   To add a service account key on Google Cloud, follow the [Managing service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) guide in Google's official documentation.

   **Important:**

   When creating your service account key, you receive a one-time download of the private key information. Make sure to download this file in either the PKCS12 or JSON format for use later in this tutorial.

2) Create a GCP Customer Master Key

   Create a new Customer Master Key

   Create a key ring and a symmetric key by following the [Create a key](https://cloud.google.com/kms/docs/creating-keys) guide from Google's official documentation.

   This key is your Customer Master Key (CMK (Customer Master Key)).

   Record the following details of your CMK (Customer Master Key) for use in a future step of this tutorial.

   | Field | Required | Description |
   | --- | --- | --- |
   | key_name | Yes | Identifier for the CMK (Customer Master Key). |
   | key_ring | Yes | Identifier for the group of keys your key belongs to. |
   | key_version | No | The version of the named key. |
   | location | Yes | Region specified for your key. |
   | endpoint | No | The host and optional port of the Google Cloud KMS. The default value is `cloudkms.googleapis.com`. |

1. Register a GCP Service Account

   Register or log into your existing account on [Google Cloud](https://cloud.google.com)

   Create a service account for your project

   To create a service account on Google Cloud, follow the [Creating a service account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating) guide in Google's official documentation.

   Add a service account key

   To add a service account key on Google Cloud, follow the [Managing service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) guide in Google's official documentation.

   **Important:**

   When creating your service account key, you receive a one-time download of the private key information. Make sure to download this file in either the PKCS12 or JSON format for use later in this tutorial.

2. Create a GCP Customer Master Key

   Create a new Customer Master Key

   Create a key ring and a symmetric key by following the [Create a key](https://cloud.google.com/kms/docs/creating-keys) guide from Google's official documentation.

   This key is your Customer Master Key (CMK (Customer Master Key)).

   Record the following details of your CMK (Customer Master Key) for use in a future step of this tutorial.

   | Field | Required | Description |
   | --- | --- | --- |
   | key_name | Yes | Identifier for the CMK (Customer Master Key). |
   | key_ring | Yes | Identifier for the group of keys your key belongs to. |
   | key_version | No | The version of the named key. |
   | location | Yes | Region specified for your key. |
   | endpoint | No | The host and optional port of the Google Cloud KMS. The default value is `cloudkms.googleapis.com`. |

## Create the Application

1. Create a Unique Index on your Key Vault collection

   Create a unique index on the `keyAltNames` field in your `encryption.__keyVault` namespace.

   ```java
   String connectionString = "<Your MongoDB URI>";
   String keyVaultDb = "encryption";
   String keyVaultColl = "__keyVault";
   String keyVaultNamespace = keyVaultDb + "." + keyVaultColl;
   MongoClient keyVaultClient = MongoClients.create(connectionString);

   // Drop the Key Vault Collection in case you created this collection
   // in a previous run of this application.
   keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl).drop();
   // Drop the database storing your encrypted fields as all
   // the DEKs encrypting those fields were deleted in the preceding line.
   keyVaultClient.getDatabase("medicalRecords").getCollection("patients").drop();


   MongoCollection keyVaultCollection = keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl);
   IndexOptions indexOpts = new IndexOptions().partialFilterExpression(new BsonDocument("keyAltNames", new BsonDocument("$exists", new BsonBoolean(true) ))).unique(true);
   keyVaultCollection.createIndex(new BsonDocument("keyAltNames", new BsonInt32(1)), indexOpts);
   keyVaultClient.close();
   ```

2. Create a Data Encryption Key

   Add your GCP KMS Credentials

   **Tip: Attached Service Account**

   If you are using an [attached service account](https://cloud.google.com/iam/docs/impersonating-service-accounts#binding-to-resources), you can allow it to automatically authenticate it to your GCP KMS.

   To automatically authenticate, assign an empty map instead of one that contains your GCP credentials, as shown in the following code:

   ```java
   String kmsProvider = "gcp";
   Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
   Map<String, Object> providerDetails = new HashMap<>();
   kmsProviders.put(kmsProvider, providerDetails);
   ```

   Proceed to the next step in the guide after adding this code.

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```java
   String kmsProvider = "gcp";
   Map<String, Map<String, Object>> kmsProviderDetails = new HashMap<String, Map<String, Object>>();
   Map<String, Object> providerDetails = new HashMap<>();
   providerDetails.put("email", "<Your GCP Email Address>");
   providerDetails.put("privateKey", "<Your GCP Private Key>");
   kmsProviderDetails.put(kmsProvider, providerDetails);
   ```

   You can also provide a custom name for your KMS provider by passing in a string that includes the name of the KMS provider, followed by a colon and the custom name. Providing a unique name for a KMS provider allows you to specify multiple KMS providers of the same type.

   For example, you can name your GCP KMS provider "my\_gcp\_provider" in your KMS credentials variable as shown in the following code:

   ```java
   Map<String, Object> kmsProviderDetails = new HashMap<>();
   kmsProviderDetails.put("email", getEnv("GCP_EMAIL")); // Your GCP email
   kmsProviderDetails.put("privateKey", getEnv("GCP_PRIVATE_KEY")); // Your GCP private key

   Map<String, Map<String, Object>> kmsProviderCredentials = new HashMap<String, Map<String, Object>>();
   kmsProviderCredentials.put("gcp:my_gcp_provider", kmsProviderDetails);
   ```

   **Tip:**

   You saved a file containing your service account key credentials in the [Create a GCP Service Account](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-register-account) step of this guide.

   If you downloaded your credentials in JSON format, you can use the following command to extract the value of your private key, substituting `<credentials-filename>` with the name of your credentials file. The following command requires that you install [OpenSSL:](https://docs.openssl.org/master/)

   ```text
   cat <credentials-filename> | jq -r .private_key | openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER | base64
   ```

   If you downloaded your credentials in PKCS12 format, you need to specify your GCP service account import password and to add a PEM pass phrase to access the key when accessing it using the following command, substituting `<credentials-filename>` with the name of your credentials file:

   ```text
   openssl pkcs12 -info -in <credentials-filename>
   ```

   1. Add Your Key Information

      **Tip:**

      You recorded your Customer Master Key details in the [Create a Customer Master Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-create-master-key) step of this guide.

      ```java
      BsonDocument masterKeyProperties = new BsonDocument();
      masterKeyProperties.put("provider", new BsonString(kmsProvider));
      masterKeyProperties.put("projectId", new BsonString("<Your GCP Project ID>"));
      masterKeyProperties.put("location", new BsonString("<Your GCP Key Location>"));
      masterKeyProperties.put("keyRing", new BsonString("<Your GCP Key Ring>"));
      masterKeyProperties.put("keyName", new BsonString("<Your GCP Key Name>"));
      ```

   2. Generate your Data Encryption Key

      Generate your Data Encryption Key using the variables declared in [step one](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-index) of this tutorial.

      ```java
      ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
              .keyVaultMongoClientSettings(MongoClientSettings.builder()
                      .applyConnectionString(new ConnectionString(connectionString))
                      .build())
              .keyVaultNamespace(keyVaultNamespace)
              .kmsProviders(kmsProviderDetails)
              .build();

      MongoClient regularClient = MongoClients.create(connectionString);

      ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
      BsonBinary dataKeyId = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions().masterKey(masterKeyProperties));
      String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
      System.out.println("DataKeyId [base64]: " + base64DataKeyId);
      clientEncryption.close();
      ```

   **Tip: Learn More**

   To view a diagram showing how your client application creates your Data Encryption Key when using an Google Cloud Key Management Service, see [Architecture.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-fundamentals-kms-providers-gcp-architecture)

   To learn more about the options for creating a Data Encryption Key encrypted with a Customer Master Key hosted in Google Cloud Key Management Service, see [kmsProviders Object](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp) and [dataKeyOpts Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-datakeyopts-gcp)

   To view the complete code for making a Data Encryption Key, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/java/gcp/reader/src/main/java/com/mongodb/csfle/MakeDataKey.java)

3. Configure the MongoClient

   **Tip:**

   Follow the remaining steps in this tutorial in a separate file from the one created in the previous steps.

   To view the complete code for this file, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/java/gcp/reader/src/main/java/com/mongodb/csfle/InsertEncryptedDocument.java)

   Specify the Key Vault Collection Namespace

   Specify `encryption.__keyVault` as the Key Vault collection namespace.

   ```java
   String keyVaultNamespace = "encryption.__keyVault";
   ```

   Specify your Cloud Account Credentials

   **Tip: Attached Service Account**

   If you are using an [attached service account](https://cloud.google.com/iam/docs/impersonating-service-accounts#binding-to-resources), you can allow it to automatically authenticate it to your GCP KMS.

   To automatically authenticate, assign an empty map instead of one that contains your GCP credentials, as shown in the following code:

   ```java
   String kmsProvider = "gcp";
   Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
   Map<String, Object> providerDetails = new HashMap<>();
   kmsProviders.put(kmsProvider, providerDetails);
   ```

   Proceed to the next step in the guide after adding this code.

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```java
   String kmsProvider = "gcp";
   Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
   Map<String, Object> providerDetails = new HashMap<>();
   providerDetails.put("email", "<Your GCP Email Address>");
   providerDetails.put("privateKey", "<Your GCP Private Key>");
   kmsProviders.put(kmsProvider, providerDetails);
   ```

   Create an Encryption Schema For Your Collection

   **Tip: Add Your Data Encryption Key Base64 ID**

   Make sure to update the following code to include your Base64 DEK (Data Encryption Key) ID. You received this value in the [Generate your Data Encryption Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-dek) step of this guide.

   ```java
   String dekId = "<paste-base-64-encoded-data-encryption-key-id>>";
   Document jsonSchema = new Document().append("bsonType", "object").append("encryptMetadata",
           new Document().append("keyId", new ArrayList<>((Arrays.asList(new Document().append("$binary", new Document()
                   .append("base64", dekId)
                   .append("subType", "04")))))))
           .append("properties", new Document()
                   .append("ssn", new Document().append("encrypt", new Document()
                           .append("bsonType", "int")
                           .append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")))
                   .append("bloodType", new Document().append("encrypt", new Document()
                           .append("bsonType", "string")
                           .append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random")))
                   .append("medicalRecords", new Document().append("encrypt", new Document()
                           .append("bsonType", "array")
                           .append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random")))
                   .append("insurance", new Document()
                           .append("bsonType", "object")
                           .append("properties",
                                   new Document().append("policyNumber", new Document().append("encrypt", new Document()
                                           .append("bsonType", "int")
                                           .append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"))))));
   HashMap<String, BsonDocument> schemaMap = new HashMap<String, BsonDocument>();
   schemaMap.put("medicalRecords.patients", BsonDocument.parse(jsonSchema.toJson()));
   ```

   Specify the Location of the Automatic Encryption Shared Library

   ```java
   Map<String, Object> extraOptions = new HashMap<String, Object>();
   extraOptions.put("cryptSharedLibPath", "<Full path to your Automatic Encryption Shared Library>"));
   ```

   **Note: Automatic Encryption Options**

   The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.

   To learn more about the Automatic Encryption Shared Library, see the [Install and Configure a CSFLE Query Analysis Component](https://www.mongodb.com/docs/manual/core/csfle/reference/install-library.md#std-label-csfle-reference-shared-library) page.

   Create the MongoClient

   Instantiate a MongoDB client object with the following automatic encryption settings that use the variables declared in the previous steps:

   ```java
   MongoClientSettings clientSettings = MongoClientSettings.builder()
       .applyConnectionString(new ConnectionString(connectionString))
       .autoEncryptionSettings(AutoEncryptionSettings.builder()
           .keyVaultNamespace(keyVaultNamespace)
           .kmsProviders(kmsProviders)
           .schemaMap(schemaMap)
           .extraOptions(extraOptions)
           .build())
       .build();

   MongoClient mongoClientSecure = MongoClients.create(clientSettings);
   ```

4. Insert a Document with Encrypted Fields

   Use your CSFLE-enabled `MongoClient` instance to insert a document with encrypted fields into the `medicalRecords.patients` namespace using the following code snippet:

   ```java
   ArrayList<Document> medicalRecords = new ArrayList<>();
   medicalRecords.add(new Document().append("weight", "180"));
   medicalRecords.add(new Document().append("bloodPressure", "120/80"));

   Document insurance = new Document()
   .append("policyNumber", 123142)
   .append("provider",  "MaestCare");

   Document patient = new Document()
       .append("name", "Jon Doe")
       .append("ssn", 241014209)
       .append("bloodType", "AB+")
       .append("medicalRecords", medicalRecords)
       .append("insurance", insurance);
   mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).insertOne(patient);
   ```

   When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:

   ```json
   {
     "_id": { "$oid": "<_id of your document>" },
     "name": "Jon Doe",
     "ssn": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "bloodType": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "medicalRecords": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "insurance": {
       "provider": "MaestCare",
       "policyNumber": {
         "$binary": "<cipher-text>",
         "$type": "6"
       }
     }
   }

   ```

   To view the complete code for inserting a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/java/gcp/reader/src/main/java/com/mongodb/csfle/InsertEncryptedDocument.java)

5. Retrieve Your Document with Encrypted Fields

   Retrieve the document with encrypted fields you inserted in the [Insert a Document with Encrypted Fields](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-insert) step of this guide.

   To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.

   ```java
   System.out.println("Finding a document with regular (non-encrypted) client.");
   Document docRegular = mongoClientRegular.getDatabase(recordsDb).getCollection(recordsColl).find(eq("name", "Jon Doe")).first();
   System.out.println(docRegular.toJson());

   System.out.println("Finding a document with encrypted client");
   Document docSecure = mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).find(eq("name", "Jon Doe")).first();
   System.out.println(docSecure.toJson());
   ```

   The output of the preceding code snippet should look like this:

   ```json
   Finding a document with regular (non-encrypted) client.

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
     bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
     'key-id': 'demo-data-key',
     medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
     insurance: {
       policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
       provider: 'MaestCare'
     }
   }

   Finding a document with encrypted client

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: 241014209,
     bloodType: 'AB+',
     'key-id': 'demo-data-key',
     medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
     insurance: { policyNumber: 123142, provider: 'MaestCare' }
   }

   ```

   To view the complete code for finding a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/java/gcp/reader/src/main/java/com/mongodb/csfle/InsertEncryptedDocument.java)

1) Create a Unique Index on your Key Vault collection

   Create a unique index on the `keyAltNames` field in your `encryption.__keyVault` namespace.

   ```javascript
   const uri = "<Your Connection String>";
   const keyVaultDatabase = "encryption";
   const keyVaultCollection = "__keyVault";
   const keyVaultNamespace = `${keyVaultDatabase}.${keyVaultCollection}`;
   const keyVaultClient = new MongoClient(uri);
   await keyVaultClient.connect();
   const keyVaultDB = keyVaultClient.db(keyVaultDatabase);
   // Drop the Key Vault Collection in case you created this collection
   // in a previous run of this application.
   await keyVaultDB.dropDatabase();
   // Drop the database storing your encrypted fields as all
   // the DEKs encrypting those fields were deleted in the preceding line.
   await keyVaultClient.db("medicalRecords").dropDatabase();
   const keyVaultColl = keyVaultDB.collection(keyVaultCollection);
   await keyVaultColl.createIndex(
     { keyAltNames: 1 },
     {
       unique: true,
       partialFilterExpression: { keyAltNames: { $exists: true } },
     }
   );
   ```

2) Create a Data Encryption Key

   Add your GCP KMS Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```javascript
   const provider = "gcp";
   const kmsProviderCredentials = {
     gcp: {
       email: "<Your GCP Email>",
       privateKey: "<Your GCP Private Key>",
     },
   };
   ```

   You can also provide a custom name for your KMS provider by passing in a string that includes the name of the KMS provider, followed by a colon and the custom name. Providing a unique name for a KMS provider allows you to specify multiple KMS providers of the same type.

   For example, you can name your GCP KMS provider "my\_gcp\_provider" in your KMS credentials variable as shown in the following code:

   ```javascript
   kmsProviders = {
     "gcp:my_gcp_provider": {
       email: process.env.GCP_EMAIL, // Your GCP email
       privateKey: process.env.GCP_PRIVATE_KEY, // Your GCP private key
     },
   };

   ```

   **Tip:**

   You saved a file containing your service account key credentials in the [Create a GCP Service Account](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-register-account) step of this guide.

   If you downloaded your credentials in JSON format, you can use the following command to extract the value of your private key, substituting `<credentials-filename>` with the name of your credentials file. The following command requires that you install [OpenSSL:](https://docs.openssl.org/master/)

   ```text
   cat <credentials-filename> | jq -r .private_key | openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER | base64
   ```

   If you downloaded your credentials in PKCS12 format, you need to specify your GCP service account import password and to add a PEM pass phrase to access the key when accessing it using the following command, substituting `<credentials-filename>` with the name of your credentials file:

   ```text
   openssl pkcs12 -info -in <credentials-filename>
   ```

   1. Add Your Key Information

      **Tip:**

      You recorded your Customer Master Key details in the [Create a Customer Master Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-create-master-key) step of this guide.

      ```javascript
      const masterKey = {
        projectId: "<Your Project ID>",
        location: "<Your Key Location>",
        keyRing: "<Your Key Ring>",
        keyName: "<Your Key Name>",
      };
      ```

   2. Generate your Data Encryption Key

      Generate your Data Encryption Key using the variables declared in [step one](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-index) of this tutorial.

      ```javascript
      const client = new MongoClient(uri);
      await client.connect();

      const encryption = new ClientEncryption(client, {
        keyVaultNamespace,
        kmsProviderCredentials,
      });
      const key = await encryption.createDataKey(provider, {
        masterKey: masterKey,
      });
      console.log("DataKeyId [base64]: ", key.toString("base64"));
      await keyVaultClient.close();
      await client.close();
      ```

      **Note: Import ClientEncryption**

      When using the Node.js driver v6.0 and later, you must import `ClientEncryption` from `mongodb`.

      For earlier driver versions, import `ClientEncryption` from `mongodb-client-encryption`.

   **Tip: Learn More**

   To view a diagram showing how your client application creates your Data Encryption Key when using an Google Cloud Key Management Service, see [Architecture.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-fundamentals-kms-providers-gcp-architecture)

   To learn more about the options for creating a Data Encryption Key encrypted with a Customer Master Key hosted in Google Cloud Key Management Service, see [kmsProviders Object](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp) and [dataKeyOpts Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-datakeyopts-gcp)

   To view the complete code for making a Data Encryption Key, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/node/gcp/reader/make_data_key.js)

3) Configure the MongoClient

   **Tip:**

   Follow the remaining steps in this tutorial in a separate file from the one created in the previous steps.

   To view the complete code for this file, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/node/gcp/reader/insert_encrypted_document.js)

   Specify the Key Vault Collection Namespace

   Specify `encryption.__keyVault` as the Key Vault collection namespace.

   ```javascript
   const keyVaultNamespace = "encryption.__keyVault";
   ```

   Specify your Cloud Account Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```javascript
   const kmsProviders = {
     gcp: {
       email: "<Your GCP Email>",
       privateKey: "<Your GCP Private Key>",
     },
   };
   ```

   Create an Encryption Schema For Your Collection

   **Tip: Add Your Data Encryption Key Base64 ID**

   Make sure to update the following code to include your Base64 DEK (Data Encryption Key) ID. You received this value in the [Generate your Data Encryption Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-dek) step of this guide.

   ```javascript
   dataKey = "<Your base64 DEK ID>";
   const schema = {
     bsonType: "object",
     encryptMetadata: {
       keyId: [new Binary(Buffer.from(dataKey, "base64"), 4)],
     },
     properties: {
       insurance: {
         bsonType: "object",
         properties: {
           policyNumber: {
             encrypt: {
               bsonType: "int",
               algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
             },
           },
         },
       },
       medicalRecords: {
         encrypt: {
           bsonType: "array",
           algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
         },
       },
       bloodType: {
         encrypt: {
           bsonType: "string",
           algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
         },
       },
       ssn: {
         encrypt: {
           bsonType: "int",
           algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
         },
       },
     },
   };

   var patientSchema = {};
   patientSchema[namespace] = schema;
   ```

   Specify the Location of the Automatic Encryption Shared Library

   ```javascript
   const extraOptions = {
     cryptSharedLibPath: "<Full path to your Automatic Encryption Shared Library>",
   };
   ```

   **Note: Automatic Encryption Options**

   The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.

   To learn more about the Automatic Encryption Shared Library, see the [Install and Configure a CSFLE Query Analysis Component](https://www.mongodb.com/docs/manual/core/csfle/reference/install-library.md#std-label-csfle-reference-shared-library) page.

   Create the MongoClient

   Instantiate a MongoDB client object with the following automatic encryption settings that use the variables declared in the previous steps:

   ```javascript
   const secureClient = new MongoClient(connectionString, {
     autoEncryption: {
       keyVaultNamespace,
       kmsProviders,
       schemaMap: patientSchema,
       extraOptions: extraOptions,
     },
   });
   ```

4) Insert a Document with Encrypted Fields

   Use your CSFLE-enabled `MongoClient` instance to insert a document with encrypted fields into the `medicalRecords.patients` namespace using the following code snippet:

   ```javascript
   try {
     const writeResult = await secureClient
       .db(db)
       .collection(coll)
       .insertOne({
         name: "Jon Doe",
         ssn: 241014209,
         bloodType: "AB+",
         medicalRecords: [{ weight: 180, bloodPressure: "120/80" }],
         insurance: {
           policyNumber: 123142,
           provider: "MaestCare",
         },
       });
   } catch (writeError) {
     console.error("writeError occurred:", writeError);
   }
   ```

   When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:

   ```json
   {
     "_id": { "$oid": "<_id of your document>" },
     "name": "Jon Doe",
     "ssn": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "bloodType": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "medicalRecords": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "insurance": {
       "provider": "MaestCare",
       "policyNumber": {
         "$binary": "<cipher-text>",
         "$type": "6"
       }
     }
   }

   ```

   To view the complete code for inserting a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/node/gcp/reader/insert_encrypted_document.js)

5) Retrieve Your Document with Encrypted Fields

   Retrieve the document with encrypted fields you inserted in the [Insert a Document with Encrypted Fields](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-insert) step of this guide.

   To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.

   ```javascript
   console.log("Finding a document with regular (non-encrypted) client.");
   console.log(
     await regularClient.db(db).collection(coll).findOne({ name: /Jon/ })
   );

   console.log("Finding a document with encrypted client");
   console.log(
     await secureClient.db(db).collection(coll).findOne({ name: /Jon/ })
   );
   ```

   The output of the preceding code snippet should look like this:

   ```json
   Finding a document with regular (non-encrypted) client.

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
     bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
     'key-id': 'demo-data-key',
     medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
     insurance: {
       policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
       provider: 'MaestCare'
     }
   }

   Finding a document with encrypted client

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: 241014209,
     bloodType: 'AB+',
     'key-id': 'demo-data-key',
     medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
     insurance: { policyNumber: 123142, provider: 'MaestCare' }
   }

   ```

   To view the complete code for finding a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/node/gcp/reader/insert_encrypted_document.js)

1. Create a Unique Index on your Key Vault collection

   Create a unique index on the `keyAltNames` field in your `encryption.__keyVault` namespace.

   ```python
   connection_string = "<your connection string here>"

   key_vault_coll = "__keyVault"
   key_vault_db = "encryption"
   key_vault_namespace = f"{key_vault_db}.{key_vault_coll}"
   key_vault_client = MongoClient(connection_string)
   # Drop the Key Vault Collection in case you created this collection
   # in a previous run of this application.
   key_vault_client.drop_database(key_vault_db)
   # Drop the database storing your encrypted fields as all
   # the DEKs encrypting those fields were deleted in the preceding line.
   key_vault_client["medicalRecords"].drop_collection("patients")
   key_vault_client[key_vault_db][key_vault_coll].create_index(
       [("keyAltNames", ASCENDING)],
       unique=True,
       partialFilterExpression={"keyAltNames": {"$exists": True}},
   )
   ```

2. Create a Data Encryption Key

   Add your GCP KMS Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```python
   provider = "gcp"
   kms_provider_credentials = {
       provider: {"email": "<your GCP email>", "privateKey": "<your GCP private key>"}
   }
   ```

   You can also provide a custom name for your KMS provider by passing in a string that includes the name of the KMS provider, followed by a colon and the custom name. Providing a unique name for a KMS provider allows you to specify multiple KMS providers of the same type.

   For example, you can name your GCP KMS provider "my\_gcp\_provider" in your KMS credentials variable as shown in the following code:

   ```python
   kms_provider_credentials = {
       "gcp:my_gcp_provider": {
           "email": os.environ['GCP_EMAIL'], # Your GCP email
           "privateKey": os.environ['GCP_PRIVATE_KEY'] # Your GCP private key
       }
   }
   ```

   **Tip:**

   You saved a file containing your service account key credentials in the [Create a GCP Service Account](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-register-account) step of this guide.

   If you downloaded your credentials in JSON format, you can use the following command to extract the value of your private key, substituting `<credentials-filename>` with the name of your credentials file. The following command requires that you install [OpenSSL:](https://docs.openssl.org/master/)

   ```text
   cat <credentials-filename> | jq -r .private_key | openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER | base64
   ```

   If you downloaded your credentials in PKCS12 format, you need to specify your GCP service account import password and to add a PEM pass phrase to access the key when accessing it using the following command, substituting `<credentials-filename>` with the name of your credentials file:

   ```text
   openssl pkcs12 -info -in <credentials-filename>
   ```

   1. Add Your Key Information

      **Tip:**

      You recorded your Customer Master Key details in the [Create a Customer Master Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-create-master-key) step of this guide.

      ```python
      master_key = {
          "projectId": "<GCP project identifier>",
          "location": "<GCP region>",
          "keyRing": "<GCP key ring name>",
          "keyName": "<GCP key name>",
      }
      ```

   2. Generate your Data Encryption Key

      Generate your Data Encryption Key using the variables declared in [step one](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-index) of this tutorial.

      ```python
      key_vault_database = "encryption"
      key_vault_collection = "__keyVault"
      key_vault_namespace = f"{key_vault_database}.{key_vault_collection}"

      client = MongoClient(connection_string)
      client_encryption = ClientEncryption(
          kms_provider_credentials,  # pass in the kms_provider_credentials variable from the previous step
          key_vault_namespace,
          client,
          CodecOptions(uuid_representation=STANDARD),
      )
      data_key_id = client_encryption.create_data_key(provider, master_key)

      base_64_data_key_id = base64.b64encode(data_key_id)
      print("DataKeyId [base64]: ", base_64_data_key_id)
      ```

   **Tip: Learn More**

   To view a diagram showing how your client application creates your Data Encryption Key when using an Google Cloud Key Management Service, see [Architecture.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-fundamentals-kms-providers-gcp-architecture)

   To learn more about the options for creating a Data Encryption Key encrypted with a Customer Master Key hosted in Google Cloud Key Management Service, see [kmsProviders Object](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp) and [dataKeyOpts Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-datakeyopts-gcp)

   To view the complete code for making a Data Encryption Key, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/python/gcp/reader/make_data_key.py)

3. Configure the MongoClient

   **Tip:**

   Follow the remaining steps in this tutorial in a separate file from the one created in the previous steps.

   To view the complete code for this file, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/python/gcp/reader/insert_encrypted_document.py)

   Specify the Key Vault Collection Namespace

   Specify `encryption.__keyVault` as the Key Vault collection namespace.

   ```python
   key_vault_namespace = "encryption.__keyVault"
   ```

   Specify your Cloud Account Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```python
   provider = "gcp"
   kms_providers = {
       "gcp": {"email": "<your GCP email>", "privateKey": "<your GCP private key>"}
   }
   ```

   Create an Encryption Schema For Your Collection

   **Tip: Add Your Data Encryption Key Base64 ID**

   Make sure to update the following code to include your Base64 DEK (Data Encryption Key) ID. You received this value in the [Generate your Data Encryption Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-dek) step of this guide.

   ```python
   dek_id = b"<paste-base-64-encoded-data-encryption-key-id>"
   json_schema = {
       "bsonType": "object",
       "encryptMetadata": {"keyId": [Binary(base64.b64decode(dek_id), UUID_SUBTYPE)]},
       "properties": {
           "insurance": {
               "bsonType": "object",
               "properties": {
                   "policyNumber": {
                       "encrypt": {
                           "bsonType": "int",
                           "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
                       }
                   }
               },
           },
           "medicalRecords": {
               "encrypt": {
                   "bsonType": "array",
                   "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
               }
           },
           "bloodType": {
               "encrypt": {
                   "bsonType": "string",
                   "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
               }
           },
           "ssn": {
               "encrypt": {
                   "bsonType": "int",
                   "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
               }
           },
       },
   }

   patient_schema = {"medicalRecords.patients": json_schema}
   ```

   Specify the Location of the Automatic Encryption Shared Library

   ```python
   extra_options = {
       "cryptSharedLibPath": "<Full path to your Automatic Encryption Shared Library>"
   }
   ```

   **Note: Automatic Encryption Options**

   The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.

   To learn more about the Automatic Encryption Shared Library, see the [Install and Configure a CSFLE Query Analysis Component](https://www.mongodb.com/docs/manual/core/csfle/reference/install-library.md#std-label-csfle-reference-shared-library) page.

   Create the MongoClient

   Instantiate a MongoDB client object with the following automatic encryption settings that use the variables declared in the previous steps:

   ```python
   fle_opts = AutoEncryptionOpts(
       kms_providers, key_vault_namespace, schema_map=patient_schema, **extra_options
   )
   secureClient = MongoClient(connection_string, auto_encryption_opts=fle_opts)
   ```

4. Insert a Document with Encrypted Fields

   Use your CSFLE-enabled `MongoClient` instance to insert a document with encrypted fields into the `medicalRecords.patients` namespace using the following code snippet:

   ```python
   def insert_patient(
       collection, name, ssn, blood_type, medical_records, policy_number, provider
   ):
       insurance = {"policyNumber": policy_number, "provider": provider}
       doc = {
           "name": name,
           "ssn": ssn,
           "bloodType": blood_type,
           "medicalRecords": medical_records,
           "insurance": insurance,
       }
       collection.insert_one(doc)


   medical_record = [{"weight": 180, "bloodPressure": "120/80"}]
   insert_patient(
       secureClient.medicalRecords.patients,
       "Jon Doe",
       241014209,
       "AB+",
       medical_record,
       123142,
       "MaestCare",
   )
   ```

   When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:

   ```json
   {
     "_id": { "$oid": "<_id of your document>" },
     "name": "Jon Doe",
     "ssn": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "bloodType": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "medicalRecords": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "insurance": {
       "provider": "MaestCare",
       "policyNumber": {
         "$binary": "<cipher-text>",
         "$type": "6"
       }
     }
   }

   ```

   To view the complete code for inserting a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/python/gcp/reader/insert_encrypted_document.py)

5. Retrieve Your Document with Encrypted Fields

   Retrieve the document with encrypted fields you inserted in the [Insert a Document with Encrypted Fields](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-insert) step of this guide.

   To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.

   ```python
   print("Finding a document with regular (non-encrypted) client.")
   result = regularClient.medicalRecords.patients.find_one({"name": "Jon Doe"})
   pprint.pprint(result)

   print("Finding a document with encrypted client")
   pprint.pprint(secureClient.medicalRecords.patients.find_one({"name": "Jon Doe"}))
   ```

   The output of the preceding code snippet should look like this:

   ```json
   Finding a document with regular (non-encrypted) client.

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
     bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
     'key-id': 'demo-data-key',
     medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
     insurance: {
       policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
       provider: 'MaestCare'
     }
   }

   Finding a document with encrypted client

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: 241014209,
     bloodType: 'AB+',
     'key-id': 'demo-data-key',
     medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
     insurance: { policyNumber: 123142, provider: 'MaestCare' }
   }

   ```

   To view the complete code for finding a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/python/gcp/reader/insert_encrypted_document.py)

1) Create a Unique Index on your Key Vault collection

   Create a unique index on the `keyAltNames` field in your `encryption.__keyVault` namespace.

   ```csharp
   var connectionString = "<Your MongoDB URI>";
   var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
   var keyVaultClient = new MongoClient(connectionString);
   var indexOptions = new CreateIndexOptions<BsonDocument>();
   indexOptions.Unique = true;
   indexOptions.PartialFilterExpression = new BsonDocument { { "keyAltNames", new BsonDocument { { "$exists", new BsonBoolean(true) } } } };
   var builder = Builders<BsonDocument>.IndexKeys;
   var indexKeysDocument = builder.Ascending("keyAltNames");
   var indexModel = new CreateIndexModel<BsonDocument>(indexKeysDocument, indexOptions);
   var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.ToString());
   // Drop the Key Vault Collection in case you created this collection
   // in a previous run of this application.  
   keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);
   // Drop the database storing your encrypted fields as all
   // the DEKs encrypting those fields were deleted in the preceding line.
   keyVaultClient.GetDatabase("medicalRecords").DropCollection("patients");
   var keyVaultCollection = keyVaultDatabase.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName.ToString());
   keyVaultCollection.Indexes.CreateOne(indexModel);
   ```

2) Create a Data Encryption Key

   Add your GCP KMS Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```csharp
   var kmsProviderCredentials = new Dictionary<string, IReadOnlyDictionary<string, object>>();
   var provider = "gcp";
   var gcpKmsOptions = new Dictionary<string, object>
   {
      { "privateKey", "<Your GCP Private Key>" },
      { "email", "<Your GCP Email>" },
   };
   kmsProviderCredentials.Add(provider, gcpKmsOptions);
   ```

   You can also provide a custom name for your KMS provider by passing in a string that includes the name of the KMS provider, followed by a colon and the custom name. Providing a unique name for a KMS provider allows you to specify multiple KMS providers of the same type.

   For example, you can name your GCP KMS provider "my\_gcp\_provider" in your KMS credentials variable as shown in the following code:

   ```csharp
   var kmsProviderCredentials = new Dictionary<string, IReadOnlyDictionary<string, object>>();
   var kmsOptions = new Dictionary<string, object>
   {
       { "email", _appSettings["Gcp:Email"] }, // Your GCP email
       { "privateKey", _appSettings["Gcp:PrivateKey"] } // Your GCP private key
   };
   kmsProviderCredentials.Add("gcp:my_gcp_provider", kmsOptions);
   ```

   **Tip:**

   You saved a file containing your service account key credentials in the [Create a GCP Service Account](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-register-account) step of this guide.

   If you downloaded your credentials in JSON format, you can use the following command to extract the value of your private key, substituting `<credentials-filename>` with the name of your credentials file. The following command requires that you install [OpenSSL:](https://docs.openssl.org/master/)

   ```text
   cat <credentials-filename> | jq -r .private_key | openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER | base64
   ```

   If you downloaded your credentials in PKCS12 format, you need to specify your GCP service account import password and to add a PEM pass phrase to access the key when accessing it using the following command, substituting `<credentials-filename>` with the name of your credentials file:

   ```text
   openssl pkcs12 -info -in <credentials-filename>
   ```

   1. Add Your Key Information

      **Tip:**

      You recorded your Customer Master Key details in the [Create a Customer Master Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-create-master-key) step of this guide.

      ```csharp
      var dataKeyOptions = new DataKeyOptions(
         masterKey: new BsonDocument
         {
             { "projectId", "Your GCP Project ID" },
             { "location", "Your GCP Key Location" } ,
             { "keyRing", "<Your GCP Key Ring>" },
             { "keyName", "<Your GCP Key Name>" },
         });
      ```

   2. Generate your Data Encryption Key

      Generate your Data Encryption Key using the variables declared in [step one](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-index) of this tutorial.

      ```csharp
      var clientEncryptionOptions = new ClientEncryptionOptions(
          keyVaultClient: keyVaultClient,
          keyVaultNamespace: keyVaultNamespace,
          kmsProviders: kmsProviderCredentials
          );

      var clientEncryption = new ClientEncryption(clientEncryptionOptions);
      var dataKeyId = clientEncryption.CreateDataKey(provider, dataKeyOptions, CancellationToken.None);
      var dataKeyIdBase64 = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));
      Console.WriteLine($"DataKeyId [base64]: {dataKeyIdBase64}");
      ```

   **Tip: Learn More**

   To view a diagram showing how your client application creates your Data Encryption Key when using an Google Cloud Key Management Service, see [Architecture.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-fundamentals-kms-providers-gcp-architecture)

   To learn more about the options for creating a Data Encryption Key encrypted with a Customer Master Key hosted in Google Cloud Key Management Service, see [kmsProviders Object](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp) and [dataKeyOpts Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-datakeyopts-gcp)

   To view the complete code for making a Data Encryption Key, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/dotnet/gcp/reader/CSFLE/MakeDataKey.cs)

3) Configure the MongoClient

   **Tip:**

   Follow the remaining steps in this tutorial in a separate file from the one created in the previous steps.

   To view the complete code for this file, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/dotnet/gcp/reader/CSFLE/InsertEncryptedDocument.cs)

   Specify the Key Vault Collection Namespace

   Specify `encryption.__keyVault` as the Key Vault collection namespace.

   ```csharp
   var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
   ```

   Specify your Cloud Account Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```csharp
   var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
   var provider = "gcp";
   var gcpKmsOptions = new Dictionary<string, object>
   {
      { "privateKey", "<Your GCP Private Key>" },
      { "email", "<Your GCP Email>" },
   };
   kmsProviders.Add(provider, gcpKmsOptions);
   ```

   Create an Encryption Schema For Your Collection

   **Tip: Add Your Data Encryption Key Base64 ID**

   Make sure to update the following code to include your Base64 DEK (Data Encryption Key) ID. You received this value in the [Generate your Data Encryption Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-dek) step of this guide.

   ```csharp
   var keyId = "<Your base64 DEK ID here>";
   var schema = new BsonDocument
   {
      { "bsonType", "object" },
      {
          "encryptMetadata",
          new BsonDocument("keyId", new BsonArray(new[] { new BsonBinaryData(Convert.FromBase64String(keyId), BsonBinarySubType.UuidStandard) }))
      },
      {
          "properties",
          new BsonDocument
          {
              {
                  "ssn", new BsonDocument
                  {
                      {
                          "encrypt", new BsonDocument
                          {
                              { "bsonType", "int" },
                              { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }
                          }
                      }
                  }
              },
              {
                  "bloodType", new BsonDocument
                  {
                      {
                          "encrypt", new BsonDocument
                          {
                              { "bsonType", "string" },
                              { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" }
                          }
                      }
                  }
              },
              {
                  "medicalRecords", new BsonDocument
                  {
                      {
                          "encrypt", new BsonDocument
                          {
                              { "bsonType", "array" },
                              { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" }
                          }
                      }
                  }
              },
              {
                  "insurance", new BsonDocument
                  {
                      { "bsonType", "object" },
                      {
                          "properties", new BsonDocument
                          {
                              {
                                  "policyNumber", new BsonDocument
                                  {
                                      {
                                          "encrypt", new BsonDocument
                                          {
                                              { "bsonType", "int" },
                                              { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
          }
      }
   };
   var schemaMap = new Dictionary<string, BsonDocument>();
   schemaMap.Add(dbNamespace, schema);
   ```

   Specify the Location of the Automatic Encryption Shared Library

   ```csharp
   var mongoBinariesPath = "<Full path to your Automatic Encryption Shared Library>";
   var extraOptions = new Dictionary<string, object>()
   {
      { "cryptSharedLibPath", mongoBinariesPath },
   };
   ```

   **Note: Automatic Encryption Options**

   The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.

   To learn more about the Automatic Encryption Shared Library, see the [Install and Configure a CSFLE Query Analysis Component](https://www.mongodb.com/docs/manual/core/csfle/reference/install-library.md#std-label-csfle-reference-shared-library) page.

   Create the MongoClient

   Instantiate a MongoDB client object with the following automatic encryption settings that use the variables declared in the previous steps:

   ### .NET/C# Driver v3.0+

   ```csharp
   MongoClientSettings.Extensions.AddAutoEncryption(); // .NET/C# Driver v3.0 or later only
   var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
   var autoEncryptionOptions = new AutoEncryptionOptions(
       keyVaultNamespace: keyVaultNamespace,
       kmsProviders: kmsProviders,
       schemaMap: schemaMap,
       extraOptions: extraOptions
       );
   clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
   var secureClient = new MongoClient(clientSettings);
   ```

4) Insert a Document with Encrypted Fields

   Use your CSFLE-enabled `MongoClient` instance to insert a document with encrypted fields into the `medicalRecords.patients` namespace using the following code snippet:

   ```csharp
   var sampleDocFields = new BsonDocument
   {
       { "name", "Jon Doe" },
       { "ssn", 145014000 },
       { "bloodType", "AB-" },
       {
           "medicalRecords", new BsonArray
           {
               new BsonDocument("weight", 180),
               new BsonDocument("bloodPressure", "120/80")
           }
       },
       {
           "insurance", new BsonDocument
           {
               { "policyNumber", 123142 },
               { "provider", "MaestCare" }
           }
       }
   };

   // Construct an auto-encrypting client
   var secureCollection = secureClient.GetDatabase(db).GetCollection<BsonDocument>(coll);

   // Insert a document into the collection
   secureCollection.InsertOne(sampleDocFields);
   ```

   When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:

   ```json
   {
     "_id": { "$oid": "<_id of your document>" },
     "name": "Jon Doe",
     "ssn": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "bloodType": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "medicalRecords": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "insurance": {
       "provider": "MaestCare",
       "policyNumber": {
         "$binary": "<cipher-text>",
         "$type": "6"
       }
     }
   }

   ```

   To view the complete code for inserting a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/dotnet/gcp/reader/CSFLE/InsertEncryptedDocument.cs)

5) Retrieve Your Document with Encrypted Fields

   Retrieve the document with encrypted fields you inserted in the [Insert a Document with Encrypted Fields](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-insert) step of this guide.

   To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.

   ```csharp
   Console.WriteLine("Finding a document with regular (non-encrypted) client.");
   var filter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe");
   var regularResult = regularCollection.Find(filter).Limit(1).ToList()[0];
   Console.WriteLine($"\n{regularResult}\n");

   Console.WriteLine("Finding a document with encrypted client");
   var ssnFilter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe");
   var secureResult = secureCollection.Find(ssnFilter).Limit(1).First();
   Console.WriteLine($"\n{secureResult}\n");
   ```

   The output of the preceding code snippet should look like this:

   ```json
   Finding a document with regular (non-encrypted) client.

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
     bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
     'key-id': 'demo-data-key',
     medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
     insurance: {
       policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
       provider: 'MaestCare'
     }
   }

   Finding a document with encrypted client

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: 241014209,
     bloodType: 'AB+',
     'key-id': 'demo-data-key',
     medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
     insurance: { policyNumber: 123142, provider: 'MaestCare' }
   }

   ```

   To view the complete code for finding a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/dotnet/gcp/reader/CSFLE/InsertEncryptedDocument.cs)

1. Create a Unique Index on your Key Vault collection

   Create a unique index on the `keyAltNames` field in your `encryption.__keyVault` namespace.

   ```go
   uri := "<Your MongoDB URI>"
   keyVaultClient, err := mongo.Connect(options.Client().ApplyURI(uri))
   if err != nil {
   	return fmt.Errorf("Connect error for regular client: %v", err)
   }
   defer func() {
   	_ = keyVaultClient.Disconnect(context.TODO())
   }()

   keyVaultColl := "__keyVault"
   keyVaultDb := "encryption"
   keyVaultNamespace := keyVaultDb + "." + keyVaultColl
   keyVaultIndex := mongo.IndexModel{
   	Keys: bson.D{{"keyAltNames", 1}},
   	Options: options.Index().
   		SetUnique(true).
   		SetPartialFilterExpression(bson.D{
   			{"keyAltNames", bson.D{
   				{"$exists", true},
   			}},
   		}),
   }
   // Drop the Key Vault Collection in case you created this collection
   // in a previous run of this application.
   if err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Drop(context.TODO()); err != nil {
   	log.Fatalf("Collection.Drop error: %v", err)
   }
   // Drop the database storing your encrypted fields as all
   // the DEKs encrypting those fields were deleted in the preceding line.
   if err = keyVaultClient.Database("medicalRecords").Collection("patients").Drop(context.TODO()); err != nil {
   	log.Fatalf("Collection.Drop error: %v", err)
   }
   _, err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Indexes().CreateOne(context.TODO(), keyVaultIndex)
   if err != nil {
   	panic(err)
   }
   ```

2. Create a Data Encryption Key

   Add your GCP KMS Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```go
   provider := "gcp"
   kmsProviders := map[string]map[string]interface{}{
   	provider: {
   		"email":      "<Your GCP Email>",
   		"privateKey": "<Your GCP Private Key>",
   	},
   }
   ```

   **Tip:**

   You saved a file containing your service account key credentials in the [Create a GCP Service Account](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-register-account) step of this guide.

   If you downloaded your credentials in JSON format, you can use the following command to extract the value of your private key, substituting `<credentials-filename>` with the name of your credentials file. The following command requires that you install [OpenSSL:](https://docs.openssl.org/master/)

   ```text
   cat <credentials-filename> | jq -r .private_key | openssl pkcs8 -topk8 -nocrypt -inform PEM -outform DER | base64
   ```

   If you downloaded your credentials in PKCS12 format, you need to specify your GCP service account import password and to add a PEM pass phrase to access the key when accessing it using the following command, substituting `<credentials-filename>` with the name of your credentials file:

   ```text
   openssl pkcs12 -info -in <credentials-filename>
   ```

   1. Add Your Key Information

      **Tip:**

      You recorded your Customer Master Key details in the [Create a Customer Master Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-gcp-create-master-key) step of this guide.

      ```go
      masterKey := map[string]interface{}{
      	"projectId": "<Your GCP Project ID>",
      	"location":  "<Your GCP Location>",
      	"keyRing":   "<Your GCP Key Ring>",
      	"keyName":   "<Your GCP Key Name>",
      }
      ```

   2. Generate your Data Encryption Key

      Generate your Data Encryption Key using the variables declared in [step one](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-index) of this tutorial.

      ```go
      clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(keyVaultNamespace).
      	SetKmsProviders(kmsProviders)
      clientEnc, err := mongo.NewClientEncryption(keyVaultClient, clientEncryptionOpts)
      if err != nil {
      	return fmt.Errorf("NewClientEncryption error %v", err)
      }
      defer func() {
      	_ = clientEnc.Close(context.TODO())
      }()
      dataKeyOpts := options.DataKey().
      	SetMasterKey(masterKey)

      dataKeyID, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts)
      if err != nil {
      	return fmt.Errorf("create data key error %v", err)
      }

      fmt.Printf("DataKeyId [base64]: %s\n", base64.StdEncoding.EncodeToString(dataKeyID.Data))
      ```

   **Tip: Learn More**

   To view a diagram showing how your client application creates your Data Encryption Key when using an Google Cloud Key Management Service, see [Architecture.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-fundamentals-kms-providers-gcp-architecture)

   To learn more about the options for creating a Data Encryption Key encrypted with a Customer Master Key hosted in Google Cloud Key Management Service, see [kmsProviders Object](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp) and [dataKeyOpts Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-datakeyopts-gcp)

   To view the complete code for making a Data Encryption Key, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/go/gcp/reader/make-data-key.go)

3. Configure the MongoClient

   **Tip:**

   Follow the remaining steps in this tutorial in a separate file from the one created in the previous steps.

   To view the complete code for this file, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/go/gcp/reader/insert-encrypted-document.go)

   Specify the Key Vault Collection Namespace

   Specify `encryption.__keyVault` as the Key Vault collection namespace.

   ```go
   keyVaultNamespace := "encryption.__keyVault"
   ```

   Specify your Cloud Account Credentials

   Unless you're using an attached service account or an access token, add the service account credentials to your CSFLE-enabled client, as shown in the following code example. To learn about all supported credential forms for GCP, see [kmsProviders Object.](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-kms-provider-object-gcp)

   ```go
   kmsProviders := map[string]map[string]interface{}{
   	"gcp": {
   		"email":      "<Your GCP Email>",
   		"privateKey": "<Your GCP Private Key>",
   	},
   }
   ```

   Create an Encryption Schema For Your Collection

   **Tip: Add Your Data Encryption Key Base64 ID**

   Make sure to update the following code to include your Base64 DEK (Data Encryption Key) ID. You received this value in the [Generate your Data Encryption Key](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-create-dek) step of this guide.

   ```go
   dek_id := "<Your Base64 DEK ID>"
   schema_template := `{
   	"bsonType": "object",
   	"encryptMetadata": {
   		"keyId": [
   			{
   				"$binary": {
   					"base64": "%s",
   					"subType": "04"
   				}
   			}
   		]
   	},
   	"properties": {
   		"insurance": {
   			"bsonType": "object",
   			"properties": {
   				"policyNumber": {
   					"encrypt": {
   						"bsonType": "int",
   						"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
   					}
   				}
   			}
   		},
   		"medicalRecords": {
   			"encrypt": {
   				"bsonType": "array",
   				"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
   			}
   		},
   		"bloodType": {
   			"encrypt": {
   				"bsonType": "string",
   				"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
   			}
   		},
   		"ssn": {
   			"encrypt": {
   				"bsonType": "int",
   				"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
   			}
   		}
   	}
   }`
   schema := fmt.Sprintf(schema_template, dek_id)
   var schemaDoc bson.Raw
   if err := bson.UnmarshalExtJSON([]byte(schema), true, &schemaDoc); err != nil {
   	return fmt.Errorf("UnmarshalExtJSON error: %v", err)
   }
   schemaMap := map[string]interface{}{
   	dbName + "." + collName: schemaDoc,
   }
   ```

   Specify the Location of the Automatic Encryption Shared Library

   ```go
   extraOptions := map[string]interface{}{
   	"cryptSharedLibPath": "<Full path to your Automatic Encryption Shared Library>",
   }
   ```

   **Note: Automatic Encryption Options**

   The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.

   To learn more about the Automatic Encryption Shared Library, see the [Install and Configure a CSFLE Query Analysis Component](https://www.mongodb.com/docs/manual/core/csfle/reference/install-library.md#std-label-csfle-reference-shared-library) page.

   Create the MongoClient

   Instantiate a MongoDB client object with the following automatic encryption settings that use the variables declared in the previous steps:

   ```go
   autoEncryptionOpts := options.AutoEncryption().
   	SetKmsProviders(kmsProviders).
   	SetKeyVaultNamespace(keyVaultNamespace).
   	SetSchemaMap(schemaMap).
   	SetExtraOptions(extraOptions)
   secureClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri).SetAutoEncryptionOptions(autoEncryptionOpts))
   if err != nil {
   	return fmt.Errorf("Connect error for encrypted client: %v", err)
   }
   defer func() {
   	_ = secureClient.Disconnect(context.TODO())
   }()
   ```

4. Insert a Document with Encrypted Fields

   Use your CSFLE-enabled `MongoClient` instance to insert a document with encrypted fields into the `medicalRecords.patients` namespace using the following code snippet:

   ```go
   test_patient := map[string]interface{}{
   	"name":      "Jon Doe",
   	"ssn":       241014209,
   	"bloodType": "AB+",
   	"medicalRecords": []map[string]interface{}{{
   		"weight":        180,
   		"bloodPressure": "120/80",
   	}},
   	"insurance": map[string]interface{}{
   		"provider":     "MaestCare",
   		"policyNumber": 123142,
   	},
   }
   if _, err := secureClient.Database(dbName).Collection(collName).InsertOne(context.TODO(), test_patient); err != nil {
   	return fmt.Errorf("InsertOne error: %v", err)
   }
   ```

   **Note:**

   Rather than creating a raw BSON document, you can pass a struct with `bson` tags directly to the driver for encoding.

   When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:

   ```json
   {
     "_id": { "$oid": "<_id of your document>" },
     "name": "Jon Doe",
     "ssn": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "bloodType": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "medicalRecords": {
       "$binary": "<cipher-text>",
       "$type": "6"
     },
     "insurance": {
       "provider": "MaestCare",
       "policyNumber": {
         "$binary": "<cipher-text>",
         "$type": "6"
       }
     }
   }

   ```

   To view the complete code for inserting a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/go/gcp/reader/insert-encrypted-document.go)

5. Retrieve Your Document with Encrypted Fields

   Retrieve the document with encrypted fields you inserted in the [Insert a Document with Encrypted Fields](https://www.mongodb.com/docs/manual/core/csfle/tutorials/gcp/gcp-automatic.md#std-label-csfle-gcp-insert) step of this guide.

   To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.

   ```go
   fmt.Println("Finding a document with regular (non-encrypted) client.")
   var resultRegular bson.M
   err = regularClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"name", "Jon Doe"}}).Decode(&resultRegular)
   if err != nil {
   	panic(err)
   }
   outputRegular, err := json.MarshalIndent(resultRegular, "", "    ")
   if err != nil {
   	panic(err)
   }
   fmt.Printf("%s\n", outputRegular)

   fmt.Println("Finding a document with encrypted client")
   var resultSecure bson.M
   err = secureClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"name", "Jon Doe"}}).Decode(&resultSecure)
   if err != nil {
   	panic(err)
   }
   outputSecure, err := json.MarshalIndent(resultSecure, "", "    ")
   if err != nil {
   	panic(err)
   }
   fmt.Printf("%s\n", outputSecure)
   ```

   The output of the preceding code snippet should look like this:

   ```json
   Finding a document with regular (non-encrypted) client.

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
     bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
     'key-id': 'demo-data-key',
     medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
     insurance: {
       policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
       provider: 'MaestCare'
     }
   }

   Finding a document with encrypted client

   {
     _id: new ObjectId("629a452e0861b3130887103a"),
     name: 'Jon Doe',
     ssn: 241014209,
     bloodType: 'AB+',
     'key-id': 'demo-data-key',
     medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
     insurance: { policyNumber: 123142, provider: 'MaestCare' }
   }

   ```

   To view the complete code for finding a document with encrypted fields, see [our Github repository.](https://github.com/mongodb/docs/tree/main/content/manual/upcoming/source/includes/generated/in-use-encryption/csfle/go/gcp/reader/insert-encrypted-document.go)

## Learn More

To learn more about the topics mentioned in this guide, see the following links:

- Learn more about CSFLE components on the [Reference](https://www.mongodb.com/docs/manual/core/csfle/reference.md#std-label-csfle-reference) page.

- Learn how Customer Master Keys and Data Encryption Keys work on the [Encryption Keys and Key Vaults](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/keys-key-vaults.md#std-label-qe-reference-keys-key-vaults) page.

- See how KMS Providers manage your CSFLE keys on the [KMS Providers](https://www.mongodb.com/docs/manual/core/queryable-encryption/fundamentals/kms-providers.md#std-label-qe-fundamentals-kms-providers) page.
