dpop

package
v2.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package dpop implements Demonstrating Proof-of-Possession (DPoP) at the application layer (RFC 9449).

It provides:

  • DPoP proof validation (Section 4.1, 4.2, 4.3)
  • DPoP-bound access token creation (Section 7.1, cnf.jkt)
  • DPoP proof verification for resource server introspection (Section 10.1)
  • Server-provided nonce support (Section 8.1)

Index

Constants

View Source
const (
	// Header is the HTTP header name for the DPoP proof.
	Header = "DPoP"

	// AccessTokenType is the token_type for DPoP-bound access tokens.
	AccessTokenType = "DPoP"

	// MaxProofAge is the maximum age of a DPoP proof (default 5 minutes per RFC 9449 §7.1).
	MaxProofAge = 5 * time.Minute
)
View Source
const NonceHeader = "DPoP-Nonce"

NonceHeader is the HTTP header name for the DPoP nonce.

View Source
const NonceLifetime = 5 * time.Minute

NonceLifetime is the lifetime of a server-provided nonce (RFC 9449 §8.1).

Variables

This section is empty.

Functions

func CNFClaim

func CNFClaim(jkt string) map[string]any

CNFClaim returns the cnf claim for DPoP-bound tokens (RFC 9449 §7.1).

func ContextWithDPoP

func ContextWithDPoP(ctx context.Context, proof *Proof) context.Context

ContextWithDPoP stores the DPoP proof in the request context. Uses shared context key for cross-package access.

func JWKThumbprint

func JWKThumbprint(key jwk.Key) (string, error)

JWKThumbprint computes the JWK Thumbprint (RFC 7638) of a key.

func ValidateATH

func ValidateATH(proof *Proof, accessToken string) error

ValidateATH validates the ath (access token hash) claim in a DPoP proof against the actual access token presented in the request (RFC 9449 §7.1). The ath claim MUST be present and MUST equal base64url(SHA-256(access_token)).

func ValidateBoundToken

func ValidateBoundToken(tokenCNF map[string]any, proof *Proof) error

ValidateBoundToken verifies that an access token was issued with the same DPoP key as the current request (RFC 9449 §10.1).

func VerifyPublicKey

func VerifyPublicKey(key crypto.PublicKey) error

VerifyPublicKey validates that the key type and algorithm are acceptable.

Types

type Plugin

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

Plugin implements DPoP proof validation and token binding.

func NewWithConfig

func NewWithConfig() *Plugin

NewWithConfig creates a new DPoP plugin.

func (*Plugin) Category

func (p *Plugin) Category() storm.PluginCategory

Category returns CategoryStandard — DPoP is optional.

func (*Plugin) CleanupNonceCache

func (p *Plugin) CleanupNonceCache()

CleanupNonceCache removes expired nonces from the cache.

func (*Plugin) Contribute

func (p *Plugin) Contribute(ctx context.Context, cfg *protocol.DiscoveryConfiguration)

Contribute returns discovery fields for DPoP.

func (*Plugin) GenerateNonce

func (p *Plugin) GenerateNonce() string

GenerateNonce creates a new server-provided nonce (RFC 9449 §8.1). The nonce is cached and can be validated later.

func (*Plugin) Middleware

func (p *Plugin) Middleware(next http.Handler) http.Handler

Middleware parses the DPoP header from the request and stores the proof in the request context. If no DPoP header is present, the context value is nil. If a DPoP header is present but invalid, the request is rejected with HTTP 400 (RFC 9449 §4.3).

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the plugin name.

func (*Plugin) Register

func (p *Plugin) Register(r chi.Router)

Register is a no-op for the DPoP plugin.

func (*Plugin) Requires

func (p *Plugin) Requires() []string

Requires returns no storage dependencies (DPoP is stateless except nonce cache).

func (*Plugin) Stop

func (p *Plugin) Stop()

Stop terminates the background cleanup goroutine.

func (*Plugin) ValidateNonce

func (p *Plugin) ValidateNonce(nonce string) bool

ValidateNonce validates a server-provided nonce (RFC 9449 §8.1). Returns true if the nonce is valid and not expired. The nonce is consumed (deleted) after validation.

func (*Plugin) WriteNonceHeader

func (p *Plugin) WriteNonceHeader(w http.ResponseWriter)

WriteNonceHeader writes the DPoP-Nonce header to the response.

type Proof

type Proof struct {
	JKT       string      // JWK thumbprint (SHA-256 of JWK)
	HTM       string      // HTTP method
	HTU       string      // HTTP URI
	ATH       string      // access token hash (base64url(SHA-256(access_token)))
	IssuedAt  time.Time   // iat claim
	UniqueID  string      // jti claim
	PublicKey interface{} // The public key from the proof (crypto.PublicKey)
}

Proof holds the parsed DPoP proof from a request.

func DPoPFromContext

func DPoPFromContext(ctx context.Context) *Proof

DPoPFromContext retrieves the DPoP proof from the context as *Proof. Returns nil if no DPoP proof was presented. For cross-package access, use shared.DPoPFromContext() which returns the shared.DPoPProof interface.

func ParseProof

func ParseProof(dpopHeader, httpMethod, httpURL string) (*Proof, error)

ParseProof parses and validates a DPoP proof JWT (RFC 9449 §4.3).

func (*Proof) AccessTokenHash

func (p *Proof) AccessTokenHash() string

AccessTokenHash returns the ath claim from the DPoP proof. Implements shared.DPoPProof interface.

func (*Proof) JWKThumbprint

func (p *Proof) JWKThumbprint() string

JWKThumbprint returns the JWK thumbprint (cnf.jkt value). Implements shared.DPoPProof interface.

Jump to

Keyboard shortcuts

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