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 Client() middleware.Middleware
- func NewAuthenticator(opts ...Option) authn.Authenticator
- func Server(opts ...Option) middleware.Middleware
- func TokenFrom(ctx context.Context) (string, bool)
- 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 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, an anonymous actor is returned with nil error (pass-through mode). If a token is found but no Verifier is configured, an anonymous actor is also returned (pass-through mode for local/test).
Verifier failure → (nil, err). ClaimsMapper failure → (nil, 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 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 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 actor.Actor.
This is the extension point business code uses to interpret IdP-specific claims. The framework ships only a minimal three-piece 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 maps ONLY the canonical JWT claims that every Bearer JWT carries to the actor three-piece (Type/ID/DisplayName):
- sub → actor.UserActor.ID (REQUIRED; empty → error)
- name → actor.UserActor.DisplayName
- preferred_username → actor.UserActor.DisplayName (fallback when name absent)
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 convert JWT claims into an actor.Actor. Defaults to DefaultClaimsMapper, which maps only the canonical three-piece (sub → ID, name/preferred_username → DisplayName).
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).