123456789_123456789_123456789_123456789_123456789_

Module: Mongoid::Tasks::Encryption

Relationships & Source Files
Defined in: lib/mongoid/tasks/encryption.rb

Overview

This module contains helper methods for data encryption.

Instance Method Summary

Instance Method Details

#create_data_key(client_name: nil, kms_provider_name: nil, key_alt_name: nil) ⇒ Hash

Create a data encryption key for the given kms provider using the auto_encryption_options from the client’s configuration.

Parameters:

  • kms_provider_name (String | nil)

    The name of the kms provider to use. If not provided, the first provider in the client’s auto_encryption_options will be used.

  • client_name (String | nil)

    The name of the client to take auto_encryption_options from. If not provided, the default client will be used.

  • key_alt_name (String | nil)

    The alternate name of the key.

Returns:

  • (Hash)

    A hash containing the key id as :key_id, kms provider name as :kms_provider, and key vault namespace as :key_vault_namespace.

[ GitHub ]

  
# File 'lib/mongoid/tasks/encryption.rb', line 24

def create_data_key(client_name: nil, kms_provider_name: nil, key_alt_name: nil)
  kms_provider_name, kms_providers, key_vault_namespace = prepare_arguments(
    kms_provider_name,
    client_name
  )
  key_vault_client = Mongoid::Clients.default.with(database: key_vault_namespace.split('.').first)
  client_encryption = Mongo::ClientEncryption.new(
    key_vault_client,
    key_vault_namespace: key_vault_namespace,
    kms_providers: kms_providers
  )
  client_encryption_opts = {}.tap do |opts|
    opts[:key_alt_names] = [key_alt_name] if key_alt_name
  end
  data_key_id = client_encryption.create_data_key(kms_provider_name, client_encryption_opts)
  {
    key_id: Base64.strict_encode64(data_key_id.data),
    kms_provider: kms_provider_name,
    key_vault_namespace: key_vault_namespace,
    key_alt_name: key_alt_name
  }.compact
end

#get_kms_provider_name(kms_provider_name, kms_providers) ⇒ String (private)

Get kms provider name to use for creating a data key.

If kms_provider_name is provided, it will be used. Otherwise, if there is only one kms provider, that provider will be used. Otherwise, an error will be raised.

Parameters:

  • kms_provider_name (String | nil)

    The name of the kms provider as provided by the user.

  • kms_providers (Hash)

    The kms providers hash from the client’s auto_encryption_options.

Returns:

  • (String)

    The kms provider name to use for creating a data key.

[ GitHub ]

  
# File 'lib/mongoid/tasks/encryption.rb', line 97

def get_kms_provider_name(kms_provider_name, kms_providers)
  if kms_provider_name
    kms_provider_name
  elsif kms_providers.keys.length == 1
    kms_providers.keys.first
  else
    raise ArgumentError, 'kms_provider_name must be provided when there are multiple kms providers'
  end
end

#prepare_arguments(kms_provider_name, client_name) ⇒ Array<String, Hash, String> (private)

Prepare arguments needed to create a data key from the client’s auto_encryption_options.

Parameters:

  • kms_provider_name (String | nil)

    The name of the kms provider.

  • client_name (String | nil)

    The name of the client.

Returns:

  • (Array<String, Hash, String>)

    An array containing the normalized kms provider name, the kms providers hash, and the key vault namespace.

[ GitHub ]

  
# File 'lib/mongoid/tasks/encryption.rb', line 58

def prepare_arguments(kms_provider_name, client_name)
  client = (client_name || 'default').to_s
  client_options = Mongoid.clients[client]
  unless client_options.is_a?(Hash)
    raise Errors::NoClientConfig.new(client)
  end
  auto_encryption_options = client_options.dig(:options, :auto_encryption_options)
  unless auto_encryption_options.is_a?(Hash)
    raise Errors::InvalidAutoEncryptionConfiguration.new(client)
  end
  key_vault_namespace = auto_encryption_options[:key_vault_namespace]
  unless key_vault_namespace.is_a?(String)
    raise Errors::InvalidAutoEncryptionConfiguration.new(client)
  end
  kms_providers = auto_encryption_options[:kms_providers]
  unless kms_providers.is_a?(Hash)
    raise Errors::InvalidAutoEncryptionConfiguration.new(client)
  end
  valid_kms_provider_name = get_kms_provider_name(kms_provider_name, kms_providers)
  unless kms_providers.key?(valid_kms_provider_name)
    raise Errors::InvalidAutoEncryptionConfiguration.new(client, valid_kms_provider_name)
  end

  [valid_kms_provider_name, kms_providers, key_vault_namespace]
end