Skip to content

feat: support OAuth2 scopes for client credentials authentication#218

Merged
rhamzeh merged 2 commits into
mainfrom
feat/oauth2-scopes
May 20, 2026
Merged

feat: support OAuth2 scopes for client credentials authentication#218
rhamzeh merged 2 commits into
mainfrom
feat/oauth2-scopes

Conversation

@SoulPancake

@SoulPancake SoulPancake commented May 18, 2026

Copy link
Copy Markdown
Member
  • Add optional Scopes property to IClientCredentialsConfig and CredentialsConfig
  • Include scope parameter in OAuth2 token exchange request when configured
  • Make ApiAudience optional (standard OAuth2 servers don't require it)
  • Add tests for scopes inclusion, omission, and combined audience+scopes

Description

What problem is being solved?

How is it being solved?

What changes are made to solve it?

References

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Summary by CodeRabbit

Release Notes

  • New Features

    • Added OAuth2 scopes support to client credentials configuration, allowing scopes to be included in token requests.
  • Bug Fixes

    • ApiAudience parameter is now optional for OAuth2 authentication.
  • Tests

    • Added new test coverage for OAuth2 token request behavior with various scopes and audience configurations.

Review Change Stack

- Add optional `Scopes` property to `IClientCredentialsConfig` and `CredentialsConfig`
- Include `scope` parameter in OAuth2 token exchange request when configured
- Make `ApiAudience` optional (standard OAuth2 servers don't require it)
- Add tests for scopes inclusion, omission, and combined audience+scopes
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8cd3de8b-5b47-4fa7-a17b-c13af5b75469

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR makes ApiAudience optional in client credentials authentication and introduces OAuth2 Scopes configuration support. Configuration contracts add the optional Scopes field; the OAuth2Client conditionally includes both audience and scope parameters in token exchange requests; and validation and test coverage verify the optional behavior.

Changes

OAuth2 Scopes and Optional Audience

Layer / File(s) Summary
Configuration contracts and validation
src/OpenFga.Sdk/Configuration/Credentials.cs
IClientCredentialsConfig interface and CredentialsConfig struct add an optional Scopes field. ApiAudience documentation is updated to indicate it is optional and Auth0-specific. Validation in Credentials.EnsureValid() removes the requirement that ApiAudience be non-empty for ClientCredentials flow.
OAuth2Client parameter handling
src/OpenFga.Sdk/ApiClient/OAuth2Client.cs
OAuth2Client constructor now conditionally adds audience parameter only when ApiAudience is non-empty/whitespace, and conditionally adds scope parameter when Scopes is non-empty/whitespace, allowing flexible OAuth2 token requests.
Configuration and scope request tests
src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs, src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs
Existing ClientIdClientSecretRequired test updated to verify ApiAudience is optional and does not throw; four new OAuth2 scopes tests validate that scope and audience parameters are included or omitted in HTTP requests according to configuration.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Suggested reviewers

  • rhamzeh
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main feature addition: support for OAuth2 scopes in client credentials authentication, which aligns with all the key changes across the modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/oauth2-scopes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@SoulPancake SoulPancake linked an issue May 18, 2026 that may be closed by this pull request
1 task
@SoulPancake SoulPancake marked this pull request as ready for review May 18, 2026 07:55
@SoulPancake SoulPancake requested a review from a team as a code owner May 18, 2026 07:55
Copilot AI review requested due to automatic review settings May 18, 2026 07:55

Copilot AI 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.

Pull request overview

This PR extends the SDK’s OAuth2 client-credentials authentication to optionally request OAuth2 scopes, while also making ApiAudience optional to support standard OAuth2 token servers.

Changes:

  • Added optional Scopes to the client-credentials configuration model.
  • Included the scope parameter in the OAuth2 token exchange request when configured.
  • Updated validation/tests to allow client-credentials auth without an ApiAudience.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/OpenFga.Sdk/Configuration/Credentials.cs Adds Scopes to credential config and makes ApiAudience optional in validation.
src/OpenFga.Sdk/ApiClient/OAuth2Client.cs Adds scope to the token request body when configured; avoids sending empty/whitespace audience.
src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs Adds coverage for including/omitting scopes and for running without audience.
src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs Updates validation expectations to reflect optional ApiAudience.
Comments suppressed due to low confidence (3)

src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs:366

  • Avoid calling .Result on ReadAsStringAsync() inside async tests; it blocks the thread and can lead to deadlocks or wrapped exceptions. Make the mock delegate async and await request.Content.ReadAsStringAsync(ct) instead.
                .ReturnsAsync((HttpRequestMessage request, CancellationToken ct) => {
                    requestBody = request.Content?.ReadAsStringAsync().Result;
                    return CreateTokenResponse();

src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs:404

  • Avoid calling .Result on ReadAsStringAsync() inside async tests; it blocks the thread and can lead to deadlocks or wrapped exceptions. Make the mock delegate async and await request.Content.ReadAsStringAsync(ct) instead.
                .ReturnsAsync((HttpRequestMessage request, CancellationToken ct) => {
                    requestBody = request.Content?.ReadAsStringAsync().Result;
                    return CreateTokenResponse();

src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs:445

  • Avoid calling .Result on ReadAsStringAsync() inside async tests; it blocks the thread and can lead to deadlocks or wrapped exceptions. Make the mock delegate async and await request.Content.ReadAsStringAsync(ct) instead.
                    ItExpr.IsAny<CancellationToken>())
                .ReturnsAsync((HttpRequestMessage request, CancellationToken ct) => {
                    requestBody = request.Content?.ReadAsStringAsync().Result;
                    return CreateTokenResponse();

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/OpenFga.Sdk/Configuration/Credentials.cs
Comment thread src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/OpenFga.Sdk/Configuration/Credentials.cs`:
- Around line 80-86: IClientCredentialsConfig was extended with a new Scopes
property which is a breaking change for existing implementors; to avoid breaking
consumers, add a default interface implementation for the Scopes property on
IClientCredentialsConfig (implement a getter that returns null and a no-op
setter) so existing implementers continue to compile, or alternatively revert
the change and introduce a new interface (e.g., IClientCredentialsConfigV2 with
the Scopes property) and keep the original IClientCredentialsConfig unchanged;
reference the interface name IClientCredentialsConfig and the Scopes property
when making the change and update documentation/release notes if you decide to
make it a breaking major-version change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f488754e-62d3-4f60-922b-79558df065af

📥 Commits

Reviewing files that changed from the base of the PR and between 01f588a and 5494afc.

📒 Files selected for processing (4)
  • src/OpenFga.Sdk.Test/Api/OpenFgaApiTests.cs
  • src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs
  • src/OpenFga.Sdk/ApiClient/OAuth2Client.cs
  • src/OpenFga.Sdk/Configuration/Credentials.cs

Comment thread src/OpenFga.Sdk/Configuration/Credentials.cs
Comment thread src/OpenFga.Sdk.Test/ApiClient/OAuth2ClientTests.cs
@rhamzeh rhamzeh added this pull request to the merge queue May 20, 2026
Merged via the queue into main with commit ff9fcff May 20, 2026
25 checks passed
@rhamzeh rhamzeh deleted the feat/oauth2-scopes branch May 20, 2026 14:58
@openfga-releaser-bot openfga-releaser-bot Bot mentioned this pull request May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Oauth2 scopes for authentication

3 participants