dpop

package
v0.0.0-...-a43836d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// HeaderName is the HTTP header that carries the DPoP proof (RFC 9449 section 5).
	HeaderName = "DPoP"
	// NonceHeader is the HTTP response header carrying a fresh nonce (RFC 9449 section 8.3).
	NonceHeader = "DPoP-Nonce"

	// ErrorUseNonce signals the client to retry with a fresh nonce.
	ErrorUseNonce = "use_dpop_nonce"
	// ErrorInvalidProof signals a malformed, wrong, or replayed DPoP proof.
	ErrorInvalidProof = "invalid_dpop_proof"
	// ErrorInvalidBinding signals that the proof key does not match the access token's cnf.jkt.
	ErrorInvalidBinding = "invalid_token_binding"
)
View Source
const (
	DefaultProofMaxAge = 60 * time.Second
	DefaultFutureSkew  = 60 * time.Second
	DefaultJtiTTL      = 2 * time.Minute
)

Validation timing parameters shared by every service that enforces DPoP.

Variables

View Source
var (
	ErrMissingProof = newError(ErrorUseNonce, http.StatusBadRequest, "DPoP proof is required")
	ErrMissingNonce = newError(ErrorUseNonce, http.StatusBadRequest, "missing DPoP nonce")
	ErrInvalidNonce = newError(ErrorUseNonce, http.StatusBadRequest, "invalid or expired DPoP nonce")
	ErrReplay       = newError(ErrorInvalidProof, http.StatusBadRequest, "DPoP proof replay detected")
)

Predefined validation failures. Missing proofs/nonces are signalled with the use_dpop_nonce code so the client can retry with a fresh nonce (RFC 9449 section 8.3).

Functions

func RequestHTU

func RequestHTU(r *http.Request) string

RequestHTU reconstructs the client-facing request URI that a DPoP proof's htu must match, honoring the forwarded headers set by the gateway.

func Thumbprint

func Thumbprint(pub *ecdsa.PublicKey) (string, error)

Thumbprint computes the RFC 7638 SHA-256 thumbprint of an EC P-256 public key.

Types

type Error

type Error struct {
	Code    string
	Status  int
	Message string
}

Error carries an RFC 9449 error code and the HTTP status for a rejected proof.

func (*Error) Error

func (e *Error) Error() string

type NonceStore

type NonceStore interface {
	// ConsumeNonce atomically deletes the single-use nonce and reports whether
	// it existed (false => missing, reused, or expired).
	ConsumeNonce(ctx context.Context, nonce string) (bool, error)
	// ReserveJti atomically records the proof jti for the given TTL and reports
	// whether it was a brand-new value (false => replay detected).
	ReserveJti(ctx context.Context, jti string, ttl time.Duration) (bool, error)
}

NonceStore provides single-use nonces and jti replay detection. Implemented by each service over its Redis client, keeping the shared package free of storage-library dependencies.

type Proof

type Proof struct {
	Raw    string
	Header proofHeader
	Claims ProofClaims
	Key    *ecdsa.PublicKey
}

Proof is a parsed and validated-claim DPoP proof.

func ParseProof

func ParseProof(raw string) (*Proof, error)

ParseProof parses a compact JWS proof and extracts the embedded public key.

func (*Proof) Thumbprint

func (p *Proof) Thumbprint() (string, error)

Thumbprint returns the RFC 7638 SHA-256 thumbprint (jkt) of the proof key.

func (*Proof) Validate

func (p *Proof) Validate(method string, htu string, now time.Time, maxAge, futureSkew time.Duration) error

Validate checks the htm, htu, iat and jti claims of the proof against the request.

func (*Proof) VerifySignature

func (p *Proof) VerifySignature() error

VerifySignature verifies the JWS signature against the key embedded in the header.

type ProofClaims

type ProofClaims struct {
	Jti   string `json:"jti"`
	Htm   string `json:"htm"`
	Htu   string `json:"htu"`
	Iat   int64  `json:"iat"`
	Nonce string `json:"nonce,omitempty"`
}

ProofClaims are the registered claims of a DPoP proof (RFC 9449 section 4.2).

type Validator

type Validator struct {
	// NonceStore provides single-use nonces and jti replay detection. When nil,
	// nonce and replay checks are skipped (not for production).
	NonceStore NonceStore
	// IssueNonce creates and persists a fresh single-use nonce.
	IssueNonce func(ctx context.Context) (string, error)

	ProofMaxAge time.Duration
	FutureSkew  time.Duration
	JtiTTL      time.Duration
}

Validator runs the complete RFC 9449 proof validation sequence shared by the protected-route middleware and the token-issuing endpoints, so behaviour is consistent everywhere.

func (*Validator) Validate

func (v *Validator) Validate(ctx context.Context, r *http.Request) (*Proof, string, error)

Validate parses and validates the DPoP proof carried by r. On success it returns the proof and a fresh nonce to send back in the DPoP-Nonce response header. On failure it returns a *Error (along with a fresh nonce to challenge the client), or a plain error if the storage backend is unavailable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL