Skip to content

Conversation

@developerkunal
Copy link
Contributor

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

🔧 Changes

This PR implements RFC 9449 DPoP (Demonstrating Proof-of-Possession) support for sender-constrained OAuth 2.0 tokens, providing enhanced security by binding tokens to cryptographic key pairs.

Core Package Changes:

  • Added unified Validator interface supporting both JWT and DPoP validation methods
  • Implemented CheckTokenWithDPoP method in core.Core for framework-agnostic validation
  • Added DPoP context support for accessing proof claims in request handlers
  • Implemented three operational modes: DPoPDisabled, DPoPIfPresent (default), DPoPRequired
  • Added DPoP-specific error codes: ErrorCodeDPoPProofMissing, ErrorCodeDPoPProofInvalid, ErrorCodeDPoPBindingMismatch

Middleware Changes:

  • Automatic DPoP/Bearer token scheme detection from Authorization header
  • DPoP header extraction and validation with configurable extractors
  • Added options: WithDPoPMode, WithDPoPProofOffset, WithDPoPIATLeeway, WithDPoPHeaderExtractor
  • Trusted proxy support via WithTrustedProxies for URL reconstruction behind reverse proxies
  • Enhanced error handling with DPoP-specific error messages

Validator Package:

  • Added ValidateDPoPProof method to Validator struct
  • Implemented dpop+jwt type validation per RFC 9449
  • JWK thumbprint computation and verification (SHA-256)
  • Required claims validation: jti, htm, htu, iat
  • Configurable proof age offset (default: 5 minutes) and IAT leeway (default: 5 seconds)

New Files:

  • core/dpop.go - Core DPoP validation logic
  • dpop.go - HTTP middleware DPoP helpers
  • proxy.go - Trusted proxy URL reconstruction
  • validator/dpop.go - DPoP proof validation
  • validator/dpop_claims.go - DPoP claims interface

Examples:

  • examples/http-dpop-example - Full DPoP implementation with optional Bearer fallback
  • examples/http-dpop-required - Strict DPoP enforcement mode
  • examples/http-dpop-disabled - Explicit DPoP opt-out for legacy systems
  • examples/http-dpop-trusted-proxy - Production deployment behind reverse proxies

Breaking Changes: None - fully backward compatible with existing Bearer token implementations. DPoP is opt-in via token scheme or explicit mode configuration.

📚 References

🔬 Testing

Test Coverage:

  • 70+ new test cases covering all DPoP scenarios
  • Integration tests for all three DPoP modes
  • Edge cases: expired proofs, mismatched claims (JKT, HTM, HTU), invalid signatures
  • Trusted proxy URL reconstruction tests
  • Maintained 95%+ code coverage (95.1% main, 94.0% core)

Manual Testing:
All example applications include integration tests demonstrating:

  1. Valid DPoP token validation with proof
  2. Bearer token validation (when allowed by mode)
  3. Missing DPoP proof detection
  4. JKT mismatch detection
  5. HTTP method/URL mismatch detection
  6. Expired/future proof handling
  7. Multiple DPoP headers handling
  8. Trusted proxy header processing

Verification:

  • ✅ All tests passing (5/5 packages)
  • ✅ 0 linting issues (19 active linters)
  • ✅ Race detector clean
  • ✅ No breaking changes to existing API

Implements RFC 9449 DPoP support for sender-constrained OAuth 2.0 tokens.

Key Features:
- Unified Validator interface supporting both JWT and DPoP validation
- Three DPoP modes: Disabled, DPoPIfPresent (default), DPoPRequired
- Automatic DPoP/Bearer token scheme detection
- DPoP proof validation (HTM, HTU, JKT claims)
- Trusted proxy support for URL reconstruction
- Configurable proof age offset and IAT leeway

Core Changes:
- Added CheckTokenWithDPoP method to core.Core
- Implemented DPoP context for accessing proof claims
- Added DPoP-specific error codes and handling

Validator:
- Added ValidateDPoPProof method
- JWK thumbprint computation and verification
- dpop+jwt type validation

Middleware:
- WithDPoPMode, WithDPoPProofOffset, WithDPoPIATLeeway options
- WithDPoPHeaderExtractor for custom header extraction
- WithTrustedProxies for reverse proxy deployments

Examples:
- http-dpop-example: Full DPoP with Bearer fallback
- http-dpop-required: Strict DPoP enforcement
- http-dpop-disabled: Explicit opt-out
- http-dpop-trusted-proxy: Production behind proxies

Tests: 70+ new tests, 95%+ coverage maintained
@developerkunal developerkunal requested a review from a team as a code owner November 27, 2025 05:50
@codecov-commenter
Copy link

codecov-commenter commented Nov 27, 2025

Codecov Report

❌ Patch coverage is 91.05691% with 44 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.75%. Comparing base (41c59e8) to head (9b10ec5).

Files with missing lines Patch % Lines
core/dpop.go 90.27% 8 Missing and 6 partials ⚠️
validator/dpop.go 83.56% 6 Missing and 6 partials ⚠️
proxy.go 92.22% 4 Missing and 3 partials ⚠️
middleware.go 88.67% 3 Missing and 3 partials ⚠️
validator/validator.go 86.36% 1 Missing and 2 partials ⚠️
option.go 91.66% 2 Missing ⚠️
Additional details and impacted files
@@                           Coverage Diff                           @@
##           v3-phase1-pr6-documentation-linting     #363      +/-   ##
=======================================================================
- Coverage                                98.86%   95.75%   -3.12%     
=======================================================================
  Files                                       12       18       +6     
  Lines                                      707     1177     +470     
=======================================================================
+ Hits                                       699     1127     +428     
- Misses                                       4       27      +23     
- Partials                                     4       23      +19     

☔ View full report in Codecov by Sentry.
📢 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.

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.

3 participants