Repository navigation
controller: rotate OpenAICredentials access tokens - #2815
Open
junfeiliu531 wants to merge 10 commits into
Open
junfeiliu531 wants to merge 10 commits into
junfeiliu531 wants to merge 10 commits into
Conversation
Add a tokenprovider.TokenProvider backed by the SPIFFE Workload API. It fetches a JWT-SVID for a fixed audience; the socket address is passed explicitly or falls back to SPIFFE_ENDPOINT_SOCKET. First step of theagentrouter#2791. Not wired into any rotator yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Add an OpenAICredentials type to v1beta1 for secretless access to OpenAI via OAuth 2.0 Token Exchange (RFC 8693). It carries optional organization/project IDs and a tokenExchange block (tokenURL, subjectTokenType defaulting to ...:token-type:jwt, audience, scopes). The subject token comes from exactly one of an OIDC client-credentials flow or a SPIFFE JWT-SVID (audience plus optional socketPath). v1beta1 only, following the CredentialOverride precedent. Part of theagentrouter#2791; the controller does not act on the new type yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Replace subjectToken.oidc (*egv1a1.OIDC) with oidcExchangeToken (*BackendSecurityPolicyOIDC), matching the field name and nesting of the AWS, Azure and GCP credential types. The controller can then read the OIDC config the same way for all four types. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Drop the subjectToken wrapper: oidcExchangeToken and the SPIFFE source now sit directly under tokenExchange, so "OIDC vs SPIFFE" can be spelled the same way if AWS/GCP/Azure gain a SPIFFE option later. Rename spiffe to spiffeJWTSVID (type BackendSecurityPolicySPIFFEJWTSVID) since nothing is exchanged when fetching it, and to leave room for an X.509-SVID source. Clarify which hop each audience/scopes field applies to. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Group the subject token sources under tokenExchange.subjectToken again, keeping the oidcExchangeToken and spiffeJWTSVID names. The wrapper keeps the sources separate from the exchange parameters and gives new sources an obvious home. Write the one-of rule as a list count so a new source only adds an entry to it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
The controller does not act on OpenAICredentials yet. Return a "not yet supported" error from credential rotation and the gateway auth translation instead of the generic unsupported-type errors, and handle the type in getBSPGeneratedSecretName so it cannot panic once rotation reaches it. Document which hop each audience field applies to. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Add filterapi.OpenAIAuth carrying an access token plus optional organization and project IDs. The handler sets Authorization: Bearer and, when configured, OpenAI-Organization and OpenAI-Project. The same headers are set when the token comes from a credential override. Part of theagentrouter#2791. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Add an RFC 8693 token exchange provider that wraps a subject token provider (SPIFFE JWT-SVID or OIDC), and an OpenAI token rotator that stores the exchanged access token in the generated BSP secret. Rotation follows the exchanged token's expires_in, falling back to the subject token's expiry when absent. Wire OpenAICredentials into the BSP controller and the gateway's filterapi translation, replacing the "not yet supported" errors, and default the credential override header to x-aigw-openai-access-token. Part of theagentrouter#2791. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Run the BackendSecurityPolicy controller against a fake SPIFFE Workload API and a fake token exchange endpoint, and check that the JWT-SVID is exchanged and the access token lands in the generated secret. Part of theagentrouter#2791. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
Add an OpenAICredentials example using a SPIFFE JWT-SVID, and note in the API docs that such policies act as the controller's SPIFFE identity. Mounting the Workload API socket into the controller is left to the deployment. Part of theagentrouter#2791. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Junfei Liu <jliu531@bloomberg.net>
✅ Deploy Preview for theagentrouter ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Second part of #2791: makes the
OpenAICredentialsBackendSecurityPolicy added in #2806 functional. The controller obtains a subject token (SPIFFE JWT-SVID or OIDC), exchanges it for an OpenAI access token via OAuth 2.0 Token Exchange (RFC 8693), and rotates it before it expires.Controller (
internal/controller)tokenprovider.NewTokenExchangeProvider: an RFC 8693 client wrapping any subjectTokenProvider. It sendssubject_token,subject_token_type, and the optionalaudienceandscope. The expiry comes fromexpires_in, falling back to the subject token's expiry when absent.rotators.NewOpenAITokenRotator: stores the access token underopenAIAccessTokenin the generatedai-eg-bsp-<name>secret, mirroring the Azure token rotator.subjectToken.spiffeJWTSVIDorsubjectToken.oidcExchangeToken. OIDC client secrets referenced from other namespaces go through the same ReferenceGrant check as AWS/Azure/GCP.filterapi.OpenAIAuth.credentialOverridedefaults to thex-aigw-openai-access-tokenheader.Data plane (
internal/backendauth)OpenAIAuthhandler setsAuthorization: Bearer <token>, plusOpenAI-OrganizationandOpenAI-Projectwhen configured. The same headers are set when the token comes from a credential override.Docs and example
examples/basic/openai-spiffe.yaml.spiffeJWTSVIDAPI doc notes that such policies act as the controller's SPIFFE identity, so only trusted cluster admins should create them.Related Issues/PRs (if applicable)
Part of #2791
Depends on #2806 (this branch includes its commits until it merges)
Special notes for reviewers (if applicable)
SPIFFE_ENDPOINT_SOCKETpointing at it) is left to the deployment. This PR makes no Helm changes.requested_token_type.tests/controllerruns the BSP controller against a fake SPIFFE Workload API and a fake token exchange endpoint. There is no kind e2e: that would require SPIRE in CI, and no other provider's token rotation has one.🤖 Generated with Claude Code [1]
1: https://claude.com/claude-code