Skip to content

Mongoose not following CSFLE configs, docs being written unencrypted #16015

@thompsonap09

Description

@thompsonap09

Prerequisites

  • I have written a descriptive issue title

Mongoose version

9.1.5

Node.js version

24.x

MongoDB version

8.0.18

Operating system

None

Operating system version (i.e. 20.04, 11.3, 10)

No response

Issue

I have an AWS Lambda that's hitting a Mongo Atlas instance, and we're using AWS KMS to handle the encryption keys. I've got a DEK being created no problem. I've read the Mongoose docs over a ton of times and just have no idea where I'm going wrong actually writing a document to the DB with an encrypted field. The document writes to the DB in "plaintext", the field I have marked as encrypted in my schema is just a standard human readable string. Any assistance on this would be greatly appreciated, because I'm really at a loss.

import { Handler } from 'aws-lambda';
import { ClientEncryption, KMSProviders, MongoClient } from 'mongodb';
import mongoose, { Schema } from 'mongoose';
import path from 'path';

const keyVaultDatabase = 'encryption';
const keyVaultCollection = '__keyVault';
const keyVaultNamespace = `${keyVaultDatabase}.${keyVaultCollection}`;

export const handler: Handler = async () => {
  try {
    const dekUUID = await getOrCreateDEK();

    const encryptSchema = new Schema(
      {
        name: String,
        ssn: {
          type: String,
          encrypt: {
            keyId: dekUUID,
            queries: 'equality',
            algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
          }
        },
        sequence: Number,
        requestingAgentCode: [String]
      },
      { encryptionType: 'csfle' }
    );

    const connection = mongoose.createConnection();

    const db = connection.useDb(process.env.MONGO_DB_NAME!);

    const encryptModel = db.model('work_requests', encryptSchema);

    await db.openUri(getMongoURI(), getEncryptedConnectionOptions());

    await encryptModel.create({
      name: 'Alan',
      ssn: '12345',
      sequence: 1234567,
      requestingAgentCode: ['23413412']
    });

    return {
      statusCode: 201,
      body: {}
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({
        message: 'Internal Server Error',
        error: (error as Error)?.message
      })
    };
  }
};

function getMongoURI(): string {
  return `${process.env.MONGODB_CONNECTION_STRING!}/?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true`;
}

function getKmsProviders(): KMSProviders {
  return {
    aws: {
      accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
      sessionToken: process.env.AWS_SESSION_TOKEN!
    }
  };
}

function getEncryptedConnectionOptions() {
  return {
    serverSelectionTimeoutMS: 5000,
    autoEncryption: {
      keyVaultNamespace: keyVaultNamespace,
      kmsProviders: getKmsProviders()
    }
  };
}

function getConnectionOptions() {
  return {
    serverSelectionTimeoutMS: 5000
  };
}

async function getOrCreateDEK(): Promise<string> {
  const keyAltName = 'csfle-dek';

  const keyVaultClient = new MongoClient(getMongoURI(), getConnectionOptions());
  await keyVaultClient.connect();

  const keyVaultDB = keyVaultClient.db(keyVaultDatabase);
  const keyVaultColl = keyVaultDB.collection(keyVaultCollection);

  // Check if the dek already exists before trying to create anything
  const existingKey = await keyVaultColl.findOne({ keyAltNames: { $in: [keyAltName] } });
  if (existingKey) {
    keyVaultClient.close();
    return existingKey._id.toString('base64');
  }

  await keyVaultColl.createIndex(
    { keyAltNames: 1 },
    {
      unique: true,
      partialFilterExpression: { keyAltNames: { $exists: true } }
    }
  );

  const kmsProviders = getKmsProviders();

  const encryption = new ClientEncryption(keyVaultClient, {
    keyVaultNamespace,
    kmsProviders
  });

  const keyUUID = await encryption.createDataKey('aws', {
    masterKey: {
      region: process.env.AWS_KEY_REGION!,
      key: process.env.AWS_KEY_ARN!
    },
    keyAltNames: [keyAltName]
  });

  keyVaultClient.close();

  return keyUUID.toString('base64');
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    helpThis issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessaryhelp wanted

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions