httpsig

package
v0.13.1 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package httpsig wires per-message proofs of origin (valiss message tokens) into net/http: a client Transport that mints a token per outgoing request and a server middleware that verifies it offline against the operator public key. Handlers read the verified claims with valiss.MessageFromContext.

A message token proves origin only — it authenticates the message, not a caller, and grants no identity. Pair with contrib/httpauth when the caller must also authenticate.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Audience

func Audience(r *http.Request) string

Audience is the canonical destination identity of an HTTP request a message token is bound to: host and path, query excluded. The emitting Transport (absolute URL) and the receiving middleware (Host header + path) must derive identical bytes, so the host is taken from r.Host with a fallback to the URL, and the scheme is excluded (unknowable behind TLS terminators).

func NewKeyringMiddleware

func NewKeyringMiddleware(keyring *valiss.Keyring, opts ...MiddlewareOption) func(http.Handler) http.Handler

NewKeyringMiddleware is NewMiddleware for a receiver trusting several operators: each message verifies against the keyring entry its chain names (valiss.VerifyMessageKeyring), and handlers tell trust domains apart by MessageClaims.Operator.

func NewMiddleware

func NewMiddleware(operatorPubKey string, opts ...MiddlewareOption) func(http.Handler) http.Handler

NewMiddleware returns a middleware that requires every request to carry a message token (valiss-message-token header) proving the origin of its exact body at this destination: the token is verified against the operator public key with the audience pinned to the incoming host and path (Audience) and the checksum compared to the received bytes. Failures get 401. Handlers read the verified claims with valiss.MessageFromContext and the body as usual.

The middleware speaks the receiving side of chain negotiation: detached chain headers (valiss-chain-account-token, valiss-chain-user-token) on the request supply the chain for a chainless token, and a chainless token whose chain is not otherwise known is rejected with the valiss-chain: required response header, asking the transport to retransmit with the chain attached. WithChainCache remembers negotiated chains so the retransmit happens once per emitter, not per message.

func RequireChain added in v0.13.0

func RequireChain(h http.Header)

RequireChain stamps the chain-negotiation signal on response headers, asking the emitting transport to retransmit with its provenance chain attached. Framework adapters set it before rejecting when Verify fails with valiss.ErrNoChain; the net/http middleware does this internally.

func StatusOf added in v0.13.0

func StatusOf(err error) int

StatusOf maps a Verify rejection to its HTTP status. Unknown errors map to 401: verification failures must never widen access.

Types

type Error added in v0.13.0

type Error struct {
	Status int
	Err    error
}

Error is the rejection returned by Receiver.Verify: the cause plus the HTTP status it maps to — 400 for an unreadable body, 401 otherwise. errors.Is/As reach the wrapped cause, so valiss.ErrNoChain remains detectable for chain-negotiation signaling.

func (*Error) Error added in v0.13.0

func (e *Error) Error() string

func (*Error) Unwrap added in v0.13.0

func (e *Error) Unwrap() error

type MiddlewareOption

type MiddlewareOption func(*Receiver)

MiddlewareOption configures the verification.

func WithChainCache

func WithChainCache(cache valiss.ChainCache) MiddlewareOption

WithChainCache stores negotiated chains between requests, so an emitter pays the chain retransmit once instead of on every message. Only chains that survived full verification are stored; an entry that later fails (e.g. after a domain rotation) is dropped and the chain re-negotiated. valiss.NewMemoryChainCache is a process-local implementation.

func WithVerifyOptions

func WithVerifyOptions(opts ...valiss.VerifyMessageOption) MiddlewareOption

WithVerifyOptions passes extra options to every valiss.VerifyMessage call, e.g. valiss.WithOperatorPolicy to enforce the domain epoch or valiss.WithChainTokens to pin a single emitter's chain in configuration. A pinned chain takes precedence over negotiated chain material; the middleware's audience and payload bindings are applied after these options and cannot be weakened by them.

type Receiver added in v0.13.0

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

Receiver is the receiving-side verification core behind NewMiddleware, shared by framework adapters (contrib/ginsig, contrib/echosig): message token extraction, body binding, chain-negotiation state, and verification over a plain *http.Request.

func NewKeyringReceiver added in v0.13.0

func NewKeyringReceiver(keyring *valiss.Keyring, opts ...MiddlewareOption) *Receiver

NewKeyringReceiver is NewReceiver for a receiver trusting several operators: each message verifies against the keyring entry its chain names (valiss.VerifyMessageKeyring), and handlers tell trust domains apart by MessageClaims.Operator.

func NewReceiver added in v0.13.0

func NewReceiver(operatorPubKey string, opts ...MiddlewareOption) *Receiver

NewReceiver returns the verification core for receivers trusting a single operator. Most servers want NewMiddleware instead; framework adapters build on the Receiver directly.

func (*Receiver) Verify added in v0.13.0

func (rc *Receiver) Verify(r *http.Request) (*valiss.MessageClaims, error)

Verify checks that r carries a message token proving the origin of its exact body at this destination: the token is verified with the audience pinned to the incoming host and path (Audience) and the checksum compared to the received bytes. The body is read in full and restored, so handlers read it as usual. A non-nil error is always an *Error; StatusOf maps it to the response status, and a wrapped valiss.ErrNoChain means the caller must reject with RequireChain on the response headers so the emitter retransmits with its chain.

type Transport

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

Transport is an http.RoundTripper that mints a fresh message token per outgoing request (valiss.IssueMessage): a proof of origin bound to the destination (Audience) and the request body, carried in the valiss-message-token header, with the provenance chain embedded. The receiver verifies it offline with NewMiddleware or valiss.VerifyMessage. Set it as (or wrap it around) http.Client.Transport on webhook emitters.

func NewTransport

func NewTransport(b creds.Creds, base http.RoundTripper, opts ...TransportOption) (*Transport, error)

NewTransport builds an emitting transport from parsed creds, which must be a bundle holding the user seed: the account token, the user token, and the seed that signs the message tokens. The trust-domain epoch is taken from the chain tokens, which must agree on it. A nil base means http.DefaultTransport.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

type TransportOption

type TransportOption func(*Transport)

TransportOption configures a Transport.

func WithChainNegotiation

func WithChainNegotiation() TransportOption

WithChainNegotiation sends chainless message tokens and retransmits once with the chain in detached headers when the receiver answers valiss-chain: required. Against a receiver holding a chain cache the steady state is the bare token per message instead of the embedded chain; without negotiation every token embeds the chain. Requests must be replayable (a nil, bytes-backed, or GetBody-capable body — the transport arranges this for bodies it can read).

func WithTTL

func WithTTL(d time.Duration) TransportOption

WithTTL overrides the valiss.DefaultMessageTTL validity window of minted message tokens.

Jump to

Keyboard shortcuts

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