Class: Google::Auth::ImpersonatedServiceAccountCredentials

Inherits:
Object
  • Object
show all
Includes:
BaseClient, Helpers::Connection
Defined in:
lib/googleauth/impersonated_service_account.rb

Overview

Authenticates requests using impersonation from base credentials. This is a two-step process: first authentication claim from the base credentials is created and then that claim is exchanged for a short-lived token at an IAMCredentials endpoint. The short-lived token and its expiration time are cached.

Constant Summary

Constants included from BaseClient

BaseClient::AUTH_METADATA_KEY

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers::Connection

connection, default_connection, default_connection=

Methods included from BaseClient

#apply, #apply!, #needs_access_token?, #notify_refresh_listeners, #on_refresh, #updater_proc

Constructor Details

#initialize(options = {}) ⇒ Google::Auth::ImpersonatedServiceAccountCredentials

Initializes a new instance of ImpersonatedServiceAccountCredentials.

Parameters:

  • options (Hash) (defaults to: {})

    A hash of options to configure the credentials.

Options Hash (options):

  • :base_credentials (Object) — default: required

    The authenticated principal. It will be used as following:

    • will be duplicated (with IAM scope) to create the source credentials if it supports duplication
    • as source credentials otherwise.
  • :impersonation_url (String) — default: required

    The URL to impersonate the service account. This URL should follow the format: https://iamcredentials.{universe_domain}/v1/projects/-/serviceAccounts/{source_sa_email}:generateAccessToken, where:

    • {universe_domain} is the domain of the IAMCredentials API endpoint (e.g., googleapis.com).
    • {source_sa_email} is the email address of the service account to impersonate.
  • :scope (Array<String>, String) — default: required

    The scope(s) for the short-lived impersonation token, defining the permissions required for the token.

  • :source_credentials (Object)

    The authenticated principal that will be used to fetch the short-lived impersonation access token. It is an alternative to providing the base credentials. It is redundant to provide both source and base credentials as only source will be used, but it can be done, e.g. when duplicating existing credentials.

Raises:

  • (ArgumentError)

    If any of the required options are missing.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/googleauth/impersonated_service_account.rb', line 116

def initialize options = {}
  @base_credentials, @impersonation_url, @scope =
    options.values_at :base_credentials,
                      :impersonation_url,
                      :scope

  # Fail-fast checks for required parameters
  if @base_credentials.nil? && !options.key?(:source_credentials)
    raise ArgumentError, "Missing required option: either :base_credentials or :source_credentials"
  end
  raise ArgumentError, "Missing required option: :impersonation_url" if @impersonation_url.nil?
  raise ArgumentError, "Missing required option: :scope" if @scope.nil?

  # Some credentials (all Signet-based ones and this one) include scope and a bunch of transient state
  # (e.g. refresh status) as part of themselves
  # so a copy needs to be created with the scope overriden and transient state dropped.
  #
  # If a credentials does not support `duplicate` we'll try to use it as is assuming it has a broad enough scope.
  # This might result in an "access denied" error downstream when the token from that credentials is being used
  # for the token exchange.
  @source_credentials = if options.key? :source_credentials
                          options[:source_credentials]
                        elsif @base_credentials.respond_to? :duplicate
                          @base_credentials.duplicate({
                                                        scope: IAM_SCOPE
                                                      })
                        else
                          @base_credentials
                        end
end

Instance Attribute Details

#access_tokenString? (readonly)

Returns The short-lived impersonation access token, retrieved and cached after making the impersonation request.

Returns:

  • (String, nil)

    The short-lived impersonation access token, retrieved and cached after making the impersonation request



60
61
62
# File 'lib/googleauth/impersonated_service_account.rb', line 60

def access_token
  @access_token
end

#base_credentialsObject (readonly)

Returns The original authenticated credentials used to fetch short-lived impersonation access tokens.

Returns:

  • (Object)

    The original authenticated credentials used to fetch short-lived impersonation access tokens



44
45
46
# File 'lib/googleauth/impersonated_service_account.rb', line 44

def base_credentials
  @base_credentials
end

#expires_atTime?

Returns The expiration time of the current access token, used to determine if the token is still valid.

Returns:

  • (Time, nil)

    The expiration time of the current access token, used to determine if the token is still valid



64
65
66
# File 'lib/googleauth/impersonated_service_account.rb', line 64

def expires_at
  @expires_at
end

#impersonation_urlString (readonly)

Returns The URL endpoint used to generate an impersonation token. This URL should follow a specific format to specify the impersonated service account.

Returns:

  • (String)

    The URL endpoint used to generate an impersonation token. This URL should follow a specific format to specify the impersonated service account.



52
53
54
# File 'lib/googleauth/impersonated_service_account.rb', line 52

def impersonation_url
  @impersonation_url
end

#scopeArray<String>, String (readonly)

Returns The scope(s) required for the impersonated access token, indicating the permissions needed for the short-lived token.

Returns:

  • (Array<String>, String)

    The scope(s) required for the impersonated access token, indicating the permissions needed for the short-lived token



56
57
58
# File 'lib/googleauth/impersonated_service_account.rb', line 56

def scope
  @scope
end

#source_credentialsObject (readonly)

Returns The modified version of base credentials, tailored for impersonation purposes with necessary scope adjustments.

Returns:

  • (Object)

    The modified version of base credentials, tailored for impersonation purposes with necessary scope adjustments



48
49
50
# File 'lib/googleauth/impersonated_service_account.rb', line 48

def source_credentials
  @source_credentials
end

Class Method Details

.make_creds(options = {}) ⇒ Google::Auth::ImpersonatedServiceAccountCredentials

Create a ImpersonatedServiceAccountCredentials When you use service account impersonation, you start with an authenticated principal (e.g. your user account or a service account) and request short-lived credentials for a service account that has the authorization that your use case requires.

Parameters:

  • options (Hash) (defaults to: {})

    A hash of options to configure the credentials.

Options Hash (options):

  • :base_credentials (Object) — default: required

    The authenticated principal. It will be used as following:

    • will be duplicated (with IAM scope) to create the source credentials if it supports duplication
    • as source credentials otherwise.
  • :impersonation_url (String) — default: required

    The URL to impersonate the service account. This URL should follow the format: https://iamcredentials.{universe_domain}/v1/projects/-/serviceAccounts/{source_sa_email}:generateAccessToken, where:

    • {universe_domain} is the domain of the IAMCredentials API endpoint (e.g., googleapis.com).
    • {source_sa_email} is the email address of the service account to impersonate.
  • :scope (Array<String>, String) — default: required

    The scope(s) for the short-lived impersonation token, defining the permissions required for the token.

  • :source_credentials (Object)

    The authenticated principal that will be used to fetch the short-lived impersonation access token. It is an alternative to providing the base credentials.

Returns:



89
90
91
# File 'lib/googleauth/impersonated_service_account.rb', line 89

def self.make_creds options = {}
  new options
end

Instance Method Details

#duplicate(options = {}) ⇒ Google::Auth::ImpersonatedServiceAccountCredentials

Creates a duplicate of these credentials without transient token state

Parameters:

  • options (Hash) (defaults to: {})

    Overrides for the credentials parameters. The following keys are recognized

    • base_credentials the base credentials used to initialize the impersonation
    • source_credentials the authenticated credentials which usually would be base credentials with scope overridden to IAM_SCOPE
    • impersonation_url the URL to use to make an impersonation token exchange
    • scope the scope(s) to access

Returns:



181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/googleauth/impersonated_service_account.rb', line 181

def duplicate options = {}
  options = deep_hash_normalize options

  options = {
    base_credentials: @base_credentials,
    source_credentials: @source_credentials,
    impersonation_url: @impersonation_url,
    scope: @scope
  }.merge(options)

  self.class.new options
end

#expires_within?(seconds) ⇒ Boolean

Determines whether the current access token expires within the specified number of seconds.

Parameters:

  • seconds (Integer)

    The number of seconds to check against the token's expiration time.

Returns:

  • (Boolean)

    Whether the access token expires within the given time frame



152
153
154
155
# File 'lib/googleauth/impersonated_service_account.rb', line 152

def expires_within? seconds
  # This method is needed for BaseClient
  @expires_at && @expires_at - Time.now.utc < seconds
end

#loggerLogger?

Returns The logger of the credentials.

Returns:

  • (Logger, nil)

    The logger of the credentials.



166
167
168
# File 'lib/googleauth/impersonated_service_account.rb', line 166

def logger
  @source_credentials.logger if source_credentials.respond_to? :logger
end

#universe_domainString

The universe domain of the impersonated credentials. Effectively this retrieves the universe domain of the source credentials.

Returns:

  • (String)

    The universe domain of the credentials.



161
162
163
# File 'lib/googleauth/impersonated_service_account.rb', line 161

def universe_domain
  @source_credentials.universe_domain
end