Skip to content

fix: configurable oauth scope instead of hardcoded 'openid' scope - #2566

Merged
Strum355 merged 1 commit into
guacsec:mainfrom
Strum355:TC-5584
Aug 12, 2026
Merged

fix: configurable oauth scope instead of hardcoded 'openid' scope#2566
Strum355 merged 1 commit into
guacsec:mainfrom
Strum355:TC-5584

Conversation

@Strum355

@Strum355 Strum355 commented Aug 11, 2026

Copy link
Copy Markdown
Member

AWS Cognito rejects client_credential grant requests containing system-reserved scopes such as openid, therefore we can't force the scope in the general case. From previous testing, the openid scope was required for Keycloak auth with EI, hence the original introduction of the hard-coded openid scope. This PR introduces the option to set a scope if necessary, leaving it unset by default (some cognito & keycloak setups may require custom scopes to be requested that cannot be set as default scopes for whatever reasons).

From the AWS docs for machine-to-machine authorization "You can authorize only custom scopes from resource servers in access tokens for client credentials grants."

Fixes TC-5584

Summary by Sourcery

Make OAuth scopes configurable for OpenID client_credentials flows instead of hardcoding the openid scope, with sensible defaults and propagation through configuration and provider code.

New Features:

  • Add CLI and environment configuration options to specify OAuth scope(s) for EI OIDC and generic OpenID token providers.
  • Support multiple space-separated OAuth scopes for client_credentials token requests, while allowing no scope parameter to be sent by default.

Enhancements:

  • Propagate the configured OAuth scope from argument structs into OpenID provider configuration and runtime, including token refresh and initial acquisition logic.

Tests:

  • Extend OIDC argument and configuration tests to cover scope defaults and propagation into the resulting config.

@Strum355
Strum355 requested a review from a team August 11, 2026 10:39
@sourcery-ai

sourcery-ai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR makes the OAuth scope used for client_credentials flows configurable instead of hard-coded to "openid", plumbs the new optional scope through CLI/env configuration, OpenID provider config, and token acquisition/refresh logic, and adds tests ensuring correct propagation and defaults.

Sequence diagram for client_credentials flow with configurable scope

sequenceDiagram
    participant Args as OpenIdTokenProviderConfigArguments
    participant Config as OpenIdTokenProviderConfig
    participant Provider as OpenIdTokenProvider
    participant Client as openid::Client

    Args->>Config: try_from_arguments(arguments)
    Config-->>Config: set scope Option<String>
    Config->>Provider: from_config(config)
    Provider-->>Provider: store scope

    rect rgb(230,230,250)
    note over Provider,Client: Initial client_credentials token
    Provider->>Client: request_token_using_client_credentials(scope.as_deref())
    Client-->>Provider: TemporalBearerGuard
    end

    rect rgb(230,250,230)
    note over Provider,Client: Refreshing token when refresh_token is present
    Provider->>Client: refresh_token(current_token, scope.as_deref())
    Client-->>Provider: TemporalBearerGuard
    end
Loading

File-Level Changes

Change Details Files
Add configurable OAuth scope to EI OIDC CLI/config and ensure it propagates into the internal config representation.
  • Introduce optional scope field on EiOidcArguments with CLI flag and environment variable wiring.
  • Pass the scope from EiOidcArguments into the constructed EI OIDC config in into_config.
  • Extend existing EI OIDC tests to cover default None scope and add a new test to verify scope propagation.
server/src/profile/api.rs
Extend OpenID token provider configuration and runtime behavior to support an optional scope for client_credentials, removing the hard-coded "openid" scope.
  • Add optional scope to OpenIdTokenProviderConfigArguments with CLI flag and environment variable wiring and set default dev mode config scope to None.
  • Add optional scope field to OpenIdTokenProviderConfig and propagate it from arguments and devmode defaults.
  • Update OpenIdTokenProvider to store scope, accept it in constructors, and carry it through configuration-based initialization.
  • Change token refresh to pass the configured scope to refresh_token and change initial token acquisition to request client_credentials with the configured scope instead of the hard-coded "openid".
common/auth/src/client/provider/openid.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Changing the default from always requesting openid to sending no scope by default alters behavior for existing deployments; consider preserving the previous default (or adding an explicit compatibility switch) so Keycloak-based setups don’t silently lose scopes after upgrade.
  • Since multiple scopes are encoded as a space-separated string, you might want a small helper or type to construct/validate scopes (e.g., from Vec<String>), to avoid subtle formatting issues and make multi-scope usage clearer at call sites.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Changing the default from always requesting `openid` to sending no scope by default alters behavior for existing deployments; consider preserving the previous default (or adding an explicit compatibility switch) so Keycloak-based setups don’t silently lose scopes after upgrade.
- Since multiple scopes are encoded as a space-separated string, you might want a small helper or type to construct/validate scopes (e.g., from `Vec<String>`), to avoid subtle formatting issues and make multi-scope usage clearer at call sites.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

default_value = "false"
)]
pub tls_insecure: bool,
/// OAuth scope(s) to request in the client_credentials token request.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is a breaking change ? what happens with existing deployments (and have we tested )

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is essentially building upon #2552, so there should be nothing breaking here. We're bringing back the default of no scope being explicitly requested, with an option to request scopes if necessary. What possible breaking change did you have in mind?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess my request is if we have tested with an existing env which has named scope and if there is any migration path concerns ... if you have none, then I have none ;)

@@ -243,7 +258,11 @@ impl OpenIdTokenProvider {
Some(current_token) => {
log::debug!("Refreshing token ... ");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just noticed while in the area - I think this should be converted to tracing call (As per CONVENTIONS.md)

@rh-jfuller rh-jfuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as long as this change has been tested with appropriate existing deployments LGTM

@Strum355
Strum355 added this pull request to the merge queue Aug 12, 2026
Merged via the queue into guacsec:main with commit 9c48530 Aug 12, 2026
17 of 18 checks passed
@Strum355
Strum355 deleted the TC-5584 branch August 12, 2026 11:50
@github-project-automation github-project-automation Bot moved this to Done in Trustify Aug 12, 2026
@trustify-ci-bot

Copy link
Copy Markdown

Successfully created backport PR for release/0.6.z:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants