Repository navigation
Accept OIDC ID tokens presented with the Bearer scheme - #8081
Open
santhosh-shanmugham wants to merge 1 commit into
Open
santhosh-shanmugham wants to merge 1 commit into
santhosh-shanmugham wants to merge 1 commit into
Conversation
flyteadmin already accepts an ID token from its userAuth OIDC provider over gRPC when the client sends it with the IDToken scheme, which is how the console authenticates. Some clients can only send Bearer: flytectl's ExternalCommand auth type and flytekit's external_process mode hardcode that scheme. Today such a token fails access-token validation against the authorization server and the request is rejected, even though flyteadmin could have verified it as an ID token. When a Bearer token fails validation as an access token and is not accompanied by an IDToken-scheme token, try it as an ID token from the userAuth provider before rejecting the request, on both the gRPC interceptor and the HTTP path. Verification is identical to the IDToken scheme: signature, issuer, audience (the userAuth client id) and expiry through go-oidc. Tokens that fail as both are rejected as before, with the ID token error added to the message. This lets a host without a browser log in through the provider's device flow and hand the ID token to a stock flytectl via ExternalCommand. It is the server-side complement to flyteorg#8080, which teaches the client to send the IDToken scheme itself. Signed-off-by: Santhosh Shanmugham <sshanmugham@waabi.ai>
santhosh-shanmugham
marked this pull request as ready for review
September 25, 2026 17:46
2 tasks done
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Empty OIDC client IDs can bypass audience, issuer, and expiry validation, and authentication errors are mislabeled.
Review effort: Balanced
Findings: 2
Open (3)
What changed in this PR
Enables FlyteAdmin to validate OIDC ID tokens presented using the Bearer scheme.
Changes:
- Adds Bearer-to-ID-token fallback for gRPC and HTTP authentication.
- Shares ID-token identity extraction logic.
- Adds OIDC-backed acceptance and rejection tests.
| File | Description |
|---|---|
flyteadmin/auth/token.go |
Adds Bearer ID-token extraction and shared validation. |
flyteadmin/auth/handlers.go |
Integrates fallback into gRPC and HTTP authentication. |
flyteadmin/auth/bearer_id_token_test.go |
Tests Bearer ID-token validation scenarios. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+450
to
+452
| if provider := authCtx.OidcProvider(); provider != nil { | ||
| identityCtx, idTokenErr := IdentityContextFromIDTokenToken(ctx, tokenStr, authCtx.Options().UserAuth.OpenID.ClientID, | ||
| provider, nil) |
Comment on lines
+119
to
+121
| if provider == nil { | ||
| return nil, errors.Errorf(ErrJwtValidation, "no OIDC provider configured to validate a bearer token as an ID token") | ||
| } |
| if (isFromHTTP && !authCtx.Options().DisableForHTTP) || | ||
| (!isFromHTTP && !authCtx.Options().DisableForGrpc) { | ||
| err := fmt.Errorf("id token err: %w, access token err: %w", fmt.Errorf("access token err: %w", accessTokenErr), idTokenErr) | ||
| err := fmt.Errorf("id token err: %w, access token err: %w, bearer id token err: %w", fmt.Errorf("access token err: %w", accessTokenErr), idTokenErr, bearerIDTokenErr) |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8081 +/- ##
==========================================
+ Coverage 57.32% 57.46% +0.14%
==========================================
Files 931 931
Lines 58315 58341 +26
==========================================
+ Hits 33427 33527 +100
+ Misses 21835 21749 -86
- Partials 3053 3065 +12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
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.


Tracking issue
Related to #8080, the client-side complement (flytectl learns to send the
IDTokenscheme itself). Either change alone is enough for the headless use case; together they cover both stock and updated clients.Why are the changes needed?
flyteadmin accepts an OIDC ID token from its
userAuth.openIdprovider over gRPC when the token is sent asIDToken <jwt>; that is how the console authenticates (GetAuthenticationInterceptorfalls back toGRPCGetIdentityFromIDToken). Several clients can only sendBearer: flytectl'sExternalCommandauth type and flytekit'sexternal_processmode both hardcode it. A user who obtains an ID token out of band, for example through the provider's device authorization grant on a host with no browser, has no way to present it: the token fails validation as an access token and the request is rejected, even though flyteadmin could have verified it.Flyte's built-in authorization server has no device authorization endpoint, so this is the shortest route to a headless, per-user login without moving a deployment to an external authorization server.
What changes were proposed in this pull request?
IDToken-scheme token is present,GetAuthenticationInterceptortries the bearer token as an ID token (GRPCGetIdentityFromBearerIDToken). Verification is the same code as theIDTokenscheme:IdentityContextFromIDTokenToken, so go-oidc checks signature, issuer, theuserAuth.openId.clientIdaudience and expiry. TheUserInfo-binmetadata handling is shared through a small helper.IdentityContextFromRequestdoes the same forAuthorization: Beareron the REST path, returning both errors when neither validation succeeds.OidcProviderconfigured skip the new step.How was this patch tested?
New
bearer_id_token_test.gowith anhttptestOIDC provider (discovery document plus JWKS for a generated RSA key, ID tokens signed withgolang-jwt, both already dependencies):Beareris accepted and yields the token's subject with theallscope; the same token asIDTokenstill works; a token for another audience is rejected withUnauthenticated; a garbage bearer token is rejected; with no OIDC provider configured the request is rejected as before.Beareris accepted; wrong audience is rejected.go test ./auth/passes,go vetclean,golangci-lint run --new-from-rev=upstream/master ./auth/...reports no new issues.End to end, before this change, against a flyteadmin on the self authorization server with Dex as
userAuth.openId: a stock flytectl configured withExternalCommandand a command that prints a Dex ID token fails with... access token err: crypto/rsa: verification error ... Request unauthenticated with IDToken, which is the code path this PR extends. The same token sent asIDToken(via grpcurl and via a flytectl built from #8080) is accepted andget projectsucceeds as the user.Labels