Skip to content

feat(auth): add OAuth2 client credentials support (alpha) - #8486

Merged
leandrodamascena merged 8 commits into
aws-powertools:developfrom
bfreiberg:feat/auth-alpha-oauth2-8466
Sep 30, 2026
Merged

leandrodamascena merged 8 commits into
aws-powertools:developfrom
bfreiberg:feat/auth-alpha-oauth2-8466

Conversation

@bfreiberg

@bfreiberg bfreiberg commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Issue number: closes #8489

Summary

Lambda functions calling an OAuth2-protected API currently need to manage token exchange, secret retrieval, token lifetimes, and concurrent refresh themselves. This adds OAuth2Client under utilities.auth_alpha.oauth2

Changes

  • Support the client_credentials grant with client_secret_basic, configurable scopes, and mutually exclusive audience or RFC 8707 resource selection.
  • Keep token caches private to each client. Reacquire tokens on demand when 30 seconds remain, coordinate concurrent exchanges, and avoid caching tokens with short or missing lifetimes.
  • Accept a secret string or callable, invoking the callable on each exchange attempt so applications can use Parameters or another secret provider.
  • Provide auth_headers() for application-owned HTTP clients and a synchronous HTTPS request() helper. Disable redirects and downstream retries, reject competing Authorization headers, and use separate acquisition and downstream budgets.
  • Share credential-free errors and transport helpers with JWT verification, preserving existing JWT exception imports. Check response-read deadlines through headers, bodies, and chunked framing; keep the existing JSON response-size limit.
  • Add a lazy [oauth2] extra requiring only urllib3, dependency-isolation tests, functional and local TLS tests, Lambda examples, API documentation, and a downstream MCP example.

Only client-credentials acquisition is included. Interactive grants, delegated token exchange, introspection, other client authentication methods, and a native async API remain outside this change.

User experience

Install aws-lambda-powertools[oauth2] and configure a client outside the Lambda handler:

import os

from aws_lambda_powertools.utilities.auth_alpha import OAuth2Client

inventory_api = OAuth2Client(
    token_url=os.environ["TOKEN_URL"],
    client_id=os.environ["CLIENT_ID"],
    client_secret=lambda: os.environ["CLIENT_SECRET"],
    resource="https://inventory.example.com",
    scopes=["inventory:read"],
)


def lambda_handler(event, context):
    response = inventory_api.request(
        "GET", "https://inventory.example.com/stock", timeout=5,
    )
    if response.status != 200:
        raise RuntimeError("Inventory lookup failed")
    return response.json()

Applications can instead obtain headers with inventory_api.auth_headers(). The guide includes a Parameters secret loader, testing examples, and guidance on trusted destinations, secret rotation, provider resource selection, and timeout limitations. The namespace remains experimental and its API may change before GA.

Validation

  • Full non-performance suite on Python 3.14: 3,047 passed, 4 existing skips, 96.77% coverage.
  • Authentication functional and real TLS tests on Python 3.10 and 3.12: 473 passed on each version. TLS cases cover certificate trust, redirects, response limits, slow headers/body/chunk framing, concurrent deadlines, and recovery after timeouts.
  • Lambda examples: 7 passed. Performance suite: 10 passed when run independently. Two existing Metrics tests with a 2 ms SLA exceeded that threshold while running alongside the package build, then passed in isolation.
  • JWT-only and OAuth-only Nox dependency sessions pass; OAuth imports and operates without PyJWT or cryptography.
  • Ruff formatting/lint, mypy, ty, Bandit, complexity limits, staged Gitleaks scan, Poetry lock validation, wheel/sdist builds, Markdown lint, and the documentation build pass.
  • Independent implementation and specification reviews completed; identified issues were addressed and covered by regression tests.

Validation uses a local TLS token endpoint. Live identity-provider interoperability and AWS deployment tests were not run. The documentation build retains existing warnings about unrelated links and external assets.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Sep 24, 2026
@boring-cyborg boring-cyborg Bot added dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tests labels Sep 24, 2026
Comment thread aws_lambda_powertools/utilities/auth_alpha/oauth2/client.py Fixed
@bfreiberg
bfreiberg marked this pull request as ready for review September 24, 2026 13:41
@bfreiberg
bfreiberg requested a review from a team as a code owner September 24, 2026 13:41
@bfreiberg
bfreiberg requested a review from svozza September 24, 2026 13:41
@codecov

codecov Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.44904% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.88%. Comparing base (172fe26) to head (b81815d).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
...a_powertools/utilities/auth_alpha/oauth2/client.py 99.01% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8486      +/-   ##
===========================================
+ Coverage    96.81%   96.88%   +0.06%     
===========================================
  Files          310      317       +7     
  Lines        15594    15899     +305     
  Branches      1361     1395      +34     
===========================================
+ Hits         15098    15403     +305     
  Misses         361      361              
  Partials       135      135              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bfreiberg
bfreiberg force-pushed the feat/auth-alpha-oauth2-8466 branch from a54d477 to 7c848b7 Compare September 28, 2026 07:58
@leandrodamascena
leandrodamascena force-pushed the feat/auth-alpha-oauth2-8466 branch 2 times, most recently from 7c848b7 to 19e8b03 Compare September 29, 2026 23:24
@sonarqubecloud

Copy link
Copy Markdown

@leandrodamascena leandrodamascena 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.

Thanks for the amazing work here @bfreiberg! Approved!

@mergify

mergify Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again.

@leandrodamascena
leandrodamascena merged commit b1af7e8 into aws-powertools:develop Sep 30, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC: OAuth2 client credentials support (alpha)

3 participants