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

JWT token generation and management for Google Cloud service accounts.

This module handles JWT creation and signing for Vertex AI authentication
based on the documentation in v1.md. It supports both service account key files
and the Google Cloud IAM signJwt API.

# `jwt_payload`

```elixir
@type jwt_payload() :: %{
  :iss =&gt; String.t(),
  :aud =&gt; String.t(),
  :sub =&gt; String.t(),
  :iat =&gt; integer(),
  :exp =&gt; integer(),
  optional(:scope) =&gt; String.t(),
  optional(atom()) =&gt; any()
}
```

# `service_account_key`

```elixir
@type service_account_key() :: %{
  type: String.t(),
  project_id: String.t(),
  private_key_id: String.t(),
  private_key: String.t(),
  client_email: String.t(),
  client_id: String.t(),
  auth_uri: String.t(),
  token_uri: String.t(),
  auth_provider_x509_cert_url: String.t(),
  client_x509_cert_url: String.t()
}
```

# `create_payload`

```elixir
@spec create_payload(String.t(), String.t(), keyword()) :: jwt_payload()
```

Create a JWT payload for Vertex AI authentication.

## Parameters
- `service_account_email`: The email of the service account (issuer)
- `audience`: The audience for the JWT (must match deployment config)
- `opts`: Optional parameters
  - `:lifetime` - Token lifetime in seconds (default: 3600)
  - `:issued_at` - Custom issued at time (default: current time)

## Examples

    iex> payload = Gemini.Auth.JWT.create_payload(
    ...>   "my-service@project.iam.gserviceaccount.com",
    ...>   "my-app-audience"
    ...> )
    iex> payload.iss
    "my-service@project.iam.gserviceaccount.com"

# `create_signed_token`

```elixir
@spec create_signed_token(String.t(), String.t(), keyword()) ::
  {:ok, String.t()} | {:error, term()}
```

Create a signed JWT token using the most appropriate method.

This function automatically chooses between local signing (if private key is available)
or IAM API signing (if access token is provided).

## Examples

    # Using service account key file
    iex> {:ok, token} = Gemini.Auth.JWT.create_signed_token(
    ...>   "my-service@project.iam.gserviceaccount.com",
    ...>   "my-app-audience",
    ...>   service_account_key: "/path/to/key.json"
    ...> )

    # Using IAM API
    iex> {:ok, token} = Gemini.Auth.JWT.create_signed_token(
    ...>   "my-service@project.iam.gserviceaccount.com",
    ...>   "my-app-audience",
    ...>   access_token: "ya29.access-token"
    ...> )

# `get_service_account_email`

```elixir
@spec get_service_account_email(service_account_key()) :: String.t()
```

Extract service account email from a service account key.

## Examples

    iex> key = %{client_email: "my-service@project.iam.gserviceaccount.com"}
    iex> Gemini.Auth.JWT.get_service_account_email(key)
    "my-service@project.iam.gserviceaccount.com"

# `load_service_account_key`

```elixir
@spec load_service_account_key(String.t()) ::
  {:ok, service_account_key()} | {:error, term()}
```

Load and parse a service account key file.

## Examples

    iex> {:ok, key} = Gemini.Auth.JWT.load_service_account_key("/path/to/key.json")
    iex> key.client_email
    "my-service@project.iam.gserviceaccount.com"

# `sign_with_iam_api`

```elixir
@spec sign_with_iam_api(jwt_payload(), String.t(), String.t()) ::
  {:ok, String.t()} | {:error, term()}
```

Sign a JWT payload using Google Cloud IAM signJwt API.

This method uses the Google Cloud IAM service to sign the JWT, which requires
the caller to have the `roles/iam.serviceAccountTokenCreator` role.

## Parameters
- `payload`: The JWT payload to sign
- `service_account_email`: The service account email
- `access_token`: A valid access token for authentication

## Examples

    iex> payload = %{iss: "...", aud: "...", sub: "...", iat: 123, exp: 456}
    iex> {:ok, token} = Gemini.Auth.JWT.sign_with_iam_api(
    ...>   payload,
    ...>   "my-service@project.iam.gserviceaccount.com",
    ...>   "ya29.access-token"
    ...> )

# `sign_with_key`

```elixir
@spec sign_with_key(jwt_payload(), service_account_key()) ::
  {:ok, String.t()} | {:error, term()}
```

Sign a JWT payload using a service account private key.

This method signs the JWT locally using the private key from the service account JSON file.

## Examples

    iex> key = %{private_key: "-----BEGIN PRIVATE KEY-----...", client_email: "..."}
    iex> payload = %{iss: "...", aud: "...", sub: "...", iat: 123, exp: 456}
    iex> {:ok, token} = Gemini.Auth.JWT.sign_with_key(payload, key)

# `validate_payload`

```elixir
@spec validate_payload(jwt_payload()) :: :ok | {:error, String.t()}
```

Validate a JWT payload has all required fields.

## Examples

    iex> payload = %{iss: "test", aud: "test", sub: "test", iat: 123, exp: 456}
    iex> Gemini.Auth.JWT.validate_payload(payload)
    :ok

---

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