Skip to content

Validate DPoP proofs in /oauth2/token/verify forward-auth endpoint #193

@rsharath

Description

@rsharath

Summary

The forward-auth endpoint /oauth2/token/verify (used by nginx auth_request, Traefik forwardAuth, Caddy forward_auth) currently validates the presented token as a Bearer token only — signature + real-time revocation check — and returns identity claims as response headers. It does not validate a DPoP proof. As a result, DPoP-bound (sender-constrained) tokens terminated at a reverse proxy are not actually proof-of-possession-checked at the edge.

Current behavior

internal/handler/auth_verify.go — reads the Authorization: Bearer header, introspects (signature + revocation), returns 200 + identity headers or 401. No DPoP header handling, no cnf.jkt binding check.

Proposed change

Extend /oauth2/token/verify to optionally accept and validate a DPoP proof (RFC 9449):

  • Read the DPoP request header alongside Authorization.
  • When the access token carries a cnf.jkt confirmation claim (i.e. it's DPoP-bound), require a valid DPoP proof and verify the proof's public key thumbprint matches cnf.jkt.
  • Validate the proof htm/htu against the forwarded method/URI (the proxy must pass the original method + URL; document the required forwarded headers per proxy).
  • Reuse the existing pkg/dpop primitives.
  • On failure, return 401 with an appropriate WWW-Authenticate: DPoP challenge.

This lets reverse proxies enforce sender-constrained tokens without each upstream re-implementing DPoP.

References

  • RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP)
  • Existing primitives: pkg/dpop

Reported by Andrii Deinega via WIMSE WG review of ZeroID.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions