Class: LittleGhost::Providers::Bedrock::AwsSigV4

Inherits:
Object
  • Object
show all
Defined in:
lib/little_ghost/providers/bedrock/aws_protocol.rb

Overview

Signs AWS HTTP requests with Signature Version 4.

Instance Method Summary collapse

Constructor Details

#initialize(service:, region:, credentials:, clock: -> { Time.now.utc }) ⇒ AwsSigV4

:nodoc:



13
14
15
16
17
18
# File 'lib/little_ghost/providers/bedrock/aws_protocol.rb', line 13

def initialize(service:, region:, credentials:, clock: -> { Time.now.utc })
  @service = service
  @region = region
  @credentials = credentials
  @clock = clock
end

Instance Method Details

#headers(method:, uri:, headers:, body:) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/little_ghost/providers/bedrock/aws_protocol.rb', line 20

def headers(method:, uri:, headers:, body:)
  time = @clock.call.utc
  timestamp = time.strftime("%Y%m%dT%H%M%SZ")
  date = time.strftime("%Y%m%d")
  normalized = headers.to_h.transform_keys { |key| key.to_s.downcase }
    .merge("host" => host_header(uri), "x-amz-date" => timestamp)
  normalized["x-amz-security-token"] = @credentials.session_token if @credentials.session_token
  canonical_headers = normalized.sort.map { |key, value| "#{key}:#{value.to_s.strip.gsub(/\s+/, " ")}\n" }.join
  signed_headers = normalized.keys.sort.join(";")
  canonical_request = [method.to_s.upcase, canonical_path(uri), canonical_query(uri), canonical_headers,
    signed_headers, Digest::SHA256.hexdigest(body)].join("\n")
  scope = "#{date}/#{@region}/#{@service}/aws4_request"
  string_to_sign = ["AWS4-HMAC-SHA256", timestamp, scope, Digest::SHA256.hexdigest(canonical_request)].join("\n")
  signature = OpenSSL::HMAC.hexdigest("SHA256", signing_key(date), string_to_sign)
  normalized.merge("authorization" => "AWS4-HMAC-SHA256 Credential=#{@credentials.access_key_id}/#{scope}, SignedHeaders=#{signed_headers}, Signature=#{signature}")
end