GcpCompute.TokenProvider behaviour (GcpCompute v0.3.0)

Copy Markdown View Source

Behaviour for minting the OAuth2 access tokens used to authenticate Compute API requests.

The library never hard-depends on a particular auth mechanism. A GcpCompute.Config holds a {module, arg} pair; before each request the configured module.fetch_token(arg) is invoked.

Built-in implementations:

Writing your own

defmodule MyApp.WorkloadIdentity do
  @behaviour GcpCompute.TokenProvider

  @impl true
  def fetch_token(_arg) do
    # ... fetch from the metadata server, Vault, etc.
    {:ok, %{token: token, expires: unix_seconds}}
  end
end

then GcpCompute.Config.new(token_provider: {MyApp.WorkloadIdentity, []}, ...).

Summary

Types

A minted token.

Callbacks

Return a valid access token, or an error.

Types

token()

@type token() :: %{
  :token => String.t(),
  optional(:type) => String.t(),
  optional(:expires) => non_neg_integer()
}

A minted token.

Only :token is required. :type and :expires are advisory metadata that this library deliberately does not read: GcpCompute holds no token cache, so there is nothing for an expiry to invalidate. Caching and refresh are the provider's job (as in Goth), which is the only place that can renew a credential. The fields are part of the type so a provider can surface them to its own callers and so %{token: _} maps from Goth pass through unchanged.

Callbacks

fetch_token(arg)

@callback fetch_token(arg :: term()) :: {:ok, token()} | {:error, term()}

Return a valid access token, or an error.

Implementations are expected to cache/refresh internally (as Goth does) — fetch_token/1 is called on every request and must be cheap on the hot path.

Return {:ok, %{token: binary}} or {:error, reason}. Anything else — an unwrapped token, nil, a 3-tuple — is rejected with %GcpCompute.Error{reason: :invalid_token_provider_return} before any request is sent, and the returned value is kept only in the error's redacted :body. Put no credential in an error reason: it can reach logs.