# `Gemini.Auth.MetadataServer`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L1)

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.

# `error_reason`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L55)

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

# `available?`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L81)

```elixir
@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`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L139)

```elixir
@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`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L259)

```elixir
@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`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L179)

```elixir
@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`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/metadata_server.ex#L219)

```elixir
@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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
