Gemini.Auth.MetadataServer (GeminiEx v0.8.4)

View Source

Authentication via GCP metadata server for workloads running on Google Cloud Platform.

This module provides authentication for workloads running on:

  • Google Compute Engine
  • Google Kubernetes Engine (GKE)
  • Cloud Run
  • Cloud Functions
  • App Engine

The metadata server provides automatic authentication without requiring explicit credentials files, making it ideal for production deployments on GCP infrastructure.

Metadata Server Endpoint

The metadata server is available at http://metadata.google.internal/computeMetadata/v1/ and requires the Metadata-Flavor: Google header on all requests.

Features

  • Automatic token retrieval from GCP metadata server
  • Project ID detection
  • Availability checking (determines if running on GCP)
  • Service account information retrieval

Usage

# Check if running on GCP
if MetadataServer.available?() do
  # Get access token
  {:ok, token} = MetadataServer.get_access_token()

  # Get project ID
  {:ok, project_id} = MetadataServer.get_project_id()
end

Timeout Configuration

Metadata server checks use a short timeout (1 second) to quickly determine if the code is running on GCP. If the metadata server is not available, the check will fail fast.

Summary

Functions

Check if the GCP metadata server is available.

Get an access token from the GCP metadata server.

Get all metadata for the instance.

Get the GCP project ID from the metadata server.

Get the service account email from the metadata server.

Types

error_reason()

@type error_reason() :: String.t()

Functions

available?()

@spec available?() :: boolean()

Check if the GCP metadata server is available.

This function performs a quick check to determine if the code is running on Google Cloud Platform infrastructure with access to the metadata server.

Uses a 1-second timeout for fast failure in non-GCP environments.

Returns

  • true - Running on GCP with metadata server access
  • false - Not running on GCP or metadata server unavailable

Examples

if MetadataServer.available?() do
  # Running on GCP, can use metadata server
  {:ok, token} = MetadataServer.get_access_token()
else
  # Not on GCP, use other authentication method
  use_service_account_file()
end

get_access_token()

@spec get_access_token() ::
  {:ok, %{token: String.t(), expires_in: pos_integer()}}
  | {:error, error_reason()}

Get an access token from the GCP metadata server.

Retrieves a fresh access token for the default service account associated with the GCP resource (VM, Cloud Run instance, etc.).

The token will have the scopes assigned to the service account, which typically includes https://www.googleapis.com/auth/cloud-platform.

Returns

  • {:ok, %{token: token, expires_in: seconds}} - Successfully retrieved token
  • {:error, reason} - Failed to retrieve token

Examples

case MetadataServer.get_access_token() do
  {:ok, %{token: token, expires_in: ttl}} ->
    # Use token for API calls
    # Cache with TTL
    TokenCache.put("metadata_server", token, ttl)

  {:error, reason} ->
    Logger.error("Failed to get token: #{reason}")
end

get_instance_metadata()

@spec get_instance_metadata() :: {:ok, map()} | {:error, error_reason()}

Get all metadata for the instance.

Retrieves comprehensive metadata about the GCP instance, including service account information, project details, and instance attributes.

Returns

  • {:ok, metadata} - Map containing instance metadata
  • {:error, reason} - Failed to retrieve metadata

Examples

case MetadataServer.get_instance_metadata() do
  {:ok, metadata} ->
    IO.inspect(metadata, label: "Instance Metadata")

  {:error, reason} ->
    Logger.error("Failed to get metadata: #{reason}")
end

get_project_id()

@spec get_project_id() :: {:ok, String.t()} | {:error, error_reason()}

Get the GCP project ID from the metadata server.

Retrieves the project ID for the GCP project in which the code is running. This is useful when you need the project ID for Vertex AI or other GCP services but don't want to hardcode it.

Returns

  • {:ok, project_id} - Successfully retrieved project ID
  • {:error, reason} - Failed to retrieve project ID

Examples

case MetadataServer.get_project_id() do
  {:ok, project_id} ->
    # Use project_id for Vertex AI configuration
    %{project_id: project_id, location: "us-central1"}

  {:error, reason} ->
    Logger.error("Failed to get project ID: #{reason}")
end

get_service_account_email()

@spec get_service_account_email() :: {:ok, String.t()} | {:error, error_reason()}

Get the service account email from the metadata server.

Retrieves the email address of the default service account associated with the GCP resource.

Returns

  • {:ok, email} - Successfully retrieved service account email
  • {:error, reason} - Failed to retrieve email

Examples

case MetadataServer.get_service_account_email() do
  {:ok, email} ->
    Logger.info("Running as service account: #{email}")

  {:error, reason} ->
    Logger.error("Failed to get service account: #{reason}")
end