Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Clarify UDF documentation on required function type annotations. ([#757](https://github.com/Open-EO/openeo-python-client/issues/757))
- `OidcProviderInfo` no longer drops requested OIDC scopes that are not listed in the provider's `scopes_supported` discovery field which made it impossible to authenticate against such providers. ([#930](https://github.com/Open-EO/openeo-python-client/issues/930))

## [0.51.0] - 2026-07-16

Expand Down
6 changes: 4 additions & 2 deletions openeo/rest/auth/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,11 @@ def __init__(
except Exception as e:
raise OidcException(f"Failed to obtain OIDC discovery document from {self.discovery_url!r}: {e!r}") from e
self.issuer = issuer or self.config["issuer"]
# Minimal set of scopes to request
self._supported_scopes = self.config.get("scopes_supported", ["openid"])
self._scopes = {"openid"}.union(scopes or []).intersection(self._supported_scopes)
# Don't filter requested scopes against `scopes_supported`: it's only a RECOMMENDED
# discovery field (RFC 8414 section 2), and some providers (e.g. Microsoft Entra ID)
# report a fixed, incomplete list there regardless of which scopes they actually accept.
self._scopes = {"openid"}.union(scopes or [])
log.debug(f"Scopes: provider supported {self._supported_scopes} & backend desired {scopes} -> {self._scopes}")
self.default_clients = default_clients
self.authorization_parameters = authorization_parameters or {}
Expand Down
17 changes: 17 additions & 0 deletions tests/rest/auth/test_oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,23 @@ def test_provider_info_scopes(requests_mock):
).get_scopes_string()


def test_provider_info_scopes_not_in_scopes_supported(requests_mock):
"""
Requested scopes should be preserved even when the provider's `scopes_supported`
discovery field does not list them (e.g. Microsoft Entra ID, which reports a fixed
tenant-wide list there regardless of which custom scopes it actually accepts).
https://github.com/Open-EO/openeo-python-client/issues/930
"""
requests_mock.get(
"https://authit.test/.well-known/openid-configuration",
json={"scopes_supported": ["openid", "profile", "email", "offline_access"]},
)
provider = OidcProviderInfo(
issuer="https://authit.test", scopes=["openid", "profile", "email", "api://client-id/openeo"]
)
assert provider.get_scopes_string() == "api://client-id/openeo email openid profile"


def test_provider_info_default_client_none(requests_mock):
requests_mock.get("https://authit.test/.well-known/openid-configuration", json={})
info = OidcProviderInfo(issuer="https://authit.test")
Expand Down