Documentation
¶
Overview ¶
Package interceptor implements the gRPC interceptor chain for the token-engine service. It does not implement the correlation interceptor — that lives in internal/observability. Chain order (maintained in main.go): otelgrpc → correlation → auth → caller auth → idempotency → validation. Primary dependencies: internal/observability for Logger and context key functions, internal/registry for CallerRegistry, internal/store for IdempotencyStore.
Index ¶
- Variables
- func NewAuthInterceptor(auth Authenticator, logger observability.Logger) grpc.UnaryServerInterceptor
- func NewCallerAuthorizationInterceptor(reg registry.CallerRegistry, logger observability.Logger) grpc.UnaryServerInterceptor
- func NewIdempotencyInterceptor(st store.IdempotencyStore, logger observability.Logger, ...) grpc.UnaryServerInterceptor
- func NewValidationInterceptor(logger observability.Logger) grpc.UnaryServerInterceptor
- type Authenticator
- type MTLSAuthenticator
- type StaticKeyAuthenticator
- type TenantAwareRequest
Constants ¶
This section is empty.
Variables ¶
var ReservedClaimKeys = map[string]struct{}{
"sub": {}, "iss": {}, "aud": {}, "exp": {}, "iat": {}, "nbf": {}, "jti": {},
}
ReservedClaimKeys is the set of JWT claim keys the validation interceptor rejects.
Functions ¶
func NewAuthInterceptor ¶
func NewAuthInterceptor(auth Authenticator, logger observability.Logger) grpc.UnaryServerInterceptor
NewAuthInterceptor returns a gRPC unary server interceptor that authenticates requests. On success, the caller identity is bound to the context via WithCallerIdentity. On authentication failure, the error is returned without calling the handler.
func NewCallerAuthorizationInterceptor ¶
func NewCallerAuthorizationInterceptor(reg registry.CallerRegistry, logger observability.Logger) grpc.UnaryServerInterceptor
NewCallerAuthorizationInterceptor returns a gRPC unary server interceptor for caller authorization. Skips authorization for gRPC health protocol RPCs. Returns codes.Internal if no caller identity is present in context (auth interceptor must run first). Returns codes.PermissionDenied if the caller is not authorized for the requested tenant.
func NewIdempotencyInterceptor ¶
func NewIdempotencyInterceptor(st store.IdempotencyStore, logger observability.Logger, metrics observability.Metrics) grpc.UnaryServerInterceptor
NewIdempotencyInterceptor returns a gRPC unary server interceptor providing at-most-once semantics for IssueToken and RefreshToken RPCs.
CRITICAL ordering for RefreshToken: the idempotency store check MUST occur BEFORE the library call. As of jwtauth v0.6.0 (#195), RefreshAccessTokenWithClaims revokes the old refresh token immediately. A retry arriving after the first call will receive ErrTokenRevoked from the library — the cached response must be returned before the library is ever called.
Key construction: idempotency:{tenantID}:{method}:{clientKey} where method is "IssueToken" or "RefreshToken".
Response type for both methods: *tokenv1.TokenPair. X-idempotency-key absent or empty: pass through without store interaction.
func NewValidationInterceptor ¶
func NewValidationInterceptor(logger observability.Logger) grpc.UnaryServerInterceptor
NewValidationInterceptor returns a gRPC unary server interceptor for request validation. Enforces non-empty sub on IssueToken and rejects reserved JWT claim keys on IssueToken and RefreshToken. All other methods pass through unchanged.
Types ¶
type Authenticator ¶
type Authenticator interface {
// Authenticate extracts a verified caller identity from the gRPC request context.
// Returns the caller identity string on success.
// Returns a gRPC status error directly — callers must not wrap the error.
Authenticate(ctx context.Context) (callerIdentity string, err error)
}
Authenticator extracts and verifies a caller identity from the gRPC request context.
type MTLSAuthenticator ¶ added in v0.5.0
type MTLSAuthenticator struct{}
MTLSAuthenticator authenticates requests using the TLS peer certificate Common Name. The gRPC server is configured with tls.RequireAndVerifyClientCert — the certificate has already been cryptographically verified before Authenticate is called. MTLSAuthenticator only extracts identity; it does not perform certificate verification. All methods are safe for concurrent use.
func NewMTLSAuthenticator ¶ added in v0.5.0
func NewMTLSAuthenticator() *MTLSAuthenticator
NewMTLSAuthenticator returns a new MTLSAuthenticator.
func (*MTLSAuthenticator) Authenticate ¶ added in v0.5.0
func (a *MTLSAuthenticator) Authenticate(ctx context.Context) (string, error)
Authenticate extracts the caller identity from the TLS peer certificate Common Name. Returns codes.Unauthenticated if: no peer in context, peer has no TLS credentials, peer has no certificates, or the leaf certificate has an empty Common Name.
type StaticKeyAuthenticator ¶
type StaticKeyAuthenticator struct {
// contains filtered or unexported fields
}
StaticKeyAuthenticator authenticates requests using a static mapping of API keys to caller identities.
func NewStaticKeyAuthenticator ¶
func NewStaticKeyAuthenticator(keys map[string]string) *StaticKeyAuthenticator
NewStaticKeyAuthenticator returns a new StaticKeyAuthenticator with the given key→identity mapping.
func (*StaticKeyAuthenticator) Authenticate ¶
func (a *StaticKeyAuthenticator) Authenticate(ctx context.Context) (string, error)
Authenticate extracts the API key from gRPC metadata and returns the mapped caller identity. If the key is absent or not found in the map, returns codes.Unauthenticated.
type TenantAwareRequest ¶ added in v0.5.0
type TenantAwareRequest interface {
GetTenantId() string
}
TenantAwareRequest is satisfied by all proto request messages containing a tenant_id field. Proto-gen-go generates GetTenantId() string for every proto3 message with a string tenant_id field. Used by the caller interceptor to extract tenant_id without type-asserting each request type individually.