Documentation
¶
Overview ¶
Package gateway verifies original-client TLS evidence from explicitly trusted gateways over mutually authenticated TLS. It never modifies Request.TLS.
This is a hop-by-hop trust protocol, not a portable attestation token. Every gateway is trusted to report its incoming transport accurately. All hops must use TLS 1.3 with certificate verification and explicit peer authorization.
Index ¶
- Constants
- func Claims(counter Counter, prefix string) func(context.Context, string, time.Duration) (bool, error)
- func Edge(authorize func(context.Context, string) error) func(http.Handler) http.Handler
- func EdgeHeaderNames() []string
- func Forward(out, in *http.Request) error
- func Pin(cert *x509.Certificate) string
- func RequireTLS13(r *http.Request) bool
- func ServerTLS(cert tls.Certificate, clients *x509.CertPool) (*tls.Config, error)
- func ValidateOutgoing(r *http.Request) error
- func Verify(p Policy) (func(http.Handler) http.Handler, error)
- type Counter
- type Evidence
- type Policy
- type Transport
Constants ¶
const Header = "Lidza-Gateway-Transport"
const NativeEdgeHeaders = "edge-headers-v1"
NativeEdgeHeaders is the explicit wire marker for a trusted TLS terminator unable to call Forward. It must overwrite every listed header from actual connection/request properties, never incoming forwarding headers. Verify must opt in with Policy.NativeEdges for the pinned immediate peer. Relays use the normal protocol; native edge headers cannot assert a prior gateway chain.
Variables ¶
This section is empty.
Functions ¶
func Claims ¶
func Claims(counter Counter, prefix string) func(context.Context, string, time.Duration) (bool, error)
Claims adapts an atomic expiring counter into Policy.Claim. Use a stable application-specific prefix shared by all replicas and verifier key rotations.
func Edge ¶
Edge captures direct TLS at a public terminator, discarding client-supplied gateway evidence. SNI must match the canonical authority. This rejects domain fronting and cleartext; TLS 1.2 may be represented but fails RequireTLS13.
func EdgeHeaderNames ¶
func EdgeHeaderNames() []string
EdgeHeaderNames is the complete native-terminator header list. A proxy must overwrite these fields and strip Header itself before creating its marker.
func Forward ¶
Forward replaces the outbound header using verified context only. Preserve method, target and public Host. Use ClientTransport for the outgoing hop; plaintext forwarding invalidates the security contract. This function alone does not secure a proxy. It must never take evidence from an unverified header.
func Pin ¶
func Pin(cert *x509.Certificate) string
Pin identifies a certificate key independently of certificate renewal.
func RequireTLS13 ¶
RequireTLS13 checks verified original-client TLS. Use this after Edge or Verify; it deliberately does not fall back to r.TLS (which may be a backend connection). Application authentication and replay protection remain required.
func ServerTLS ¶
ServerTLS builds a private TLS 1.3 listener config requiring client certificate chain verification. Verify additionally pins authorized gateway keys. Use a dedicated listener; do not expose a plaintext fallback for protected protocols.
func ValidateOutgoing ¶
ValidateOutgoing is useful in proxy error handling before RoundTrip. A TLS transport does not prevent http:// requests by itself, so callers must check.
func Verify ¶
Verify accepts the protocol only from a chain-verified, pinned mutual-TLS peer. Metadata is bound to this same protected HTTP request (method, target, authority), expires after 15 seconds and is never accepted as a bearer token. A shared atomic Claim store rejects reuse across connections and replicas. TLS record authentication, sequence numbers and fresh session keys prevent captured evidence/records being replayed by a network attacker. Go TLS has no server-side 0-RTT. Retrying an authenticated HTTP operation remains the app's idempotency/nonce responsibility, not a transport authentication guarantee.
Types ¶
type Counter ¶
Counter is satisfied by the cache pack. Production verifiers must use a shared atomic backend, not independent process-local memory stores.
type Evidence ¶
type Evidence struct {
TLSVersion uint16
Authority string
ServerName string
// Gateways is the ordered list of authenticated gateway public-key pins.
Gateways []string
}
Evidence describes verified original-client transport, separately from the TLS connection of the current hop. Fields are read-only copies.
type Policy ¶
type Policy struct {
// Claim atomically reserves an unused nonce for ttl across all verifier nodes.
// Return false for a duplicate and an error on store failure; both fail closed.
// A shared cache Incr with a TTL succeeds only when the result is 1.
Claim func(ctx context.Context, key string, ttl time.Duration) (bool, error)
Peers []string
// Delegates authorizes earlier gateways asserted by the immediate peer.
// Empty accepts a direct edge only. Maximum four total protected gateways.
Delegates []string
// NativeEdges authorizes the native-terminator header format only for listed
// immediate peer pins, each also present in Peers. Never enable globally.
NativeEdges []string
Authorize func(ctx context.Context, authority string) error
}
Policy authorizes both the immediate gateway and the original authority. Pins are SHA-256 SubjectPublicKeyInfo pins from Pin. Keep overlapping old/new pins during certificate-key rotation. Authorize must be concurrency-safe and return promptly using ctx; nil never authorizes an authority.
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport rejects plaintext and credential-bearing backend URLs before any I/O. Its private TLS configuration cannot be weakened after construction.
func ClientTransport ¶
ClientTransport verifies the backend name and CA and authenticates the gateway. It has no environment proxy and never sends evidence over plaintext. CloseIdleConnections when retiring it. Redirects must be disabled by callers.
func (*Transport) CloseIdleConnections ¶
func (t *Transport) CloseIdleConnections()