Skip to content

feat(plugin): add dpop plugin for RFC 9449 proof-of-possession#13161

Closed
Alnyli07 wants to merge 3 commits into
apache:masterfrom
Alnyli07:feat/plugin-dpop
Closed

feat(plugin): add dpop plugin for RFC 9449 proof-of-possession#13161
Alnyli07 wants to merge 3 commits into
apache:masterfrom
Alnyli07:feat/plugin-dpop

Conversation

@Alnyli07
Copy link
Copy Markdown

@Alnyli07 Alnyli07 commented Apr 5, 2026

Description

Add dpop plugin for RFC 9449 DPoP (Demonstrating Proof of Possession) validation. This plugin enforces sender-constrained access tokens at the API gateway level, preventing token theft and replay attacks with zero changes to upstream services.

Fixes #11219

Why a Separate Plugin?

DPoP is a proof-of-possession layer, not an authentication mechanism. It complements existing auth plugins (openid-connect, jwt-auth, multi-auth) rather than replacing them. It runs at priority 2601 to rewrite Authorization: DPoPAuthorization: Bearer before downstream auth plugins process the token.

Features

  • Full RFC 9449 DPoP proof validation (typ, alg, htm, htu, iat, ath, jti)
  • DPoP proof signature verification (ES256/384/512, RS256/384/512, PS256/384/512)
  • JWK Thumbprint binding (cnf.jkt) per RFC 7638
  • Access token signature verification via JWKS (OIDC discovery or direct URI)
  • Token introspection fallback (RFC 7662) for opaque tokens
  • Distributed JTI replay protection (memory / Redis / Infinispan, configurable fallback strategy)
  • Bearer downgrade detection
  • DPoPBearer header rewrite + DPoP-Thumbprint header injection
  • Selective enforcement via uri_allow
  • Structured audit logging with OpenTelemetry trace_id correlation

A Go WASM version (proxy-wasm-go-sdk v0.24.0) is also available at Keymate-io/keymate-apisix-dpop-plugin.

Files Changed

File Description
apisix/plugins/dpop.lua Plugin implementation (1384 LOC)
conf/config.yaml.example Plugin registration (priority 2601)
docs/en/latest/plugins/dpop.md English documentation
t/plugin/dpop.t 15 Test::Nginx test cases

Tested With

  • Apache APISIX 3.11.0
  • Keycloak 26.0 (any RFC 9449-compliant IdP)
  • 58 E2E checks (k6), 49 Postman requests in our upstream repo
  • Dependencies: only libraries already in APISIX (resty.openssl, resty.http, resty.redis, resty.lrucache)

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible

Add DPoP (Demonstrating Proof of Possession) validation plugin that
enforces sender-constrained access tokens at the API gateway level.

- Full RFC 9449 DPoP proof validation (typ, alg, htm, htu, iat, ath, jti)
- JWK Thumbprint binding (cnf.jkt) per RFC 7638
- Token introspection fallback (RFC 7662) for opaque tokens
- Distributed JTI replay protection (memory/Redis/Infinispan)
- Bearer downgrade detection
- Authorization header rewrite (DPoP → Bearer) for upstream compatibility
- Selective enforcement via uri_allow
- 15 Test::Nginx test cases
- English documentation in APISIX format

Signed-off-by: Ali Tuğrul Pınar <ali@keymate.io>
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Apr 5, 2026
@dosubot dosubot Bot added enhancement New feature or request plugin labels Apr 5, 2026
Alnyli07 added 2 commits April 5, 2026 14:45
Signed-off-by: Ali Tuğrul Pınar <ali@keymate.io>
Signed-off-by: Ali Tuğrul Pınar <ali@keymate.io>
@Alnyli07 Alnyli07 closed this Apr 6, 2026
@Alnyli07 Alnyli07 changed the title feat(plugin): add keymate-dpop plugin for RFC 9449 proof-of-possession feat(plugin): add dpop plugin for RFC 9449 proof-of-possession Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request plugin size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: support DPoP in OpenID Connect/OAuth2 plugin

1 participant