class Google::Auth::GCECredentials

the GCE metadata server.
Extends Signet::OAuth2::Client so that the auth token is obtained from

def add_universe_domain_to hash

def add_universe_domain_to hash
  return if @universe_domain_overridden
  universe_domain =
    if disable_universe_domain_check
      # TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
      "googleapis.com"
    else
      Google::Cloud.env.lookup_metadata "universe", "universe-domain"
    end
  universe_domain = "googleapis.com" if !universe_domain || universe_domain.empty?
  hash["universe_domain"] = universe_domain.strip
end

def adjust_for_stale_expires_in hash, retrieval_time

second to offset any skew from metadata server latency.
We also ensure expires_in is conservative; subtracting at least 1
stale. Update it based on the time since the data was retrieved.
The response might have been cached, which means expires_in might be
def adjust_for_stale_expires_in hash, retrieval_time
  return unless hash["expires_in"].is_a? Numeric
  offset = 1 + (Process.clock_gettime(Process::CLOCK_MONOTONIC) - retrieval_time).round
  hash["expires_in"] -= offset if offset.positive?
  hash["expires_in"] = 0 if hash["expires_in"].negative?
end

def build_metadata_request_params

Returns:
  • (Array) - The query parameters and endpoint path

Other tags:
    Private: -
def build_metadata_request_params
  query, entry =
    if token_type == :id_token
      [{ "audience" => target_audience, "format" => "full" }, "service-accounts/default/identity"]
    else
      [{}, "service-accounts/default/token"]
    end
  query[:scopes] = Array(scope).join "," if scope
  [query, entry]
end

def build_token_hash body, content_type, retrieval_time

Returns:
  • (Hash) - A hash containing:

Parameters:
  • retrieval_time (Float) -- The monotonic time when the response was retrieved
  • content_type (String) -- The content type of the response
  • body (String) -- The response body from the metadata server

Other tags:
    Private: -
def build_token_hash body, content_type, retrieval_time
  hash =
    if ["text/html", "application/text"].include? content_type
      parse_encoded_token body
    else
      Signet::OAuth2.parse_credentials body, content_type
    end
  add_universe_domain_to hash
  adjust_for_stale_expires_in hash, retrieval_time
  hash
end

def compute_auth_token_uri

Other tags:
    Private: - Unused and deprecated
def compute_auth_token_uri
  "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/token".freeze
end

def compute_check_uri

Other tags:
    Private: - Unused and deprecated
def compute_check_uri
  "http://#{metadata_host}".freeze
end

def compute_id_token_uri

Other tags:
    Private: - Unused and deprecated
def compute_id_token_uri
  "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/identity".freeze
end

def duplicate options = {}

Parameters:
  • options (Hash) -- Overrides for the credentials parameters.
def duplicate options = {}
  options = deep_hash_normalize options
  super(
    {
      universe_domain_overridden: @universe_domain_overridden
    }.merge(options)
  )
end

def fetch_access_token _options = {}

Raises:
  • (Google::Auth::AuthorizationError) - If metadata server is unavailable or returns error
  • (Google::Auth::UnexpectedStatusError) - On unexpected HTTP status codes

Returns:
  • (Hash) - The token data hash

Parameters:
  • _options (Hash) -- Options for token fetch (not used)
def fetch_access_token _options = {}
  query, entry = build_metadata_request_params
  begin
    log_fetch_query
    resp = Google::Cloud.env.lookup_metadata_response "instance", entry, query: query
    log_fetch_resp resp
    handle_metadata_response resp
  rescue Google::Cloud::Env::MetadataServerNotResponding => e
    log_fetch_err e
    raise AuthorizationError.with_details(
      e.message,
      credential_type_name: self.class.name,
      principal: principal
    )
  end
end

def handle_metadata_response resp

Raises:
  • (Google::Auth::UnexpectedStatusError, Google::Auth::AuthorizationError) - On error

Returns:
  • (Hash) - The token hash on success

Parameters:
  • resp (Google::Cloud::Env::MetadataResponse) -- The metadata server response

Other tags:
    Private: -
def handle_metadata_response resp
  case resp.status
  when 200
    build_token_hash resp.body, resp.headers["content-type"], resp.retrieval_monotonic_time
  when 403, 500
    raise Signet::UnexpectedStatusError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
  when 404
    raise Signet::AuthorizationError, NO_METADATA_SERVER_ERROR
  else
    raise Signet::AuthorizationError, "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
  end
end

def initialize options = {}

Construct a GCECredentials
def initialize options = {}
  # Override the constructor to remember whether the universe domain was
  # overridden by a constructor argument.
  @universe_domain_overridden = options["universe_domain"] || options[:universe_domain]
  # TODO: Remove when universe domain metadata endpoint is stable (see b/349488459).
  @disable_universe_domain_check = true
  super options
end

def log_fetch_err _err

def log_fetch_err _err
  logger&.info do
    Google::Logging::Message.from(
      message: "MDS did not respond to token request",
      "credentialsId" => object_id
    )
  end
end

def log_fetch_query

def log_fetch_query
  if token_type == :id_token
    logger&.info do
      Google::Logging::Message.from(
        message: "Requesting id token from MDS with aud=#{target_audience}",
        "credentialsId" => object_id
      )
    end
  else
    logger&.info do
      Google::Logging::Message.from(
        message: "Requesting access token from MDS",
        "credentialsId" => object_id
      )
    end
  end
end

def log_fetch_resp resp

def log_fetch_resp resp
  logger&.info do
    Google::Logging::Message.from(
      message: "Received #{resp.status} from MDS",
      "credentialsId" => object_id
    )
  end
end

def metadata_host

Other tags:
    Private: - Unused and deprecated
def metadata_host
  ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST
end

def on_gce? _options = {}, _reload = false # rubocop:disable Style/OptionalBooleanParameter

rubocop:disable Style/OptionalBooleanParameter
The parameters are deprecated and unused.
is available.
Detect if this appear to be a GCE instance, by checking if metadata
def on_gce? _options = {}, _reload = false # rubocop:disable Style/OptionalBooleanParameter
  Google::Cloud.env.metadata?
end

def parse_encoded_token body

def parse_encoded_token body
  hash = { token_type.to_s => body }
  if token_type == :id_token
    expires_at = expires_at_from_id_token body
    hash["expires_at"] = expires_at if expires_at
  end
  hash
end

def principal

Returns:
  • (Symbol) - :gce to represent Google Compute Engine identity

Other tags:
    Private: -
def principal
  :gce_metadata
end

def reset_cache

def reset_cache
  Google::Cloud.env.compute_metadata.reset_existence!
  Google::Cloud.env.compute_metadata.cache.expire_all!
end

def universe_domain

Other tags:
    Private: -
def universe_domain
  value = super
  return value unless value.nil?
  fetch_access_token!
  super
end

def update! options = {}

Returns:
  • (Google::Auth::GCECredentials) -

Parameters:
  • options (Hash) -- Overrides for the credentials parameters.
def update! options = {}
  # Normalize all keys to symbols to allow indifferent access.
  options = deep_hash_normalize options
  @universe_domain_overridden = options[:universe_domain_overridden] if options.key? :universe_domain_overridden
  super(options)
  self
end