Documentation
¶
Overview ¶
Package jwt provides a generic Bearer JWT authentication skeleton for the engine-agnostic authn dispatcher. It owns its credential I/O end-to-end:
- Server is a power-user convenience: the canonical thin wrapper around authn.Server + authn.Multi(authn.Named(jwt.Scheme, NewAuthenticator(...))) for the single-engine direct mount case.
- Client is a Kratos client middleware that propagates the token from the ctx into the outbound Authorization header.
- WithToken / TokenFrom are the jwt-package-private ctx channel; they are the supported way to read or write the raw bearer token in flight.
- NewAuthenticator exposes the bare engine for power users who want to compose their own wrapper (e.g. read the token from a non-HTTP carrier) or who wire several engines into authn.Multi directly.
Typical business usage:
import authjwt "github.com/Servora-Kit/servora/security/authn/jwt" mw = append(mw, authjwt.Server(authjwt.WithVerifier(km.Verifier())))
Multi-engine wiring (recommended for production):
mw = append(mw, authn.Server(
authn.Multi(
authn.Named(authjwt.Scheme, authjwt.NewAuthenticator(authjwt.WithVerifier(v))),
authn.Named(apikey.Scheme, apikey.NewAuthenticator(...)),
),
authn.WithRulesFuncs(examplev1.AuthnRules),
))
The transport middleware package MUST NOT host equivalents of WithToken / TokenFrom / Bearer extraction — those are jwt-engine concerns, not framework-wide concerns.
Index ¶
- Constants
- func ClaimsFrom(ctx context.Context) (gojwt.MapClaims, bool)
- func Client() middleware.Middleware
- func NewAuthenticator(opts ...Option) authn.Authenticator
- func Server(opts ...Option) middleware.Middleware
- func SubjectFrom(ctx context.Context) (string, bool)
- func TokenFrom(ctx context.Context) (string, bool)
- func WithClaims(ctx context.Context, claims gojwt.MapClaims) context.Context
- func WithToken(ctx context.Context, token string) context.Context
- type ClaimsMapper
- type Option
Constants ¶
const Scheme = "jwt"
Scheme is the canonical scheme string for this engine, paired with NewAuthenticator via authn.Named. The framework does not enumerate scheme constants — each engine sub-package owns its own string.
Variables ¶
This section is empty.
Functions ¶
func ClaimsFrom ¶ added in v0.5.0
ClaimsFrom reads the parsed JWT MapClaims previously stored by WithClaims. Returns (nil, false) if no claims are present in the context.
func Client ¶ added in v0.4.7
func Client() middleware.Middleware
Client returns a Kratos client middleware that propagates the jwt token previously stored in the ctx (by Server on the inbound side, or by an explicit WithToken call) into the outbound Authorization header as `Bearer <token>`.
If no token is present in the ctx or no client transport is attached, the middleware passes through without modification — never errors.
Business callers must opt in explicitly: the framework's default client chain does NOT include this middleware, because not every outbound call wants to forward an inbound credential (cross-realm calls, third-party integrations, etc.). See design.md Decision 5.
Typical usage:
conn, err := grpc.Dial(grpc.WithMiddleware(jwt.Client()))
func NewAuthenticator ¶
func NewAuthenticator(opts ...Option) authn.Authenticator
NewAuthenticator creates a JWT-based authn.Authenticator.
The returned authenticator's Authenticate(ctx) reads the raw bearer token from (in priority order):
- The jwt-private ctx channel (TokenFrom) — typically populated by Server before dispatch, or by upstream code via WithToken.
- The inbound Authorization header on the Kratos server transport — used when the engine is wired into authn.Multi directly without Server.
If no token is found, ctx is returned unchanged with nil error (pass-through mode). If a token is found but no Verifier is configured, ctx is also returned unchanged (pass-through mode for local/test).
Verifier failure → (ctx, err). ClaimsMapper failure → (ctx, err).
func Server ¶ added in v0.4.7
func Server(opts ...Option) middleware.Middleware
Server returns a Kratos server middleware that authenticates incoming requests with a single JWT engine. It is a power-user convenience wrapper for the most common single-engine direct mount:
jwt.Server(jwt.WithVerifier(v))
Internally this is exactly equivalent to:
authn.Server(authn.Multi(authn.Named(jwt.Scheme, jwt.NewAuthenticator(opts...))))
plus a pre-step that extracts the inbound Bearer token and stashes it into the jwt-private ctx channel (WithToken), so downstream middleware (e.g. Client for outbound propagation) and any business handler can read it via TokenFrom.
Business code that wires multiple engines (jwt + apikey, …) should NOT use this helper — call authn.Server + authn.Multi(authn.Named(...), …) directly so each engine contributes its own Named pair.
func SubjectFrom ¶ added in v0.5.0
SubjectFrom is a convenience accessor that reads the "sub" claim from the jwt-private claims ctx channel. It returns ("", false) if no claims are present or if "sub" is missing or not a string.
func TokenFrom ¶ added in v0.4.8
TokenFrom reads the raw bearer token previously stored by WithToken. It is used by Client for outbound propagation, and may be used by business middleware that wants to observe the inbound token. Returns ("", false) if no token is present.
func WithClaims ¶ added in v0.5.0
WithClaims stores the parsed JWT MapClaims into a jwt-package-private ctx channel. It is invoked by the default ClaimsMapper after successful verification, and may also be called by custom mappers that wish to expose the full claims to downstream handlers via ClaimsFrom.
func WithToken ¶ added in v0.4.7
WithToken stores the raw bearer token into a jwt-package-private ctx channel. It is invoked by Server after parsing the inbound Authorization header, and may also be called directly by upstream code that obtained a token via some other path (e.g., re-injection during a retry, or a non-HTTP carrier feeding a custom wrapper around NewAuthenticator).
The channel is intentionally jwt-private. The general transport middleware package MUST NOT host equivalent helpers — credential carrier shape (the Bearer token format) is jwt-engine concern, not framework-wide concern.
Types ¶
type ClaimsMapper ¶
ClaimsMapper converts parsed JWT MapClaims into an enriched context.
The first parameter is the incoming ctx that the engine needs to write private ctx channels into. The returned context carries whatever the mapper chose to store (at minimum the full claims map via WithClaims).
This is the extension point business code uses to interpret IdP-specific claims. The framework ships only a minimal default — anything richer (custom roles, tenant, scopes, group memberships, …) belongs in business code, plugged via WithClaimsMapper.
func DefaultClaimsMapper ¶
func DefaultClaimsMapper() ClaimsMapper
DefaultClaimsMapper returns the framework's minimal Bearer-JWT mapper.
It validates that the `sub` claim is present and non-empty (REQUIRED), then stores the full claims map into the jwt-private ctx channel via WithClaims. Downstream handlers read individual claims via ClaimsFrom or the convenience SubjectFrom.
IdP-specific claim interpretation (azp, scope, email, roles, groups, custom claims, …) is intentionally NOT covered. Business code that needs those fields installs its own ClaimsMapper via WithClaimsMapper.
type Option ¶
type Option func(*authenticatorConfig)
Option configures the JWT Authenticator.
func WithClaimsMapper ¶
func WithClaimsMapper(m ClaimsMapper) Option
WithClaimsMapper sets a custom ClaimsMapper to enrich the ctx with parsed JWT claims. Defaults to DefaultClaimsMapper, which validates the sub claim and stores the full claims map via WithClaims.
Business code that needs IdP-specific fields (custom roles / scopes / tenant / group memberships / …) installs its own mapper here.
func WithVerifier ¶
WithVerifier sets the JWT verifier used to validate token signatures. If nil, the authenticator operates in pass-through mode (anonymous actor returned without an error).