serviceauth

package
v1.31.1 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package serviceauth provides constant-time validation of shared service-to-service tokens. It is intended for the IAM mono-repo's service-to-service auth edges (auth ↔ caller, dataaccess ↔ caller, ...) and answers the question "is the calling process a trusted peer service". It does NOT establish end-user identity — see pkg/userauth for that.

Each service owns its own metadata header name and interceptor; this package only owns the comparison logic.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnauthorized = errors.New("unauthorized")

ErrUnauthorized is returned when the presented token does not match any of the configured tokens.

Functions

func HTTPMiddleware added in v1.26.0

func HTTPMiddleware(next http.Handler, cfg Config, headerName string) http.Handler

HTTPMiddleware returns middleware that validates the service token presented under headerName against the tokens derived from cfg (Config.Tokens()). It wraps next and rejects requests where the header is missing, empty, or does not match — responding with 401 Unauthorized and a JSON body {"error":"Unauthorized"}.

cfg.NextServiceToken, if set, is accepted alongside cfg.ServiceToken to support zero-downtime rotation.

func UnaryServerInterceptor added in v1.26.0

func UnaryServerInterceptor(cfg Config, headerName string, publicMethods map[string]bool) grpc.UnaryServerInterceptor

UnaryServerInterceptor returns a gRPC unary server interceptor that validates the service token presented under headerName for all RPCs not in publicMethods. The accepted tokens are derived from cfg (Config.Tokens()).

On any failure — missing metadata, missing or empty header, or token rejection — the interceptor returns codes.Unauthenticated with an opaque "Unauthorized" message. Distinguishing the cause would leak whether a token was provided, providing an oracle to attackers.

Types

type Config added in v1.26.0

type Config struct {
	ServiceToken     string `mapstructure:"service_token"`
	NextServiceToken string `mapstructure:"next_service_token"`
}

Config is the subset of a service's configuration that controls service-to-service shared-secret authentication. Services embed this with the mapstructure squash tag so the TOML keys sit at the top level of the service's table, e.g.:

[services.data-access]
service_token = "..."
next_service_token = ""

During rotation, NextServiceToken holds the new token alongside the current one; a Validator built from Tokens() accepts either.

func (Config) Tokens added in v1.26.0

func (c Config) Tokens() []string

Tokens returns the rotation pair as a slice suitable for NewValidator. Empty entries are passed through; NewValidator ignores them.

func (Config) Validate added in v1.26.0

func (c Config) Validate() error

Validate returns an error if the required ServiceToken is missing. NextServiceToken is optional and only used during rotation.

type Validator

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

Validator performs constant-time token validation against a set of pre-computed SHA-512 hashes. It is safe for concurrent use.

func NewValidator

func NewValidator(tokens ...string) *Validator

NewValidator creates a Validator that accepts the given tokens. Empty token strings are silently ignored so callers can pass an optional next-token slot without conditional logic.

func (*Validator) Validate

func (v *Validator) Validate(_ context.Context, providedToken string) error

Validate checks whether the provided token matches any of the configured tokens. Returns nil on success, ErrUnauthorized on failure.

All configured hashes are checked without short-circuiting so the total work is constant regardless of which (if any) token matches.

Jump to

Keyboard shortcuts

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