Documentation
¶
Overview ¶
Package htpx is the HTTP application toolkit that backs apic-generated services. It wires a Gin-based TLS/mTLS server (driven by the OpenAPI spec via oapi-codegen middleware, CORS, and slog request logging), a buffered outbound HTTP Client with retry, rate limiting, and a response-body size ceiling, and a TLS-terminating reverse Proxy with pluggable rules, subnet filters, and request rewriters. It also provides the request-authentication surfaces: API keys (with pluggable stores and scope checks), FIDO/WebAuthn, HMAC request signatures, and OIDC. Structured logging flows through pkg/log.
Index ¶
- Constants
- Variables
- func APIKeyMiddleware(cfg *APIKeyAuthConfig) gin.HandlerFunc
- func Args(app string) cli.Args
- func AuthToken(ctx context.Context) (jwt.Token, error)
- func CacheMiddleware(cfg *CacheConfig) gin.HandlerFunc
- func CircuitBreakerMiddleware(cb *CircuitBreaker) gin.HandlerFunc
- func Clone(in *http.Request) *http.Request
- func CloneHeader(in http.Header) http.Header
- func CloneResponse(in *http.Response) *http.Response
- func CloneURL(in *url.URL) *url.URL
- func CompressionMiddleware(cfg *CompressionConfig) gin.HandlerFunc
- func ConstantTimeCompare(a, b string) bool
- func FIDOMiddleware(store FIDOStore) gin.HandlerFunc
- func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error)
- func GenerateTLSCertificate(l net.Listener, names ...string) (tls.Certificate, error)
- func LoadPrivateKey(pemBytes []byte) (any, error)
- func LoadPublicKey(pemBytes []byte) (any, error)
- func Proxy(ctx context.Context, l net.Listener, opts ...ProxyOption) error
- func RequestLogger(logger *slog.Logger) gin.HandlerFunc
- func RequireScope(scope string) gin.HandlerFunc
- func SignatureMiddleware(verifier *Verifier) gin.HandlerFunc
- func To[T any](c *Client, resp *http.Response) (T, error)
- type APIKey
- type APIKeyAuthConfig
- type APIKeyManager
- func (m *APIKeyManager) DeleteKey(id string) error
- func (m *APIKeyManager) GenerateKey(name string, scopes []string, metadata map[string]any, expiresAt *time.Time) (*APIKey, string, error)
- func (m *APIKeyManager) GetKey(id string) (*APIKey, error)
- func (m *APIKeyManager) ListKeys() ([]*APIKey, error)
- func (m *APIKeyManager) RevokeKey(id string) error
- func (m *APIKeyManager) ValidateKey(keyStr string) (*APIKey, error)
- type APIKeyStats
- type APIKeyStore
- type CacheConfig
- type CacheEntry
- type CacheStore
- type CircuitBreaker
- type CircuitBreakerConfig
- type CircuitState
- type Client
- func (c *Client) Close() (out error)
- func (c *Client) Delete(uri string, query url.Values, opts ...RequestOption) (*http.Response, error)
- func (c *Client) Do(req *http.Request) (*http.Response, error)
- func (c *Client) Get(uri string, query url.Values, opts ...RequestOption) (*http.Response, error)
- func (c *Client) JSONReader(in any) (io.ReadCloser, error)
- func (c *Client) LogValue() slog.Value
- func (c *Client) Post(uri string, query url.Values, body io.ReadCloser, opts ...RequestOption) (*http.Response, error)
- func (c *Client) Put(uri string, query url.Values, body io.ReadCloser, opts ...RequestOption) (*http.Response, error)
- func (c *Client) RoundTrip(req *http.Request) (*http.Response, error)
- type ClientWrapper
- type CompressionConfig
- type FIDOConfig
- type FIDOCredential
- type FIDOServer
- type FIDOStore
- type FIDOUser
- func (u *FIDOUser) MarshalJSON() ([]byte, error)
- func (u *FIDOUser) UnmarshalJSON(data []byte) error
- func (u *FIDOUser) WebAuthnCredentials() []webauthn.Credential
- func (u *FIDOUser) WebAuthnDisplayName() string
- func (u *FIDOUser) WebAuthnID() []byte
- func (u *FIDOUser) WebAuthnIcon() string
- func (u *FIDOUser) WebAuthnName() string
- type HTTPClient
- type HTTPExchange
- type Host
- type ID
- type KeyStore
- type MemoryAPIKeyStore
- func (s *MemoryAPIKeyStore) Delete(id string) error
- func (s *MemoryAPIKeyStore) GetByHash(hash string) (*APIKey, error)
- func (s *MemoryAPIKeyStore) GetByID(id string) (*APIKey, error)
- func (s *MemoryAPIKeyStore) GetByPrefix(prefix string) (*APIKey, error)
- func (s *MemoryAPIKeyStore) List() ([]*APIKey, error)
- func (s *MemoryAPIKeyStore) Save(key *APIKey) error
- func (s *MemoryAPIKeyStore) UpdateLastUsed(id string, t time.Time) error
- type MemoryCacheStore
- type MemoryFIDOStore
- func (s *MemoryFIDOStore) GetCredentials(userID []byte) ([]*FIDOCredential, error)
- func (s *MemoryFIDOStore) GetUser(userID []byte) (*FIDOUser, error)
- func (s *MemoryFIDOStore) GetUserByName(username string) (*FIDOUser, error)
- func (s *MemoryFIDOStore) SaveCredential(userID []byte, credential *FIDOCredential) error
- func (s *MemoryFIDOStore) SaveUser(user *FIDOUser) error
- func (s *MemoryFIDOStore) UpdateCredential(credentialID []byte, credential *FIDOCredential) error
- type MemoryKeyStore
- type MockEndpoint
- type MockServer
- type OIDC
- type Option
- func WithAPIKey(key string) Option
- func WithAutoRefreshToken(refresher *TokenRefresher) Option
- func WithBasicAuth(username, password string) Option
- func WithBearerToken(token string) Option
- func WithCircuitBreaker(cb *CircuitBreaker) Option
- func WithDebugFile(file string) Option
- func WithDoer(client HTTPClient) Option
- func WithHeader(key, value string) Option
- func WithLimiter(ctx context.Context, delay time.Duration, retries int, concurrency int, ...) Option
- func WithLogger(log log.Logger) Option
- func WithMaxResponseBytes(n int64) Option
- func WithOAuth2(clientID, clientSecret, tokenURL string, scopes ...string) Option
- func WithRetry(cfg *RetryConfig) Option
- func WithRoot(rootURL string) Option
- func WithSignature(signer *Signer) Option
- func WithTransport(transport http.RoundTripper) Option
- type ProxyOption
- type Register
- type ReplayRequest
- type ReplayResult
- type Replayer
- type RequestOption
- type RetryConfig
- type Rewriter
- type Rule
- type Server
- type ServerOption
- func RateLimit(limit int, duration time.Duration) ServerOption
- func WithAPIKeyManager(manager *APIKeyManager, adminAuth gin.HandlerFunc) ServerOption
- func WithCORS(allowedOrigins []string, methods ...string) ServerOption
- func WithErrorHandler(handler func(ctx *gin.Context, err error, i int)) ServerOption
- func WithFIDO(cfg *FIDOConfig) ServerOption
- func WithHost(host string) ServerOption
- func WithImpl(impl any) ServerOption
- func WithMiddleware(middleware ...gin.HandlerFunc) ServerOption
- func WithPerIPRateLimit() ServerOption
- func WithPort(port int) ServerOption
- func WithServerLogger(logger log.Logger) ServerOption
- func WithSwaggerSpec(spec *openapi3.T) ServerOption
- func WithTLS(cert, key string) ServerOption
- func WithTrustedProxies(proxies []string) ServerOption
- func WithValidation(ctx context.Context, oidc string, audience string) ServerOption
- type SignatureAlgorithm
- type SignatureConfig
- type SignatureInfo
- type SignatureStats
- type Signer
- type TOKEN
- type Timeout
- type TokenRefresher
- type TrafficDiff
- type TrafficDiffer
- type Verifier
Constants ¶
const ( DefaultRead = Timeout(5 * time.Second) DefaultWrite = Timeout(10 * time.Second) DefaultReadHeader = Timeout(5 * time.Second) DefaultClient = Timeout(10 * time.Second) DefaultResponse = Timeout(10 * time.Second) DefaultTLSHandshake = Timeout(10 * time.Second) DefaultKeepAlive = Timeout(30 * time.Second) DefaultExpect = Timeout(1 * time.Second) )
const ( // AuthScopes is the context key for the authentication scopes that are defined // for a specific API path that must be present in the JWT token in order to // access the path. OAuth2Scopes = "oauth2_scopes" ENV = "GIN_MODE" // runnning environment DEVENV = "debug" // development environment INSECURE_DEV = "APIC_INSECURE_DEV" )
const DefaultMaxResponseBytes int64 = 32 << 20
DefaultMaxResponseBytes is the secure-default ceiling on buffered response bodies (32 MiB). An unauthenticated/compromised upstream returning a multi-gigabyte body would otherwise OOM the client via io.ReadAll (PERF-0024). Raise or disable per-client with WithMaxResponseBytes.
const MaxSignatureBodyBytes int64 = 32 << 20 // 32 MiB
MaxSignatureBodyBytes caps the request body size that signature signing and verification will hash for the Digest header. Bodies larger than this are rejected with ErrSignatureBodyTooLarge instead of being buffered into memory. The cap matches PERF-0014's response body cap so signed flows on either side of the wire share the same backpressure ceiling.
Variables ¶
var ( // ErrAPIKeyNotFound is returned by APIKeyStore implementations when // a lookup or delete targets a key that is not present. Replaces the // six "API key not found" anonymous errors.New sites in apikey.go. ErrAPIKeyNotFound = errors.New("htpx: api key not found") // ErrAPIKeyInvalid is returned by APIKeyManager.ValidateKey when the // provided key string does not hash to a known stored key. The // message intentionally avoids leaking whether the key was unknown // versus mismatched (to limit oracle behavior under brute-force). ErrAPIKeyInvalid = errors.New("htpx: invalid api key") // ErrAPIKeyDisabled is returned by APIKeyManager.ValidateKey when // the key exists but is not enabled. ErrAPIKeyDisabled = errors.New("htpx: api key is disabled") // ErrAPIKeyExpired is returned by APIKeyManager.ValidateKey when the // key exists, is enabled, but its ExpiresAt is in the past. ErrAPIKeyExpired = errors.New("htpx: api key is expired") // ErrFIDOUserNotFound is returned by FIDOStore implementations when // a user lookup misses. Returned by GetUser, GetUserByName, and // GetCredentials in MemoryFIDOStore. ErrFIDOUserNotFound = errors.New("htpx: fido user not found") // ErrFIDOConfigRequired is returned by NewFIDOServer when the // supplied configuration pointer is nil. ErrFIDOConfigRequired = errors.New("htpx: fido config is required") // ErrOIDCEndpointEmpty is returned by the API server constructor // when an authenticated build is requested without an OIDC endpoint // AND insecure-dev startup is not allowed. ErrOIDCEndpointEmpty = errors.New("htpx: oidc endpoint is empty") // ErrValidationSpecMissing is returned by WithValidation when OIDC // auth is configured but no OpenAPI spec was supplied. The OpenAPI // request validator mounted from the spec is the only component // that invokes the authentication function, so without a spec every // `security:`-declared route would be served unauthenticated // (fail-open). htpx has no embedded spec to fall back on; pass // WithSwaggerSpec before WithValidation. Sibling of appsec N-01 // fixed in api/ (73d6568). ErrValidationSpecMissing = errors.New( "htpx: oidc auth is configured but no OpenAPI spec was supplied;" + " pass WithSwaggerSpec before WithValidation so the auth" + " enforcer can be mounted", ) // ErrRegisterFunctionNil is returned by api.New when called without // a route registration function. ErrRegisterFunctionNil = errors.New("htpx: register function is nil") // ErrInsecureDevNonLoopback is returned by newListener when // APIC_INSECURE_DEV is set but the host is not a loopback address. ErrInsecureDevNonLoopback = errors.New("htpx: APIC_INSECURE_DEV is only allowed on loopback hosts") // ErrMissingTLSPaths is returned by newListener when neither // insecure-dev nor a cert/key path pair is provided. ErrMissingTLSPaths = errors.New("htpx: missing TLS cert/key paths") // ErrTransportNil is returned by WithTransport when the supplied // http.RoundTripper is nil. ErrTransportNil = errors.New("htpx: transport is nil") // ErrClientNil is returned by WithDoer when the supplied // HTTPClient is nil. ErrClientNil = errors.New("htpx: client is nil") // ErrCircuitBreakerOpen is returned by CircuitBreaker.Execute when // the breaker is in the open state and the call is short-circuited. ErrCircuitBreakerOpen = errors.New("htpx: circuit breaker is open") // ErrCacheMiss is returned by MemoryCacheStore.Get when no entry // exists for the requested key. ErrCacheMiss = errors.New("htpx: cache miss") // ErrCacheExpired is returned by MemoryCacheStore.Get when an entry // exists but its TTL has elapsed. ErrCacheExpired = errors.New("htpx: cache expired") // ErrReadResponseBody is wrapped via errors.Join when ReadJSON fails // to read the response body off the wire. ErrReadResponseBody = errors.New("htpx: failed to read response body") // ErrUnmarshalResponseBody is wrapped via errors.Join when ReadJSON // fails to decode the response body as JSON. ErrUnmarshalResponseBody = errors.New("htpx: failed to unmarshal response body") // ErrResponseBodyTooLarge is returned when a response body exceeds the // client's maxResponseBytes ceiling (see WithMaxResponseBytes). PERF-0024. ErrResponseBodyTooLarge = errors.New("htpx: response body exceeds maximum") // ErrNoTokenToRefresh is returned by TokenRefresher.Start when the // refresher has no current token to refresh. ErrNoTokenToRefresh = errors.New("htpx: no token to refresh") // ErrAuthTokenMissing is returned by AuthToken when no JWT is // present in the request context. ErrAuthTokenMissing = errors.New("htpx: failed to get auth token") // ErrJWTMissingScopeClaim is returned by OIDC.Authenticate when // scopes are required but the token has no "scope" claim. ErrJWTMissingScopeClaim = errors.New("htpx: missing scope claim in jwt") // ErrJWTScopeClaimNotString is returned by OIDC.Authenticate when // the "scope" claim exists but is not a string. ErrJWTScopeClaimNotString = errors.New("htpx: jwt scope claim is not a string") // ErrJWKEndpointEmpty is returned by OIDC.UnmarshalJSON when the // JWK endpoint returns no keys at cold start. ErrJWKEndpointEmpty = errors.New("htpx: no keys found in jwk endpoint") // ErrUnsupportedJWTAlg is returned by ExtractToken when an inbound // token declares a JWS algorithm outside the asymmetric allowlist // (e.g. "none" or HS256/384/512). Mirrors api/oidc.go (QG-060) so the // JWKS verification path cannot be downgraded via algorithm // confusion. QG-081. ErrUnsupportedJWTAlg = errors.New("htpx: unsupported jwt algorithm") // ErrSignatureConfigRequired is returned by NewSigner when given a // nil SignatureConfig. ErrSignatureConfigRequired = errors.New("htpx: signature config is required") // ErrSignatureKeyIDRequired is returned by NewSigner when the // SignatureConfig has an empty KeyID. ErrSignatureKeyIDRequired = errors.New("htpx: signature key id is required") // ErrSignaturePrivateKeyRequired is returned by NewSigner when the // SignatureConfig has a nil PrivateKey. ErrSignaturePrivateKeyRequired = errors.New("htpx: signature private key is required") // ErrSignatureHMACKeyType is returned by Signer.sign and Verifier.verify // when the configured key for HMAC algorithms is not a []byte. ErrSignatureHMACKeyType = errors.New("htpx: hmac key must be []byte") // ErrSignatureRSAPrivateKey is returned by Signer.sign when the // configured private key is not an *rsa.PrivateKey. ErrSignatureRSAPrivateKey = errors.New("htpx: rsa private key required") // ErrSignatureECDSAPrivateKey is returned by Signer.sign when the // configured private key is not an *ecdsa.PrivateKey. ErrSignatureECDSAPrivateKey = errors.New("htpx: ecdsa private key required") // ErrSignatureED25519PrivateKey is returned by Signer.sign when the // configured private key is not an ed25519.PrivateKey. ErrSignatureED25519PrivateKey = errors.New("htpx: ed25519 private key required") // ErrSignatureMissingAuthHeader is returned by VerifyRequest when // the request has no Authorization header. ErrSignatureMissingAuthHeader = errors.New("htpx: missing authorization header") // ErrSignatureDateHeaderMissing is returned by VerifyRequest when // the signed headers include "date" but the request has none. ErrSignatureDateHeaderMissing = errors.New("htpx: date header required but not found") // ErrSignatureClockSkew is returned by VerifyRequest when the date // header is outside the configured clock-skew window. The message // intentionally retains the substring "clock skew" for compatibility // with existing tests that match on it. ErrSignatureClockSkew = errors.New("htpx: date header outside allowed clock skew") // ErrSignatureHMACVerify is returned by Verifier.verify when the // HMAC signature does not match the expected value. ErrSignatureHMACVerify = errors.New("htpx: hmac verification failed") // ErrSignatureRSAPublicKey is returned by Verifier.verify when the // configured public key is not an *rsa.PublicKey. ErrSignatureRSAPublicKey = errors.New("htpx: rsa public key required") // ErrSignatureECDSAPublicKey is returned by Verifier.verify when the // configured public key is not an *ecdsa.PublicKey. ErrSignatureECDSAPublicKey = errors.New("htpx: ecdsa public key required") // ErrSignatureECDSAVerify is returned by Verifier.verify when the // ECDSA signature does not match. ErrSignatureECDSAVerify = errors.New("htpx: ecdsa verification failed") // ErrSignatureED25519PublicKey is returned by Verifier.verify when // the configured public key is not an ed25519.PublicKey. ErrSignatureED25519PublicKey = errors.New("htpx: ed25519 public key required") // ErrSignatureED25519Verify is returned by Verifier.verify when the // Ed25519 signature does not match. ErrSignatureED25519Verify = errors.New("htpx: ed25519 verification failed") // ErrSignatureHeaderFormat is returned by parseSignatureHeader when // the Authorization header does not start with "Signature ". ErrSignatureHeaderFormat = errors.New("htpx: invalid signature header format") // ErrSignatureHeaderIncomplete is returned by parseSignatureHeader // when the Signature header is missing required fields. ErrSignatureHeaderIncomplete = errors.New("htpx: incomplete signature header") // ErrSignatureDigestHeaderMissing is returned by verifyDigest when // the request is missing the Digest header that was signed. ErrSignatureDigestHeaderMissing = errors.New("htpx: digest header required but not found") // ErrSignatureDigestUnsupported is returned by verifyDigest when the // Digest header uses an algorithm other than SHA-256. ErrSignatureDigestUnsupported = errors.New("htpx: only SHA-256 digest supported") // ErrSignatureDigestMismatch is returned by verifyDigest when the // computed digest does not match the value supplied in the header. ErrSignatureDigestMismatch = errors.New("htpx: digest mismatch") // ErrSignaturePEMDecode is returned by LoadPrivateKey and // LoadPublicKey when the PEM block cannot be decoded. ErrSignaturePEMDecode = errors.New("htpx: failed to decode PEM block") )
Sentinel errors for the htpx package. Kept at package level per repo conventions. Messages use a lowercase, package-prefixed, diagnostic form so log output reads naturally; errors.Is callers should rely on pointer equality rather than substring matching of Error().
Sentinels that have richer documentation (ErrInvalidURL, ErrInvalidScheme, ErrAuthHeaderMissing, ErrMalformedAuthHeader, ErrEmptyAudience, ErrSignatureBodyTooLarge, ErrNotApplicable) are declared at their use sites.
var ( GET = WithMethod(http.MethodGet) POST = WithMethod(http.MethodPost) PUT = WithMethod(http.MethodPut) DELETE = WithMethod(http.MethodDelete) PATCH = WithMethod(http.MethodPatch) )
var ErrAuthHeaderMissing = errors.New("htpx: authorization header missing")
var ErrEmptyAudience = errors.New("htpx: empty audience")
var ErrInvalidScheme = errors.New("htpx: invalid scheme")
var ErrInvalidURL = errors.New("htpx: invalid url")
var ErrMalformedAuthHeader = errors.New("htpx: malformed authorization header")
var ErrNotApplicable = errors.New("htpx: rewriter not applicable")
var ErrSignatureBodyTooLarge = errors.New("htpx: signed-request body exceeds size cap")
ErrSignatureBodyTooLarge is returned by computeDigest (via SignRequest and VerifyRequest) when the request body exceeds MaxSignatureBodyBytes. It is wrapped, so callers should use errors.Is to test it.
Functions ¶
func APIKeyMiddleware ¶
func APIKeyMiddleware(cfg *APIKeyAuthConfig) gin.HandlerFunc
APIKeyMiddleware creates a Gin middleware for API key authentication
func CacheMiddleware ¶
func CacheMiddleware(cfg *CacheConfig) gin.HandlerFunc
CacheMiddleware creates a response caching middleware
func CircuitBreakerMiddleware ¶
func CircuitBreakerMiddleware(cb *CircuitBreaker) gin.HandlerFunc
CircuitBreakerMiddleware creates a circuit breaker middleware for Gin
func CompressionMiddleware ¶
func CompressionMiddleware(cfg *CompressionConfig) gin.HandlerFunc
CompressionMiddleware creates a response compression middleware
func ConstantTimeCompare ¶
ConstantTimeCompare performs a constant-time comparison of two strings
func FIDOMiddleware ¶
func FIDOMiddleware(store FIDOStore) gin.HandlerFunc
FIDOMiddleware creates a Gin middleware for FIDO2 authentication
func GenerateKeyPair ¶
GenerateKeyPair generates a new RSA key pair for testing
func GenerateTLSCertificate ¶
GenerateTLSCertificate generates a self-signed TLS certificate.
func LoadPrivateKey ¶
LoadPrivateKey loads a private key from PEM bytes
func LoadPublicKey ¶
LoadPublicKey loads a public key from PEM bytes
func RequestLogger ¶
func RequestLogger(logger *slog.Logger) gin.HandlerFunc
RequestLogger returns the Gin request-logging middleware htpx installs on every server. It emits one structured slog record per request via github.com/samber/slog-gin with slog-gin's DefaultConfig: the request method and path are logged under a "request" group (request.method, request.path), the response status under a "response" group (response.status), and a request id under the "id" key (taken from the inbound X-Request-Id header, or generated when absent). Passing a logger backed by a custom slog.Handler lets callers/tests capture and assert that contract; New uses RequestLogger(slog.Default()) so the production wiring and the tested wiring share one construction point (GAP-0057).
func RequireScope ¶
func RequireScope(scope string) gin.HandlerFunc
RequireScope returns a middleware that requires a specific scope
func SignatureMiddleware ¶
func SignatureMiddleware(verifier *Verifier) gin.HandlerFunc
SignatureMiddleware creates a Gin middleware for signature verification
Types ¶
type APIKey ¶
type APIKey struct {
ID string `json:"id"`
Name string `json:"name"`
KeyHash string `json:"key_hash"`
Prefix string `json:"prefix"`
Scopes []string `json:"scopes"`
Metadata map[string]any `json:"metadata"`
Created time.Time `json:"created"`
LastUsed time.Time `json:"last_used"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
RateLimitID string `json:"rate_limit_id"`
Enabled bool `json:"enabled"`
}
APIKey represents an API key
type APIKeyAuthConfig ¶
type APIKeyAuthConfig struct {
// Manager is the API key manager
Manager *APIKeyManager
// HeaderName is the header to check for the API key (default: X-API-Key)
HeaderName string
// RequireScopes are the scopes required for this route
RequireScopes []string
// Optional makes the API key optional (for public endpoints with optional auth)
Optional bool
}
APIKeyAuthConfig configures API key authentication
type APIKeyManager ¶
type APIKeyManager struct {
// contains filtered or unexported fields
}
APIKeyManager manages API keys
func NewAPIKeyManager ¶
func NewAPIKeyManager(store APIKeyStore, logger *slog.Logger) *APIKeyManager
NewAPIKeyManager creates a new API key manager
func (*APIKeyManager) DeleteKey ¶
func (m *APIKeyManager) DeleteKey(id string) error
DeleteKey deletes an API key
func (*APIKeyManager) GenerateKey ¶
func (m *APIKeyManager) GenerateKey(name string, scopes []string, metadata map[string]any, expiresAt *time.Time) (*APIKey, string, error)
GenerateKey generates a new API key
func (*APIKeyManager) GetKey ¶
func (m *APIKeyManager) GetKey(id string) (*APIKey, error)
GetKey returns a specific API key by ID
func (*APIKeyManager) ListKeys ¶
func (m *APIKeyManager) ListKeys() ([]*APIKey, error)
ListKeys returns all API keys
func (*APIKeyManager) RevokeKey ¶
func (m *APIKeyManager) RevokeKey(id string) error
RevokeKey revokes an API key
func (*APIKeyManager) ValidateKey ¶
func (m *APIKeyManager) ValidateKey(keyStr string) (*APIKey, error)
ValidateKey validates an API key and returns the key object
type APIKeyStats ¶
type APIKeyStats struct {
// contains filtered or unexported fields
}
APIKeyStats tracks API key usage statistics
func (*APIKeyStats) GetAllStats ¶
func (s *APIKeyStats) GetAllStats() map[string]any
GetAllStats returns stats for all API keys
func (*APIKeyStats) GetStats ¶
func (s *APIKeyStats) GetStats(keyID string) map[string]any
GetStats returns stats for a specific API key
func (*APIKeyStats) RecordRequest ¶
func (s *APIKeyStats) RecordRequest(keyID string, err error)
RecordRequest records a request for an API key
type APIKeyStore ¶
type APIKeyStore interface {
// GetByHash retrieves an API key by its hash
GetByHash(hash string) (*APIKey, error)
// GetByID retrieves an API key by its ID
GetByID(id string) (*APIKey, error)
// GetByPrefix retrieves an API key by its prefix
GetByPrefix(prefix string) (*APIKey, error)
// Save saves or updates an API key
Save(key *APIKey) error
// Delete deletes an API key by ID
Delete(id string) error
// List returns all API keys
List() ([]*APIKey, error)
// UpdateLastUsed updates the last used timestamp
UpdateLastUsed(id string, t time.Time) error
}
APIKeyStore defines the interface for storing and retrieving API keys
type CacheConfig ¶
type CacheConfig struct {
// Store is the cache store
Store CacheStore
// TTL is the default cache time-to-live
TTL time.Duration
// KeyFunc generates cache keys (default: method + URL)
KeyFunc func(*gin.Context) string
// ShouldCache determines if a response should be cached
ShouldCache func(*gin.Context) bool
}
CacheConfig configures response caching
type CacheEntry ¶
type CacheEntry struct {
StatusCode int
Headers http.Header
Body []byte
Timestamp time.Time
TTL time.Duration
}
CacheEntry represents a cached response
func (*CacheEntry) IsExpired ¶
func (e *CacheEntry) IsExpired() bool
IsExpired checks if the cache entry has expired
type CacheStore ¶
type CacheStore interface {
Get(key string) (*CacheEntry, error)
Set(key string, entry *CacheEntry) error
Delete(key string) error
Clear() error
}
CacheStore defines the interface for caching
type CircuitBreaker ¶
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker implements the circuit breaker pattern
func NewCircuitBreaker ¶
func NewCircuitBreaker(cfg *CircuitBreakerConfig) *CircuitBreaker
NewCircuitBreaker creates a new circuit breaker
func (*CircuitBreaker) Execute ¶
func (cb *CircuitBreaker) Execute(fn func() error) error
Execute executes a function with circuit breaker protection
func (*CircuitBreaker) State ¶
func (cb *CircuitBreaker) State() CircuitState
State returns the current circuit state
func (*CircuitBreaker) Stats ¶
func (cb *CircuitBreaker) Stats() map[string]any
Stats returns circuit breaker statistics
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
// MaxFailures is the number of failures before opening the circuit
MaxFailures int64
// Timeout is how long to wait before attempting to close the circuit
Timeout time.Duration
// FailureThreshold is the percentage of failures to trigger circuit open (0-100)
FailureThreshold float64
// MinRequests is the minimum number of requests before evaluating failure rate
MinRequests int64
// OnStateChange is called when the circuit state changes
OnStateChange func(from, to CircuitState)
}
CircuitBreakerConfig configures a circuit breaker
type CircuitState ¶
type CircuitState int
CircuitState represents the state of a circuit breaker
const ( CircuitClosed CircuitState = iota CircuitOpen CircuitHalfOpen )
func (CircuitState) String ¶
func (s CircuitState) String() string
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func (*Client) JSONReader ¶
func (c *Client) JSONReader(in any) (io.ReadCloser, error)
func (*Client) Post ¶
func (c *Client) Post( uri string, query url.Values, body io.ReadCloser, opts ...RequestOption, ) (*http.Response, error)
type ClientWrapper ¶
type CompressionConfig ¶
type FIDOConfig ¶
type FIDOConfig struct {
// RPDisplayName is the relying party display name (e.g., "My App")
RPDisplayName string
// RPID is the relying party ID (e.g., "example.com")
RPID string
// RPOrigins are the allowed origins for WebAuthn requests
RPOrigins []string
// Timeout is the timeout for WebAuthn ceremonies (default: 60s)
Timeout time.Duration
// Debug enables debug logging
Debug bool
// Logger for WebAuthn operations
Logger *slog.Logger
// Store is the credential store
Store FIDOStore
}
FIDOConfig configures WebAuthn/FIDO2 authentication
type FIDOCredential ¶
type FIDOCredential struct {
ID []byte `json:"id"`
PublicKey []byte `json:"public_key"`
AttestationType string `json:"attestation_type"`
Transport []protocol.AuthenticatorTransport `json:"transport"`
Flags webauthn.CredentialFlags `json:"flags"`
Authenticator webauthn.Authenticator `json:"authenticator"`
BackupEligible bool `json:"backup_eligible"`
BackupState bool `json:"backup_state"`
Created time.Time `json:"created"`
LastUsed time.Time `json:"last_used"`
}
FIDOCredential represents a WebAuthn credential
func FromWebAuthn ¶
func FromWebAuthn(cred *webauthn.Credential) *FIDOCredential
FromWebAuthn creates a FIDOCredential from webauthn.Credential
func (*FIDOCredential) ToWebAuthn ¶
func (c *FIDOCredential) ToWebAuthn() webauthn.Credential
ToWebAuthn converts FIDOCredential to webauthn.Credential
type FIDOServer ¶
type FIDOServer struct {
// contains filtered or unexported fields
}
FIDOServer provides WebAuthn/FIDO2 authentication handlers
func NewFIDOServer ¶
func NewFIDOServer(cfg *FIDOConfig) (*FIDOServer, error)
NewFIDOServer creates a new FIDO server
func (*FIDOServer) BeginLogin ¶
func (s *FIDOServer) BeginLogin(c *gin.Context)
BeginLogin starts the FIDO2 authentication ceremony
func (*FIDOServer) BeginRegistration ¶
func (s *FIDOServer) BeginRegistration(c *gin.Context)
BeginRegistration starts the FIDO2 registration ceremony
func (*FIDOServer) FinishLogin ¶
func (s *FIDOServer) FinishLogin(c *gin.Context)
FinishLogin completes the FIDO2 authentication ceremony
func (*FIDOServer) FinishRegistration ¶
func (s *FIDOServer) FinishRegistration(c *gin.Context)
FinishRegistration completes the FIDO2 registration ceremony
func (*FIDOServer) RegisterRoutes ¶
func (s *FIDOServer) RegisterRoutes(r gin.IRouter)
RegisterRoutes registers FIDO2 routes on a Gin router
type FIDOStore ¶
type FIDOStore interface {
// GetUser retrieves a user by ID
GetUser(userID []byte) (*FIDOUser, error)
// GetUserByName retrieves a user by username
GetUserByName(username string) (*FIDOUser, error)
// SaveUser saves or updates a user
SaveUser(user *FIDOUser) error
// SaveCredential saves a credential for a user
SaveCredential(userID []byte, credential *FIDOCredential) error
// GetCredentials retrieves all credentials for a user
GetCredentials(userID []byte) ([]*FIDOCredential, error)
// UpdateCredential updates a credential (e.g., sign count)
UpdateCredential(credentialID []byte, credential *FIDOCredential) error
}
FIDOStore defines the interface for storing and retrieving WebAuthn credentials
type FIDOUser ¶
type FIDOUser struct {
ID []byte `json:"id"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
Credentials []*FIDOCredential
}
FIDOUser represents a WebAuthn user
func GetFIDOUser ¶
GetFIDOUser retrieves the authenticated FIDO user from the context
func (*FIDOUser) MarshalJSON ¶
MarshalJSON implements json.Marshaler for FIDOUser
func (*FIDOUser) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler for FIDOUser
func (*FIDOUser) WebAuthnCredentials ¶
func (u *FIDOUser) WebAuthnCredentials() []webauthn.Credential
WebAuthnCredentials returns the user's credentials
func (*FIDOUser) WebAuthnDisplayName ¶
WebAuthnDisplayName returns the display name for WebAuthn
func (*FIDOUser) WebAuthnID ¶
WebAuthnID returns the user ID for WebAuthn
func (*FIDOUser) WebAuthnIcon ¶
WebAuthnIcon returns the user icon URL (deprecated in WebAuthn spec)
func (*FIDOUser) WebAuthnName ¶
WebAuthnName returns the username for WebAuthn
type HTTPExchange ¶
type HTTPExchange struct {
Request *ReplayRequest `json:"request"`
Response *ReplayResult `json:"response"`
}
HTTPExchange represents an HTTP request/response pair
type KeyStore ¶
type KeyStore interface {
// GetPublicKey retrieves a public key by key ID
GetPublicKey(keyID string) (any, error)
}
KeyStore provides public keys for signature verification
type MemoryAPIKeyStore ¶
type MemoryAPIKeyStore struct {
// contains filtered or unexported fields
}
MemoryAPIKeyStore is an in-memory implementation of APIKeyStore
func NewMemoryAPIKeyStore ¶
func NewMemoryAPIKeyStore() *MemoryAPIKeyStore
NewMemoryAPIKeyStore creates a new in-memory API key store
func (*MemoryAPIKeyStore) Delete ¶
func (s *MemoryAPIKeyStore) Delete(id string) error
func (*MemoryAPIKeyStore) GetByHash ¶
func (s *MemoryAPIKeyStore) GetByHash(hash string) (*APIKey, error)
func (*MemoryAPIKeyStore) GetByPrefix ¶
func (s *MemoryAPIKeyStore) GetByPrefix(prefix string) (*APIKey, error)
func (*MemoryAPIKeyStore) List ¶
func (s *MemoryAPIKeyStore) List() ([]*APIKey, error)
func (*MemoryAPIKeyStore) Save ¶
func (s *MemoryAPIKeyStore) Save(key *APIKey) error
func (*MemoryAPIKeyStore) UpdateLastUsed ¶
func (s *MemoryAPIKeyStore) UpdateLastUsed(id string, t time.Time) error
type MemoryCacheStore ¶
type MemoryCacheStore struct {
// contains filtered or unexported fields
}
MemoryCacheStore is an in-memory cache store
func NewMemoryCacheStore ¶
func NewMemoryCacheStore() *MemoryCacheStore
NewMemoryCacheStore creates a new in-memory cache store
func (*MemoryCacheStore) Clear ¶
func (s *MemoryCacheStore) Clear() error
func (*MemoryCacheStore) Delete ¶
func (s *MemoryCacheStore) Delete(key string) error
func (*MemoryCacheStore) Get ¶
func (s *MemoryCacheStore) Get(key string) (*CacheEntry, error)
func (*MemoryCacheStore) Set ¶
func (s *MemoryCacheStore) Set(key string, entry *CacheEntry) error
type MemoryFIDOStore ¶
type MemoryFIDOStore struct {
// contains filtered or unexported fields
}
MemoryFIDOStore is an in-memory implementation of FIDOStore for development/testing
func NewMemoryFIDOStore ¶
func NewMemoryFIDOStore() *MemoryFIDOStore
NewMemoryFIDOStore creates a new in-memory FIDO store
func (*MemoryFIDOStore) GetCredentials ¶
func (s *MemoryFIDOStore) GetCredentials(userID []byte) ([]*FIDOCredential, error)
func (*MemoryFIDOStore) GetUser ¶
func (s *MemoryFIDOStore) GetUser(userID []byte) (*FIDOUser, error)
func (*MemoryFIDOStore) GetUserByName ¶
func (s *MemoryFIDOStore) GetUserByName(username string) (*FIDOUser, error)
func (*MemoryFIDOStore) SaveCredential ¶
func (s *MemoryFIDOStore) SaveCredential(userID []byte, credential *FIDOCredential) error
func (*MemoryFIDOStore) SaveUser ¶
func (s *MemoryFIDOStore) SaveUser(user *FIDOUser) error
func (*MemoryFIDOStore) UpdateCredential ¶
func (s *MemoryFIDOStore) UpdateCredential(credentialID []byte, credential *FIDOCredential) error
type MemoryKeyStore ¶
type MemoryKeyStore struct {
// contains filtered or unexported fields
}
MemoryKeyStore is an in-memory key store
func NewMemoryKeyStore ¶
func NewMemoryKeyStore() *MemoryKeyStore
NewMemoryKeyStore creates a new in-memory key store
func (*MemoryKeyStore) AddKey ¶
func (s *MemoryKeyStore) AddKey(keyID string, key any)
AddKey adds a key to the store
func (*MemoryKeyStore) GetPublicKey ¶
func (s *MemoryKeyStore) GetPublicKey(keyID string) (any, error)
GetPublicKey retrieves a public key by ID
type MockEndpoint ¶
type MockEndpoint struct {
Method string `json:"method"`
Path string `json:"path"`
StatusCode int `json:"status_code"`
Response any `json:"response"`
Headers map[string]string `json:"headers,omitempty"`
Delay time.Duration `json:"delay,omitempty"`
MatchQuery map[string]string `json:"match_query,omitempty"`
MatchBody map[string]any `json:"match_body,omitempty"`
}
MockEndpoint represents a mock API endpoint
func LoadMockEndpointsFromJSON ¶
func LoadMockEndpointsFromJSON(data []byte) ([]*MockEndpoint, error)
LoadMockEndpointsFromJSON loads mock endpoints from JSON
type MockServer ¶
type MockServer struct {
// contains filtered or unexported fields
}
MockServer provides a configurable mock HTTP server
func NewMockServer ¶
func NewMockServer(logger *slog.Logger) *MockServer
NewMockServer creates a new mock server
func (*MockServer) AddEndpoint ¶
func (ms *MockServer) AddEndpoint(endpoint *MockEndpoint)
AddEndpoint adds a mock endpoint
func (*MockServer) AddEndpoints ¶
func (ms *MockServer) AddEndpoints(endpoints []*MockEndpoint)
AddEndpoints adds multiple endpoints
func (*MockServer) Handler ¶
func (ms *MockServer) Handler() http.Handler
Handler returns the HTTP handler
type OIDC ¶
type OIDC struct {
Issuer string `json:"issuer" validate:"required,url,max=255"`
AuthZURL *url.URL
TokenURL *url.URL
UserURL *url.URL
LogoutURL *url.URL
IntrospectURL *url.URL
RevocationURL *url.URL
DeviceAuthzURL *url.URL
JWKsURL *url.URL
// JWKs holds the cold-start key set so legacy callers continue to
// observe a non-nil reference. The authoritative, auto-refreshing
// view lives behind jwkCache and is consulted on every JWT
// validation path so IdP key rotation is picked up without a host
// process restart (PERF-0043, SEC #150).
JWKs jwk.Set
Aud string
ResponseTypes [][]string
ResponseModes []string `json:"response_modes_supported"`
GrantTypes []string `json:"grant_types_supported"`
SigningAlgos []string `json:"id_token_signing_alg_values_supported"`
SubjectTypes []string `json:"subject_types_supported"`
AuthMethods []string `json:"token_endpoint_auth_methods_supported"`
AcrValues []string `json:"acr_values_supported"`
Scopes []string `json:"scopes_supported"`
Claims []string `json:"claims_supported"`
CodeChallengeMethods []string `json:"code_challenge_methods_supported"`
ClaimsParameters bool `json:"claims_parameter_supported"`
RequestParameter bool `json:"request_parameter_supported"`
// contains filtered or unexported fields
}
func LoadOIDC ¶
LoadOIDC loads the OpenID Connect configuration from the given URL. @client: HTTP client to use for the request. @url: URL of the OpenID Connect configuration endpoint. @aud: Audience of the OpenID Connect configuration endpoint (usually the client ID of the application). @return: OpenID Connect configuration.
func (*OIDC) Authenticate ¶
func (o *OIDC) Authenticate( ctx context.Context, input *oapifilter.AuthenticationInput, ) error
ValidateToken middleware verifies a valid Auth0 JWT token being present in the request.
func (*OIDC) ExtractToken ¶
ExtractToken parses the Authorization HTTP header for valid JWT token and validates it with the JWK keys. Also verifies if the audience present in the token matches with the designated audience as per current configuration.
func (*OIDC) UnmarshalJSON ¶
type Option ¶
func WithAutoRefreshToken ¶
func WithAutoRefreshToken(refresher *TokenRefresher) Option
WithAutoRefreshToken creates a client with automatic token refresh
func WithBasicAuth ¶
func WithBearerToken ¶
func WithCircuitBreaker ¶
func WithCircuitBreaker(cb *CircuitBreaker) Option
func WithDebugFile ¶
func WithDoer ¶
func WithDoer(client HTTPClient) Option
func WithHeader ¶
func WithLimiter ¶
func WithLogger ¶
func WithMaxResponseBytes ¶
WithMaxResponseBytes sets the ceiling on response-body bytes buffered by ReadJSON. A value <=0 disables the limit (unbounded; use only for trusted upstreams). The default is DefaultMaxResponseBytes (32 MiB) (PERF-0024).
func WithOAuth2 ¶
func WithSignature ¶
WithSignature adds HTTP signature signing to the client
func WithTransport ¶
func WithTransport(transport http.RoundTripper) Option
type ProxyOption ¶
type ProxyOption func(*proxy) error
func WithCertificate ¶
func WithCertificate(cert, key string) ProxyOption
func WithClient ¶
func WithClient(c *Client) ProxyOption
func WithRewriters ¶
func WithRewriters(r ...Rewriter) ProxyOption
func WithRule ¶
func WithRule(name string, rule Rule) ProxyOption
func WithSubnetFilter ¶
func WithSubnetFilter(subnets ...netip.Prefix) ProxyOption
func WithTLSConfig ¶
func WithTLSConfig(cfg *tls.Config) ProxyOption
type ReplayRequest ¶
type ReplayRequest struct {
Method string `json:"method"`
URL string `json:"url"`
Headers map[string]string `json:"headers"`
Body []byte `json:"body,omitempty"`
}
ReplayRequest represents a captured HTTP request for replay
func LoadRequestsFromJSON ¶
func LoadRequestsFromJSON(data []byte) ([]*ReplayRequest, error)
LoadRequestsFromJSON loads replay requests from JSON
type ReplayResult ¶
type ReplayResult struct {
Request *ReplayRequest
StatusCode int
Headers http.Header
Body []byte
Duration time.Duration
Error error
Timestamp time.Time
}
ReplayResult contains the result of a replayed request
type Replayer ¶
type Replayer struct {
// contains filtered or unexported fields
}
Replayer replays captured HTTP requests
func NewReplayer ¶
NewReplayer creates a new request replayer
func (*Replayer) Replay ¶
func (r *Replayer) Replay(ctx context.Context, req *ReplayRequest) *ReplayResult
Replay replays a single request
func (*Replayer) ReplayBatch ¶
func (r *Replayer) ReplayBatch(ctx context.Context, requests []*ReplayRequest, parallel bool) []*ReplayResult
ReplayBatch replays multiple requests
type RequestOption ¶
func WithBody ¶
func WithBody(body io.ReadCloser) RequestOption
func WithMethod ¶
func WithMethod(method string) RequestOption
func WithQuery ¶
func WithQuery(query url.Values) RequestOption
func WithRequestAuth ¶
func WithRequestAuth(auth string) RequestOption
func WithRequestHeader ¶
func WithRequestHeader(key, value string) RequestOption
type RetryConfig ¶
type RetryConfig struct {
// MaxAttempts is the maximum number of retry attempts
MaxAttempts int
// InitialDelay is the delay before the first retry
InitialDelay time.Duration
// MaxDelay is the maximum delay between retries
MaxDelay time.Duration
// Multiplier is the backoff multiplier (default: 2.0)
Multiplier float64
// ShouldRetry determines if a request should be retried
ShouldRetry func(*http.Response, error) bool
}
RetryConfig configures retry behavior
type Rewriter ¶
type ServerOption ¶
type ServerOption func(*apiServer) error
func WithAPIKeyManager ¶
func WithAPIKeyManager(manager *APIKeyManager, adminAuth gin.HandlerFunc) ServerOption
WithAPIKeyManager adds API key management routes to the server
func WithCORS ¶
func WithCORS(allowedOrigins []string, methods ...string) ServerOption
func WithErrorHandler ¶
func WithErrorHandler(handler func(ctx *gin.Context, err error, i int)) ServerOption
func WithFIDO ¶
func WithFIDO(cfg *FIDOConfig) ServerOption
WithFIDO adds FIDO2 authentication to an API server
func WithHost ¶
func WithHost(host string) ServerOption
func WithImpl ¶
func WithImpl(impl any) ServerOption
func WithMiddleware ¶
func WithMiddleware(middleware ...gin.HandlerFunc) ServerOption
func WithPerIPRateLimit ¶
func WithPerIPRateLimit() ServerOption
WithPerIPRateLimit enables per-remote-IP token buckets instead of global bucket.
func WithPort ¶
func WithPort(port int) ServerOption
func WithServerLogger ¶
func WithServerLogger(logger log.Logger) ServerOption
func WithSwaggerSpec ¶
func WithSwaggerSpec(spec *openapi3.T) ServerOption
func WithTLS ¶
func WithTLS(cert, key string) ServerOption
func WithTrustedProxies ¶
func WithTrustedProxies(proxies []string) ServerOption
func WithValidation ¶
func WithValidation( ctx context.Context, oidc string, audience string, ) ServerOption
type SignatureAlgorithm ¶
type SignatureAlgorithm string
SignatureAlgorithm represents the signature algorithm
const ( AlgoHMAC_SHA256 SignatureAlgorithm = "hmac-sha256" AlgoRSA_SHA256 SignatureAlgorithm = "rsa-sha256" AlgoECDSA_SHA256 SignatureAlgorithm = "ecdsa-sha256" AlgoED25519 SignatureAlgorithm = "ed25519" )
type SignatureConfig ¶
type SignatureConfig struct {
// KeyID identifies the key used for signing
KeyID string
// Algorithm is the signature algorithm
Algorithm SignatureAlgorithm
// PrivateKey is the private key for signing (crypto.Signer or []byte for HMAC)
PrivateKey any
// PublicKey is the public key for verification (crypto.PublicKey or []byte for HMAC)
PublicKey any
// Headers are the headers to include in the signature (default: date, digest)
Headers []string
// IncludeDigest adds a Digest header with the request body hash
IncludeDigest bool
// MaxClockSkew is the maximum allowed clock skew for date validation (default: 5 minutes)
MaxClockSkew time.Duration
}
SignatureConfig configures HTTP signature signing/verification
type SignatureInfo ¶
type SignatureInfo struct {
KeyID string
Algorithm SignatureAlgorithm
Headers []string
Signature string
}
SignatureInfo contains parsed signature information
type SignatureStats ¶
SignatureStats tracks signature verification statistics
func NewSignatureStats ¶
func NewSignatureStats() *SignatureStats
NewSignatureStats creates a new stats tracker
func (*SignatureStats) Record ¶
func (s *SignatureStats) Record(err error)
Record records a verification result
func (*SignatureStats) Summary ¶
func (s *SignatureStats) Summary() map[string]any
Summary returns a summary of statistics
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer signs HTTP requests
func NewSigner ¶
func NewSigner(cfg *SignatureConfig) (*Signer, error)
NewSigner creates a new HTTP signature signer
type TokenRefresher ¶
type TokenRefresher struct {
// contains filtered or unexported fields
}
TokenRefresher automatically refreshes OAuth2 tokens
func NewTokenRefresher ¶
func NewTokenRefresher(config *oauth2.Config, token *oauth2.Token, logger *slog.Logger) *TokenRefresher
NewTokenRefresher creates a new token refresher
func (*TokenRefresher) Client ¶
func (tr *TokenRefresher) Client(ctx context.Context) *http.Client
Client returns an HTTP client with automatic token refresh
func (*TokenRefresher) OnRefresh ¶
func (tr *TokenRefresher) OnRefresh(fn func(*oauth2.Token))
OnRefresh sets a callback for when the token is refreshed
func (*TokenRefresher) Start ¶
func (tr *TokenRefresher) Start(ctx context.Context) error
Start starts the automatic token refresh
func (*TokenRefresher) Token ¶
func (tr *TokenRefresher) Token() *oauth2.Token
Token returns the current token
type TrafficDiff ¶
type TrafficDiff struct {
Type string `json:"type"` // "method", "path", "header", "body", "status"
Field string `json:"field,omitempty"`
Expected any `json:"expected"`
Actual any `json:"actual"`
Description string `json:"description"`
}
TrafficDiff represents a difference between two HTTP exchanges
type TrafficDiffer ¶
type TrafficDiffer struct {
// contains filtered or unexported fields
}
TrafficDiffer compares HTTP traffic
func NewTrafficDiffer ¶
func NewTrafficDiffer() *TrafficDiffer
NewTrafficDiffer creates a new traffic differ
func (*TrafficDiffer) Compare ¶
func (td *TrafficDiffer) Compare(expected, actual *HTTPExchange) []*TrafficDiff
Compare compares two HTTP exchanges
func (*TrafficDiffer) IgnoreFields ¶
func (td *TrafficDiffer) IgnoreFields(fields ...string)
IgnoreFields sets JSON fields to ignore in body comparisons
func (*TrafficDiffer) IgnoreHeaders ¶
func (td *TrafficDiffer) IgnoreHeaders(headers ...string)
IgnoreHeaders sets headers to ignore in comparisons
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier verifies HTTP signatures
func NewVerifier ¶
NewVerifier creates a new HTTP signature verifier