Help us shape the future of Go! Take the 2026 Go Developer Survey

dpopproof

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package dpopproof verifies DPoP proofs (RFC 9449) for servers that issue or accept DPoP-bound tokens, and yields a Proof only for a proof that passed every check, so a token is bound only to a key its client proved it holds.

A Checker verifies the proof's signature and typ, that its htm and htu match the request, that it is fresh (iat), that its jti has not been seen before (ReplayCache), that it carries the hash of the access token when one is presented (ath), and, when server nonces are on, that it carries a nonce this server issued recently.

Index

Constants

View Source
const DefaultNonceLifetime = 5 * time.Minute

DefaultNonceLifetime is how long a server nonce is accepted when NewNonces is given none.

Variables

View Source
var (
	// ErrMissing is returned when a request carries no DPoP proof.
	ErrMissing = errors.New("dpopproof: DPoP proof required")
	// ErrInvalid is returned for a proof that fails verification, or for a
	// request with more than one DPoP header.
	ErrInvalid = errors.New("dpopproof: invalid DPoP proof")
	// ErrReplayed is returned for a proof whose jti was already used.
	ErrReplayed = fmt.Errorf("%w: replayed", ErrInvalid)
	// ErrUseNonce is returned when server nonces are on and the proof
	// carries no nonce, or one this server did not issue recently. The
	// client should retry with the nonce in the DPoP-Nonce response header.
	ErrUseNonce = errors.New("dpopproof: DPoP proof must carry a fresh server nonce")
	// ErrReplayCacheRequired is returned by NewChecker without a replay
	// cache.
	ErrReplayCacheRequired = errors.New("dpopproof: Config.ReplayCache is required")
)
View Source
var Algorithms = []string{"ES256", "ES384", "ES512"}

Algorithms are the JWS algorithms accepted for proofs, as advertised in dpop_signing_alg_values_supported.

View Source
var ErrNonceSecret = fmt.Errorf("dpopproof: the nonce secret must be at least %d bytes", minNonceSecret)

ErrNonceSecret is returned by NewNonces for a short secret.

Functions

func Present

func Present(r *http.Request) bool

Present reports whether r carries a DPoP header.

func Proofs

func Proofs(r *http.Request) []string

Proofs returns the DPoP header values of r.

Types

type Checker

type Checker struct {
	// contains filtered or unexported fields
}

Checker verifies DPoP proofs.

func NewChecker

func NewChecker(cfg Config) (*Checker, error)

NewChecker returns a Checker for cfg.

func (*Checker) Check

func (c *Checker) Check(ctx context.Context, r *http.Request, target Target) (*Proof, error)

Check verifies the DPoP proof of r for target. It returns ErrMissing when r carries none; ErrInvalid (or ErrReplayed) for a bad proof or more than one DPoP header; ErrUseNonce when a server nonce is required. Other errors come from the replay cache.

func (*Checker) Nonce

func (c *Checker) Nonce() (string, error)

Nonce returns a fresh server nonce for the DPoP-Nonce response header, or "" when server nonces are off.

func (*Checker) NoncesRequired

func (c *Checker) NoncesRequired() bool

NoncesRequired reports whether proofs must carry a server nonce.

func (*Checker) Verify

func (c *Checker) Verify(ctx context.Context, proof string, target Target) (*Proof, error)

Verify verifies one DPoP proof for target; see Check.

type Config

type Config struct {
	// MaxAge is how old a proof's iat may be. Default: 5 minutes.
	MaxAge time.Duration

	// ClockSkew is how far a proof's iat may be in the future, and is added
	// to MaxAge. Default: 30 seconds.
	ClockSkew time.Duration

	// ReplayCache rejects a proof whose jti was used before (required).
	ReplayCache ReplayCache

	// Nonces, when set, requires every proof to carry a nonce it issued
	// (RFC 9449 §8), which bounds how long a proof made ahead of time is
	// usable whatever its iat says.
	Nonces *Nonces
}

Config configures a Checker.

type Nonces

type Nonces struct {
	// contains filtered or unexported fields
}

Nonces issues and checks server-provided DPoP nonces (RFC 9449 §8). A nonce is the time it was issued, authenticated with an HMAC under the secret, so it needs no storage: every instance given the same secret accepts the nonces any of them issued, for Lifetime after issue.

func NewNonces

func NewNonces(secret []byte, lifetime time.Duration) (*Nonces, error)

NewNonces returns a nonce source keyed by secret (at least 32 bytes, the same on every instance). lifetime <= 0 uses DefaultNonceLifetime.

func (*Nonces) Issue

func (n *Nonces) Issue() (string, error)

Issue returns a new nonce.

type Proof

type Proof struct {
	// contains filtered or unexported fields
}

Proof is a verified DPoP proof. Only a Checker creates one, so a Proof is evidence that the request's sender holds the private key whose thumbprint JKT returns.

func (*Proof) IssuedAt

func (p *Proof) IssuedAt() time.Time

IssuedAt returns the proof's iat.

func (*Proof) JKT

func (p *Proof) JKT() string

JKT returns the RFC 7638 SHA-256 thumbprint of the proof's key, the value of a bound token's cnf.jkt claim; "" for a nil Proof (no proof).

func (*Proof) JTI

func (p *Proof) JTI() string

JTI returns the proof's unique identifier.

type ReplayCache

type ReplayCache interface {
	// Use records key until expiresAt and reports whether it was already
	// recorded (a replay).
	Use(ctx context.Context, key string, expiresAt time.Time) (replayed bool, err error)
}

ReplayCache records proof identifiers so each proof is accepted once. Implementations must be safe for concurrent use and shared between the instances that accept proofs for the same URIs. The caches in session/middleware (NewMemoryReplayCache, NewRedisReplayCache) implement it.

type Target

type Target struct {
	// Method is the request method the proof's htm must name.
	Method string
	// URI is the request URI without query or fragment the proof's htu
	// must name. Behind a proxy that terminates TLS, build it from the
	// configured external base URL rather than the request.
	URI string
	// AccessToken, when set, is the token presented with the proof, whose
	// hash the proof's ath must carry.
	AccessToken string //nolint:gosec // G117: field holds a runtime token value
}

Target is what a proof must be made for.

Jump to

Keyboard shortcuts

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