OpenAiWorkloadIdentity unstable
The OpenAiWorkloadIdentity module authenticates OpenAiClient with
workload identity federation.
Constructors
Creates an HttpClient transform that authenticates OpenAI requests with
workload identity federation.
When to use
Use as the transformClient option of OpenAiClient instead of an API key.
Details
The first request runs identityToken and exchanges the result at
https://auth.openai.com/oauth/token with the token-exchange grant. The
access token is cached and sent as Authorization: Bearer until shortly
before it expires. Concurrent requests share one exchange. identityToken
runs again on every exchange, so a token read from a file is picked up after
it rotates. Surrounding whitespace is trimmed.
Exchanges use the HttpClient captured by make, not the transformed client.
Failures are HttpClientErrors, mapped to AiError by OpenAiClient.
A failing or empty identityToken produces an EncodeError. Source failures
are preserved as causes and must not contain secrets. Exchange errors redact
the literal identity token, including JSON-escaped occurrences.
In WebSocket mode the access token is resolved each time a socket connects.
Gotchas
- No background refresh: the next request after expiry waits for an exchange.
- A 401 invalidates only the token used by that request, without replay.
- A WebSocket keeps the token it connected with. A rejected WebSocket handshake does not discard the cached token, because the socket does not report the response status.
- The exchange client must not follow redirects or log request bodies.
FetchHttpClientredirects are disabled; redirect responses fail the exchange. - The exchange is never retried.
- The token URL must use
https, orhttponlocalhost,127.0.0.1or::1. Any other URL is a defect. - Leave the
apiKeyoption ofOpenAiClientunset. The access token replaces it. - The access token is not accepted by the Admin API.
See
- layer for providing the transformed
HttpClientas a layer
Signature
declare function make<E = never, R = never>(options: Options<E, R>): Effect<(client: HttpClient) => HttpClient, never, HttpClient | R>Example Reading a projected Kubernetes token
import { OpenAiClient, OpenAiWorkloadIdentity } from "@effect/ai-openai"import { Effect, FileSystem, Layer, Redacted } from "effect"
// Provide an `HttpClient` and a `FileSystem` to this layer.const OpenAiLayer = Layer.unwrap(Effect.gen(function*() { const fs = yield* FileSystem.FileSystem const transformClient = yield* OpenAiWorkloadIdentity.make({ identityToken: Effect.map( fs.readFileString("/var/run/secrets/openai.com/token"), Redacted.make ), identityProviderId: "idp_...", serviceAccountId: "sa_..." }) return OpenAiClient.layer({ transformClient })}))Layers
Provides the current HttpClient authenticated with workload identity federation.
When to use
Use with Layer.provide to authenticate OpenAiClient without
setting its transformClient option.
Details
Applies make to the current client, which also performs token exchanges.
The layer requires the services needed by identityToken.
Gotchas
- Every request carries the access token regardless of URL. Provide this
layer only to
OpenAiClient, not the whole application. - An
apiKeyoption ofOpenAiClientreplaces the access token here, so leave it unset. - The other gotchas of
makeapply.
See
- make for the client transform this layer applies
Signature
declare function layer<E = never, R = never>(options: Options<E, R>): Layer<HttpClient, never, HttpClient | R>Example
import { OpenAiClient, OpenAiWorkloadIdentity } from "@effect/ai-openai"import { Effect, FileSystem, Layer, Redacted } from "effect"
const WorkloadIdentity = OpenAiWorkloadIdentity.layer({ identityToken: Effect.gen(function*() { const fs = yield* FileSystem.FileSystem return Redacted.make(yield* fs.readFileString("/var/run/secrets/openai.com/token")) }), identityProviderId: "idp_...", serviceAccountId: "sa_..."})
// Requires an `HttpClient` and a `FileSystem`.const OpenAiLayer = OpenAiClient.layer({}).pipe( Layer.provide(WorkloadIdentity))Options
Options for authenticating OpenAI requests with Workload Identity Federation.
See
Signature
type Options<E = never, R = never> = { readonly identityProviderId: string; readonly identityToken: Effect.Effect<Redacted.Redacted<string>, E, R>; readonly identityTokenType?: "jwt" | "id_token"; readonly serviceAccountId: string; readonly tokenUrl?: string;}