Class: Google::Auth::ExternalAccount::AwsRequestSigner

Inherits:
Object
  • Object
show all
Defined in:
lib/googleauth/external_account/aws_credentials.rb

Overview

Implements an AWS request signer based on the AWS Signature Version 4 signing process. https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

Instance Method Summary collapse

Constructor Details

#initialize(region_name) ⇒ AwsRequestSigner

Instantiates an AWS request signer used to compute authenticated signed requests to AWS APIs based on the AWS Signature Version 4 signing process.



264
265
266
# File 'lib/googleauth/external_account/aws_credentials.rb', line 264

def initialize region_name
  @region_name = region_name
end

Instance Method Details

#generate_signed_request(aws_credentials, original_request) ⇒ Hash

Generates an AWS signature version 4 signed request.

Creates a signed request following the AWS Signature Version 4 process, which provides secure authentication for AWS API calls. The process includes creating canonical request strings, calculating signatures using the AWS credentials, and building proper authorization headers.

For detailed information on the signing process, see: https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html

Raises:



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/googleauth/external_account/aws_credentials.rb', line 296

def generate_signed_request aws_credentials, original_request
  uri = Addressable::URI.parse original_request[:url]
  unless uri.hostname && uri.scheme == "https"
    # NOTE: We use AwsCredentials name but can't access its principal since AwsRequestSigner
    # is a separate class and not a credential object with access to the audience
    raise CredentialsError.with_details(
      "Invalid AWS service URL",
      credential_type_name: AwsCredentials.name,
      principal: "aws"
    )
  end
  service_name = uri.host.split(".").first

  datetime = Time.now.utc.strftime "%Y%m%dT%H%M%SZ"
  date = datetime[0, 8]

  headers = aws_headers aws_credentials, original_request, datetime

  request_payload = original_request[:data] || ""
  content_sha256 = sha256_hexdigest request_payload

  canonical_req = canonical_request original_request[:method], uri, headers, content_sha256
  sts = string_to_sign datetime, canonical_req, service_name

  # Authorization header requires everything else to be properly setup in order to be properly
  # calculated.
  headers["Authorization"] = build_authorization_header headers, sts, aws_credentials, service_name, date

  {
    url: uri.to_s,
    headers: headers,
    method: original_request[:method],
    data: (request_payload unless request_payload.empty?)
  }.compact
end