Support client_credentials flow with JWT and Basic auth
Summary
Implements SEP-1046 OAuth client_credentials flow support with simplified providers for machine-to-machine authentication.
New OAuth Providers
-
ClientCredentialsOAuthProvider: Forclient_credentialsgrant with client_id + client_secret- Supports
client_secret_basic(default) andclient_secret_postauth methods - Sets
client_infodirectly, bypassing dynamic client registration
- Supports
-
PrivateKeyJWTOAuthProvider: Forclient_credentialsgrant withprivate_key_jwtauthentication (RFC 7523 Section 2.2)- Takes an
assertion_providercallback that receives the audience (authorization server's issuer identifier per RFC 7523bis) and returns a JWT - Designed for workload identity federation (GCP, AWS IAM, Azure AD)
- Takes an
-
SignedJWTParameters: Helper class for SDK-signed JWT assertionscreate_assertion_provider()returns a callback for use withPrivateKeyJWTOAuthProvider
-
static_assertion_provider(): Helper for pre-built JWTs that don't need the audience parameter
Deprecation
RFC7523OAuthClientProvider is now deprecated with a DeprecationWarning.
The original implementation incorrectly used RFC 7523 Section 2.1 (jwt-bearer authorization grant where the JWT itself is the authorization) instead of the intended Section 2.2 (private_key_jwt client authentication with grant_type=client_credentials).
Use ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider instead.
Example Usage
# Simple client credentials with client_id + secret
provider = ClientCredentialsOAuthProvider(
server_url="https://api.example.com",
storage=my_token_storage,
client_id="my-client-id",
client_secret="my-client-secret",
)
# Private key JWT with workload identity federation
async def get_workload_identity_token(audience: str) -> str:
return await fetch_token_from_identity_provider(audience=audience)
provider = PrivateKeyJWTOAuthProvider(
server_url="https://api.example.com",
storage=my_token_storage,
client_id="my-client-id",
assertion_provider=get_workload_identity_token,
)
# Private key JWT with SDK-signed assertions
jwt_params = SignedJWTParameters(
issuer="my-client-id",
subject="my-client-id",
signing_key=private_key_pem,
)
provider = PrivateKeyJWTOAuthProvider(
server_url="https://api.example.com",
storage=my_token_storage,
client_id="my-client-id",
assertion_provider=jwt_params.create_assertion_provider(),
)
Testing
- Unit tests with 100% coverage for new providers
- Conformance tests pending