Class: Keycardai::OAuth::GCPMetadataTokenSource

Inherits:
Object
  • Object
show all
Defined in:
lib/keycardai/oauth/token_sources.rb

Overview

Fetches an identity token from the GCP metadata server. Covers GKE, GCE, and Cloud Run.

Constant Summary collapse

DEFAULT_METADATA_URL =
"http://metadata.google.internal"
IDENTITY_PATH =
"/computeMetadata/v1/instance/service-accounts/default/identity"

Instance Method Summary collapse

Constructor Details

#initialize(audience:, metadata_url: DEFAULT_METADATA_URL, timeout: nil, http_client: HTTP::NetHTTPClient.new) ⇒ GCPMetadataTokenSource

Returns a new instance of GCPMetadataTokenSource.

Parameters:

  • audience (String)

    the aud claim the platform mints into the token

  • metadata_url (String) (defaults to: DEFAULT_METADATA_URL)

    override for testing

  • timeout (Numeric, nil) (defaults to: nil)
  • http_client (#get) (defaults to: HTTP::NetHTTPClient.new)

    pluggable transport

Raises:



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/keycardai/oauth/token_sources.rb', line 82

def initialize(audience:, metadata_url: DEFAULT_METADATA_URL, timeout: nil,
               http_client: HTTP::NetHTTPClient.new)
  if audience.nil? || audience.empty?
    raise WorkloadIdentityConfigurationError.new("GCPMetadataTokenSource requires an audience",
                                                 source: "gcp-metadata")
  end

  @audience = audience
  @metadata_url = 
  @timeout = timeout
  @http_client = http_client
end

Instance Method Details

#identity_tokenString

Returns the current platform token.

Returns:

  • (String)

    the current platform token

Raises:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/keycardai/oauth/token_sources.rb', line 97

def identity_token
  url = "#{@metadata_url}#{IDENTITY_PATH}?#{URI.encode_www_form("audience" => @audience, "format" => "full")}"
  response = begin
    @http_client.get(url, headers: { "Metadata-Flavor" => "Google" }, timeout: @timeout)
  rescue NetworkError => e
    raise WorkloadIdentityRuntimeError.new("metadata server unreachable: #{e.message}", source: "gcp-metadata")
  end
  unless response.success?
    raise WorkloadIdentityRuntimeError.new("metadata server returned HTTP #{response.status}",
                                           source: "gcp-metadata")
  end

  response.body
end

#source_identifierObject



112
113
114
# File 'lib/keycardai/oauth/token_sources.rb', line 112

def source_identifier
  "gcp-metadata"
end