class Google::Auth::GCECredentials

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

Constants

COMPUTE_AUTH_TOKEN_URI

@private Unused and deprecated

COMPUTE_CHECK_URI

@private Unused and deprecated

COMPUTE_ID_TOKEN_URI

@private Unused and deprecated

DEFAULT_METADATA_HOST

The IP Address is used in the URIs to speed up failures on non-GCE systems.

Public Class Methods

compute_auth_token_uri() click to toggle source
# File lib/googleauth/compute_engine.rb, line 61
def compute_auth_token_uri
  "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/token".freeze
end
compute_check_uri() click to toggle source
# File lib/googleauth/compute_engine.rb, line 57
def compute_check_uri
  "http://#{metadata_host}".freeze
end
compute_id_token_uri() click to toggle source
# File lib/googleauth/compute_engine.rb, line 65
def compute_id_token_uri
  "#{compute_check_uri}/computeMetadata/v1/instance/service-accounts/default/identity".freeze
end
metadata_host() click to toggle source
# File lib/googleauth/compute_engine.rb, line 53
def metadata_host
  ENV.fetch "GCE_METADATA_HOST", DEFAULT_METADATA_HOST
end
on_gce?(options = {}) click to toggle source

Detect if this appear to be a GCE instance, by checking if metadata is available.

# File lib/googleauth/compute_engine.rb, line 71
def on_gce? options = {}
  # TODO: This should use google-cloud-env instead.
  c = options[:connection] || Faraday.default_connection
  headers = { "Metadata-Flavor" => "Google" }
  resp = c.get compute_check_uri, nil, headers do |req|
    req.options.timeout = 1.0
    req.options.open_timeout = 0.1
  end
  return false unless resp.status == 200
  resp.headers["Metadata-Flavor"] == "Google"
rescue Faraday::TimeoutError, Faraday::ConnectionFailed
  false
end

Public Instance Methods

fetch_access_token(options = {}) click to toggle source

Overrides the super class method to change how access tokens are fetched.

# File lib/googleauth/compute_engine.rb, line 90
def fetch_access_token options = {}
  c = options[:connection] || Faraday.default_connection
  retry_with_error do
    uri = target_audience ? GCECredentials.compute_id_token_uri : GCECredentials.compute_auth_token_uri
    query = target_audience ? { "audience" => target_audience, "format" => "full" } : {}
    query[:scopes] = Array(scope).join "," if scope
    resp = c.get uri, query, "Metadata-Flavor" => "Google"
    case resp.status
    when 200
      content_type = resp.headers["content-type"]
      if ["text/html", "application/text"].include? content_type
        { (target_audience ? "id_token" : "access_token") => resp.body }
      else
        Signet::OAuth2.parse_credentials resp.body, content_type
      end
    when 403, 500
      msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
      raise Signet::UnexpectedStatusError, msg
    when 404
      raise Signet::AuthorizationError, NO_METADATA_SERVER_ERROR
    else
      msg = "Unexpected error code #{resp.status} #{UNEXPECTED_ERROR_SUFFIX}"
      raise Signet::AuthorizationError, msg
    end
  end
end