fix(sdk/go): honor gateway-configured oidc scopes in interactive flows - #3284
Open
rhuss wants to merge 3 commits into
Open
fix(sdk/go): honor gateway-configured oidc scopes in interactive flows#3284rhuss wants to merge 3 commits into
rhuss wants to merge 3 commits into
Conversation
`loginConfig.applyDefaults()` keyed off the zero value rather than set-ness, so it could not distinguish an unset field from one a caller explicitly set to its zero value: - `WithTimeout(0)` was silently replaced by the 2m default. - `WithScopes()` (explicit empty) was replaced by the default scopes, even though `WithScopes` already records `scopesSet`. Switch `applyDefaults` to consult the `*Set` sentinels, add a `timeoutSet` sentinel set by `WithTimeout`, and guard the client-credentials exchange so a zero timeout means "no deadline" instead of creating an already-expired context (matching Login and DeviceFlow). `WithTimeout(0)` now means "no timeout". Unset fields still receive their defaults; non-zero explicit values are unaffected. Signed-off-by: Roland Huß <rhuss@redhat.com>
Login and DeviceLogin authenticate a user, so their requests must be
OpenID Connect ones. Both passed the caller's scopes through verbatim,
so WithScopes("profile") produced an authorization request without
"openid", and buildAuthURL set the parameter unconditionally, so an
explicitly-empty list emitted a bare "scope=".
Normalize the scopes for both interactive flows: "openid" is placed
first and a caller-supplied duplicate is dropped, with the remaining
scopes keeping their order. This mirrors build_scopes in
crates/openshell-cli/src/oidc_auth.rs, which the Go SDK did not follow.
The client credentials grant is left untouched. It has no user and no
ID token, so it keeps sending exactly what the caller asked for,
matching build_ci_scopes.
Also document the WithTimeout contract: the flows all gate on
timeout > 0, so any non-positive duration means "no deadline".
Signed-off-by: Roland Huß <rhuss@redhat.com>
A gateway's metadata.json carries oidc_scopes, and the Rust CLI feeds it into every flow it starts (commands/gateway.rs passes metadata.oidc_scopes to both the interactive and the client-credentials paths). The Go SDK read the field in resolveClientCredentialsConfig only, so Login and DeviceLogin silently ignored it and always used the built-in defaults. Resolve gateway scopes in both interactive flows using the same rule the client-credentials path already applies: they fill only genuinely-unset scopes, so an explicit WithScopes still wins. The openid normalization now runs after gateway resolution, so scopes coming from metadata.json are normalized too. Behavior change: a gateway with oidc_scopes set in metadata.json now affects Login and DeviceLogin from the Go SDK, matching the CLI. Signed-off-by: Roland Huß <rhuss@redhat.com>
rhuss
requested review from
a team,
derekwaynecarr,
mrunalp and
sjenning
as code owners
September 11, 2026 13:58
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.
Summary
A gateway's
metadata.jsoncarriesoidc_scopes, and the Rust CLI feeds it into every flow it starts:commands/gateway.rsreadsmetadata.oidc_scopesand passes it to both the interactive path and the client-credentials path.The Go SDK reads that field in
resolveClientCredentialsConfigonly.LoginandDeviceLoginsilently ignored it and always used the built-in defaults (openid profile email), so a gateway registered with custom scopes got them for machine-to-machine auth but not for user login.This resolves gateway scopes in both interactive flows using the same rule the client-credentials path already applies: they fill only genuinely-unset scopes, so an explicit
WithScopesstill wins.Behavior change: a gateway with
oidc_scopesset inmetadata.jsonnow affectsLoginandDeviceLoginfrom the Go SDK, matching what the CLI has always done.Related Issue
No separate issue. This is a localized bug fix bringing the Go SDK in line with existing CLI behavior for a metadata field the SDK already parses, in the same spirit as #3235 (which this stacks on).
Depends on #3235. That PR adds the
requireOpenIDScope()normalization this one reorders, so merge it first.Because the branch is stacked on a fork, GitHub cannot target #3235's branch directly, so the diff below currently includes that PR's commit as well. Review only
fix(sdk/go): honor gateway-configured oidc scopes in interactive flows(2dd564c); the diff resolves itself once #3235 lands.Changes
oidc.go:resolveOIDCConfigresolvesgwCfg.OIDCScopesinto unset scopes, mirroringcredentials.go.Loginnow normalizesopenidafter gateway resolution rather than before, so scopes frommetadata.jsonare normalized too.device.go: the same resolution inDeviceLogin's gateway block, with the same reordering.openid, explicitWithScopeswins, emptyoidc_scopesfalls back to defaults). ExtractedsetupScopeCapturingDeviceProviderso the device tests share one mock provider.Testing
mise run go:cigreen: build,golangci-lint(0 issues),gofmt, fullgo test -race, proto-check, docs-check.mise run pre-commitgreen.TestLogin_GatewayScopesandTestDeviceLogin_GatewayScopes.Checklist