Gemini.Auth.JWT (GeminiEx v0.0.2)

View Source

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.

Summary

Functions

Create a JWT payload for Vertex AI authentication.

Create a signed JWT token using the most appropriate method.

Extract service account email from a service account key.

Load and parse a service account key file.

Sign a JWT payload using Google Cloud IAM signJwt API.

Sign a JWT payload using a service account private key.

Validate a JWT payload has all required fields.

Types

jwt_payload()

@type jwt_payload() :: %{
  iss: String.t(),
  aud: String.t(),
  sub: String.t(),
  iat: integer(),
  exp: integer()
}

service_account_key()

@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()
}

Functions

create_payload(service_account_email, audience, opts \\ [])

@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(service_account_email, audience, opts \\ [])

@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(map)

@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(file_path)

@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(payload, service_account_email, access_token)

@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(payload, map)

@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(arg1)

@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