class Google::Auth::OAuth2::STSClient


(tools.ietf.org/html/rfc8693#section-2.2.1) spec JSON response.
The returned dictionary response will be based on the [rfc8693 section 2.2.1]
mapped to parameters defined in the RFC.
A deviation on the spec will be for additional Google specific options that cannot be easily
The implementation will support various types of client authentication as allowed in the spec.
access Google APIs.
used to exchange external credentials for GCP access tokens in workload identity pools to
[OAuth 2.0 Token Exchange](tools.ietf.org/html/rfc8693) spec. This will be mainly
This module defines a token exchange utility based on the
OAuth 2.0 Token Exchange Spec.

def exchange_token options = {}

Returns:
  • (Hash) - A hash containing the token exchange response.

Parameters:
  • additional_headers (Hash) -- :
  • requested_token_type (String) --
  • scopes (Array) --
  • audience (String) --
  • resource (String) --
  • subject_token_type (String) --
  • subject_token (String) --
  • grant_type (String) --
  • connection (Faraday instance) --
def exchange_token options = {}
  missing_required_opts = [:grant_type, :subject_token, :subject_token_type] - options.keys
  unless missing_required_opts.empty?
    raise ArgumentError, "Missing required options: #{missing_required_opts.join ', '}"
  end
  # TODO: Add the ability to add authentication to the headers
  headers = URLENCODED_HEADERS.dup.merge(options[:additional_headers] || {})
  request_body = make_request options
  response = connection.post @token_exchange_endpoint, URI.encode_www_form(request_body), headers
  if response.status != 200
    raise "Token exchange failed with status #{response.status}"
  end
  MultiJson.load response.body
end

def initialize options = {}

Parameters:
  • token_exchange_endpoint (String) --
def initialize options = {}
  raise "Token exchange endpoint can not be nil" if options[:token_exchange_endpoint].nil?
  self.default_connection = options[:connection]
  @token_exchange_endpoint = options[:token_exchange_endpoint]
end

def make_request options = {}

def make_request options = {}
  request_body = {
    grant_type: options[:grant_type],
    audience: options[:audience],
    scope: Array(options[:scopes])&.join(" ") || [],
    requested_token_type: options[:requested_token_type],
    subject_token: options[:subject_token],
    subject_token_type: options[:subject_token_type]
  }
  unless options[:additional_options].nil?
    request_body[:options] = CGI.escape MultiJson.dump(options[:additional_options], symbolize_name: true)
  end
  request_body
end