class Aws::S3::Encryption::Client

Attributes

client[R]

@return [S3::Client]

envelope_location[R]

@return [Symbol<:metadata, :instruction_file>]

instruction_file_suffix[R]

@return [String] When {#envelope_location} is `:instruction_file`,

the envelope is stored in the object with the object key suffixed
by this string.
key_provider[R]

@return [KeyProvider, nil] Returns `nil` if you are using

AWS Key Management Service (KMS).

Public Class Methods

new(options = {}) click to toggle source

Creates a new encryption client. You must provide one of the following options:

  • `:encryption_key`

  • `:kms_key_id`

  • `:key_provider`

You may also pass any other options accepted by `Client#initialize`.

@option options [S3::Client] :client A basic S3 client that is used

to make api calls. If a `:client` is not provided, a new {S3::Client}
will be constructed.

@option options [OpenSSL::PKey::RSA, String] :encryption_key The master

key to use for encrypting/decrypting all objects.

@option options [String] :kms_key_id When you provide a `:kms_key_id`,

then AWS Key Management Service (KMS) will be used to manage the
object encryption keys. By default a {KMS::Client} will be
constructed for KMS API calls. Alternatively, you can provide
your own via `:kms_client`.

@option options [#key_for] :key_provider Any object that responds

to `#key_for`. This method should accept a materials description
JSON document string and return return an encryption key.

@option options [Symbol] :envelope_location (:metadata) Where to

store the envelope encryption keys. By default, the envelope is
stored with the encrypted object. If you pass `:instruction_file`,
then the envelope is stored in a separate object in Amazon S3.

@option options [String] :instruction_file_suffix ('.instruction')

When `:envelope_location` is `:instruction_file` then the
instruction file uses the object key with this suffix appended.

@option options [KMS::Client] :kms_client A default {KMS::Client}

is constructed when using KMS to manage encryption keys.
# File lib/aws-sdk-s3/encryption/client.rb, line 230
def initialize(options = {})
  @client = extract_client(options)
  @cipher_provider = cipher_provider(options)
  @envelope_location = extract_location(options)
  @instruction_file_suffix = extract_suffix(options)
end

Public Instance Methods

get_object(params = {}, &block) click to toggle source

Gets an object from Amazon S3, decrypting data locally. See {S3::Client#get_object} for documentation on accepted request parameters. @option params [String] :instruction_file_suffix The suffix

used to find the instruction file containing the encryption
envelope. You should not set this option when the envelope
is stored in the object metadata. Defaults to
{#instruction_file_suffix}.

@option params [String] :instruction_file_suffix @option (see S3::Client#get_object) @return (see S3::Client#get_object) @see S3::Client#get_object @note The `:range` request parameter is not yet supported.

# File lib/aws-sdk-s3/encryption/client.rb, line 289
def get_object(params = {}, &block)
  if params[:range]
    raise NotImplementedError, '#get_object with :range not supported yet'
  end
  envelope_location, instruction_file_suffix = envelope_options(params)
  req = @client.build_request(:get_object, params)
  req.handlers.add(DecryptHandler)
  req.context[:encryption] = {
    cipher_provider: @cipher_provider,
    envelope_location: envelope_location,
    instruction_file_suffix: instruction_file_suffix,
  }
  req.send_request(target: block)
end
put_object(params = {}) click to toggle source

Uploads an object to Amazon S3, encrypting data client-side. See {S3::Client#put_object} for documentation on accepted request parameters. @option (see S3::Client#put_object) @return (see S3::Client#put_object) @see S3::Client#put_object

# File lib/aws-sdk-s3/encryption/client.rb, line 265
def put_object(params = {})
  req = @client.build_request(:put_object, params)
  req.handlers.add(EncryptHandler, priority: 95)
  req.context[:encryption] = {
    cipher_provider: @cipher_provider,
    envelope_location: @envelope_location,
    instruction_file_suffix: @instruction_file_suffix,
  }
  req.send_request
end

Private Instance Methods

cipher_provider(options) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 328
def cipher_provider(options)
  if options[:kms_key_id]
    KmsCipherProvider.new(
      kms_key_id: options[:kms_key_id],
      kms_client: kms_client(options),
    )
  else
    # kept here for backwards compatability, {#key_provider} is deprecated
    @key_provider = extract_key_provider(options)
    DefaultCipherProvider.new(key_provider: @key_provider)
  end
end
envelope_options(params) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 352
def envelope_options(params)
  location = params.delete(:envelope_location) || @envelope_location
  suffix = params.delete(:instruction_file_suffix)
  if suffix
    [:instruction_file, suffix]
  else
    [location, @instruction_file_suffix]
  end
end
extract_client(options) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 306
def extract_client(options)
  options[:client] || begin
    options = options.dup
    options.delete(:kms_key_id)
    options.delete(:kms_client)
    options.delete(:key_provider)
    options.delete(:encryption_key)
    options.delete(:envelope_location)
    options.delete(:instruction_file_suffix)
    S3::Client.new(options)
  end
end
extract_key_provider(options) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 341
def extract_key_provider(options)
  if options[:key_provider]
    options[:key_provider]
  elsif options[:encryption_key]
    DefaultKeyProvider.new(options)
  else
    msg = 'you must pass a :kms_key_id, :key_provider, or :encryption_key'
    raise ArgumentError, msg
  end
end
extract_location(options) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 362
def extract_location(options)
  location = options[:envelope_location] || :metadata
  if [:metadata, :instruction_file].include?(location)
    location
  else
    msg = ':envelope_location must be :metadata or :instruction_file '\
          "got #{location.inspect}"
    raise ArgumentError, msg
  end
end
extract_suffix(options) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 373
def extract_suffix(options)
  suffix = options[:instruction_file_suffix] || '.instruction'
  if String === suffix
    suffix
  else
    msg = ':instruction_file_suffix must be a String'
    raise ArgumentError, msg
  end
end
kms_client(options) click to toggle source
# File lib/aws-sdk-s3/encryption/client.rb, line 319
def kms_client(options)
  options[:kms_client] || begin
    KMS::Client.new(
      region: @client.config.region,
      credentials: @client.config.credentials,
    )
  end
end