jwt

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2026 License: MIT, MIT Imports: 30 Imported by: 0

README

GoModularAuth JWT Plugin (gomodularauth-jwt)

An optional, production-grade JWT (JSON Web Token) plugin library for GoModularAuth. It provides stateless, cryptographically signed token issuance and verification for integrations requiring decoupled or distributed token verification (e.g. public APIs, microservices, OAuth2/OIDC interoperability, and mobile clients) without replacing Core server-side opaque Sessions.

Installation

go get github.com/BladiCreator/go-modular-auth/plugins/jwt

Quick Start


Detailed guide: doc/plugins/jwt.md.

Documentation

Overview

Package jwt provides stateless, signed JSON Web Token (JWT) issuance and verification with support for HMAC, RSA, and ECDSA key suites.

Index

Constants

View Source
const (
	// EventJWTTokenIssued is emitted when a new JWT has been signed and issued.
	EventJWTTokenIssued auth.EventName = "jwt.token.issued"

	// EventJWTTokenVerified is emitted when a token is successfully verified.
	EventJWTTokenVerified auth.EventName = "jwt.token.verified"

	// EventJWTTokenRevoked is emitted when a token or subject is explicitly revoked.
	EventJWTTokenRevoked auth.EventName = "jwt.token.revoked"

	// EventJWTKeyRotated is emitted when the active signing key is rotated.
	EventJWTKeyRotated auth.EventName = "jwt.key.rotated"
)
View Source
const (
	ModelJWTRevocations        = "jwt_revocations"
	ModelJWTSubjectRevocations = "jwt_subject_revocations"
)

Variables

View Source
var (
	// ErrInvalidToken is returned when a JWT is malformed, structurally invalid, or fails JSON parsing.
	ErrInvalidToken = errors.New("jwt: invalid or malformed token")

	// ErrTokenExpired is returned when a token's exp claim is in the past.
	ErrTokenExpired = errors.New("jwt: token has expired")

	// ErrTokenNotYetValid is returned when a token's nbf claim is in the future.
	ErrTokenNotYetValid = errors.New("jwt: token is not yet valid (nbf)")

	// ErrInvalidIssuer is returned when a token's iss claim does not match the expected issuer.
	ErrInvalidIssuer = errors.New("jwt: token issuer does not match expectation")

	// ErrInvalidAudience is returned when a token's aud claim does not include the expected audience.
	ErrInvalidAudience = errors.New("jwt: token audience does not match expectation")

	// ErrInvalidSubject is returned when a token's sub claim does not match the expected subject.
	ErrInvalidSubject = errors.New("jwt: token subject does not match expectation")

	// ErrAlgorithmMismatch is returned when a token header's alg differs from the key's declared algorithm,
	// preventing algorithm substitution attacks.
	ErrAlgorithmMismatch = errors.New("jwt: algorithm mismatch between token header and key specification")

	// ErrAlgorithmNotAllowed is returned when a token's algorithm is not among the configured allowed algorithms.
	ErrAlgorithmNotAllowed = errors.New("jwt: signing algorithm is not allowed")

	// ErrUnsignedTokenNotAllowed is returned when a token uses alg: 'none' or lacks a signature.
	ErrUnsignedTokenNotAllowed = errors.New("jwt: unsigned tokens (alg 'none') are strictly forbidden")

	// ErrInvalidSignature is returned when the cryptographic signature verification fails.
	ErrInvalidSignature = errors.New("jwt: cryptographic signature verification failed")

	// ErrKeyNotFound is returned when the key referenced by kid is not present in the KeyManager.
	ErrKeyNotFound = errors.New("jwt: signing key not found for specified kid")

	// ErrKeyIDRequired is returned when multiple keys are loaded but the token lacks a kid header.
	ErrKeyIDRequired = errors.New("jwt: kid header is required when multiple verification keys exist")

	// ErrInvalidKey is returned when the supplied cryptographic key is invalid, corrupt, or of wrong type.
	ErrInvalidKey = errors.New("jwt: invalid cryptographic key")

	// ErrNoActiveSigningKey is returned when issuing tokens without any active signing key configured.
	ErrNoActiveSigningKey = errors.New("jwt: no active signing key configured for token issuance")

	// ErrTokenRevoked is returned when the token has been explicitly invalidated in the revocation store.
	ErrTokenRevoked = errors.New("jwt: token has been revoked")

	// ErrMissingRequiredClaim is returned when a required claim is missing from the payload.
	ErrMissingRequiredClaim = errors.New("jwt: missing required claim")
)

Functions

func RegisterSchema added in v1.3.0

func RegisterSchema(s *schema.Schema) error

RegisterSchema registers the JWT revocation models into the compiled schema.

Types

type Algorithm

type Algorithm string

Algorithm identifies a registered JWA cryptographic signing algorithm.

const (
	// HMAC using SHA-256
	HS256 Algorithm = "HS256"
	// HMAC using SHA-384
	HS384 Algorithm = "HS384"
	// HMAC using SHA-512
	HS512 Algorithm = "HS512"

	// RSASSA-PKCS1-v1_5 using SHA-256
	RS256 Algorithm = "RS256"
	// RSASSA-PKCS1-v1_5 using SHA-384
	RS384 Algorithm = "RS384"
	// RSASSA-PKCS1-v1_5 using SHA-512
	RS512 Algorithm = "RS512"

	// RSASSA-PSS using SHA-256
	PS256 Algorithm = "PS256"
	// RSASSA-PSS using SHA-384
	PS384 Algorithm = "PS384"
	// RSASSA-PSS using SHA-512
	PS512 Algorithm = "PS512"

	// ECDSA using P-256 and SHA-256
	ES256 Algorithm = "ES256"
	// ECDSA using P-384 and SHA-384
	ES384 Algorithm = "ES384"
	// ECDSA using P-521 and SHA-512
	ES512 Algorithm = "ES512"

	// EdDSA using Ed25519
	EdDSA Algorithm = "EdDSA"
)

func (Algorithm) IsAsymmetric added in v1.3.0

func (a Algorithm) IsAsymmetric() bool

IsAsymmetric reports whether the algorithm is asymmetric (RSA, ECDSA, EdDSA).

func (Algorithm) IsSymmetric added in v1.3.0

func (a Algorithm) IsSymmetric() bool

IsSymmetric reports whether the algorithm is symmetric (HMAC).

func (Algorithm) IsValid added in v1.3.0

func (a Algorithm) IsValid() bool

IsValid reports whether the algorithm is one of the supported algorithms.

type Audience added in v1.3.0

type Audience []string

Audience represents the aud claim which can be a single string or an array of strings in RFC 7519.

func (Audience) Contains added in v1.3.0

func (a Audience) Contains(target string) bool

Contains reports whether the target audience is present in the Audience slice.

func (Audience) MarshalJSON added in v1.3.0

func (a Audience) MarshalJSON() ([]byte, error)

MarshalJSON serializes single audience as a JSON string, and multiple as an array.

func (*Audience) UnmarshalJSON added in v1.3.0

func (a *Audience) UnmarshalJSON(data []byte) error

UnmarshalJSON parses either a JSON string or an array of strings.

type Claims added in v1.3.0

type Claims struct {
	// Issuer (iss) identifies the principal that issued the JWT.
	Issuer string `json:"iss,omitempty"`

	// Subject (sub) identifies the principal that is the subject of the JWT.
	Subject string `json:"sub,omitempty"`

	// Audience (aud) identifies the recipients that the JWT is intended for.
	Audience Audience `json:"aud,omitempty"`

	// ExpiresAt (exp) identifies the expiration time on or after which the JWT MUST NOT be accepted.
	ExpiresAt *NumericDate `json:"exp,omitempty"`

	// NotBefore (nbf) identifies the time before which the JWT MUST NOT be accepted.
	NotBefore *NumericDate `json:"nbf,omitempty"`

	// IssuedAt (iat) identifies the time at which the JWT was issued.
	IssuedAt *NumericDate `json:"iat,omitempty"`

	// ID (jti) provides a unique identifier for the JWT.
	ID string `json:"jti,omitempty"`

	// Custom contains additional non-standard application claims.
	Custom map[string]any `json:"-"`
}

Claims represents the standard and custom claims of a JWT payload.

func (Claims) MarshalJSON added in v1.3.0

func (c Claims) MarshalJSON() ([]byte, error)

MarshalJSON serializes standard and custom claims into a single JSON object.

func (*Claims) UnmarshalJSON added in v1.3.0

func (c *Claims) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes standard claims and captures any remaining fields into Custom.

func (*Claims) Validate added in v1.3.0

func (c *Claims) Validate(now time.Time, cfg *verifyConfig) error

Validate verifies standard claim expectations including expiration, not-before, issuer, audience, and subject.

type Config

type Config struct {
	// Issuer defines the default issuer string applied to issued tokens.
	Issuer string

	// DefaultAudience specifies the default audience list applied when claims.Audience is empty.
	DefaultAudience []string

	// DefaultTTL specifies the default token validity duration when ExpiresAt is not explicitly provided.
	DefaultTTL time.Duration

	// AllowedAlgorithms is the strict whitelist of algorithms permitted for verification.
	AllowedAlgorithms []Algorithm

	// KeyManager manages cryptographic keys, key rotation, and kid resolution.
	KeyManager KeyManager

	// Cache accelerates revocation verification lookups.
	Cache jwtcache.RevocationCache

	// Leeway provides clock skew tolerance during expiration (exp) and not-before (nbf) validation.
	Leeway time.Duration

	// Hooks provides lifecycle extension points for issue, verify, and revoke operations.
	Hooks *Hooks
}

Config configures the JWT plugin module.

type Hooks added in v1.3.0

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

Hooks provides lifecycle extension points for JWT operations. Registered hooks execute synchronously and may mutate inputs or abort operations by returning an error.

func NewHooks added in v1.3.0

func NewHooks() *Hooks

NewHooks initializes an empty Hooks registry.

func (*Hooks) AfterIssue added in v1.3.0

func (h *Hooks) AfterIssue(fn func(ctx context.Context, tokenString string, claims *Claims) error)

AfterIssue registers an interceptor invoked after a token is signed.

func (*Hooks) AfterRevoke added in v1.3.0

func (h *Hooks) AfterRevoke(fn func(ctx context.Context, jti string) error)

AfterRevoke registers an interceptor invoked after a token is revoked.

func (*Hooks) AfterVerify added in v1.3.0

func (h *Hooks) AfterVerify(fn func(ctx context.Context, claims *Claims) error)

AfterVerify registers an interceptor invoked after a token is verified and validated.

func (*Hooks) BeforeIssue added in v1.3.0

func (h *Hooks) BeforeIssue(fn func(ctx context.Context, claims *Claims) error)

BeforeIssue registers an interceptor invoked before signing a token.

func (*Hooks) BeforeRevoke added in v1.3.0

func (h *Hooks) BeforeRevoke(fn func(ctx context.Context, jti string) error)

BeforeRevoke registers an interceptor invoked before revoking a token.

func (*Hooks) BeforeVerify added in v1.3.0

func (h *Hooks) BeforeVerify(fn func(ctx context.Context, tokenString string) error)

BeforeVerify registers an interceptor invoked before parsing and verifying a token.

type JWK

type JWK struct {
	// Kty is the key type: RSA, EC, or OKP.
	Kty string `json:"kty"`

	// Use is the intended public key use: "sig".
	Use string `json:"use,omitempty"`

	// Kid is the key identifier.
	Kid string `json:"kid,omitempty"`

	// Alg is the algorithm intended for use with the key.
	Alg string `json:"alg,omitempty"`

	// Crv is the cryptographic curve for EC or OKP keys (e.g., "P-256", "Ed25519").
	Crv string `json:"crv,omitempty"`

	// X is the x coordinate for EC keys, or public key for OKP keys (base64url-encoded).
	X string `json:"x,omitempty"`

	// Y is the y coordinate for EC keys (base64url-encoded).
	Y string `json:"y,omitempty"`

	// N is the RSA modulus (base64url-encoded).
	N string `json:"n,omitempty"`

	// E is the RSA public exponent (base64url-encoded).
	E string `json:"e,omitempty"`
}

JWK represents a single JSON Web Key per RFC 7517.

func KeyToJWK added in v1.3.0

func KeyToJWK(k Key) (JWK, error)

KeyToJWK converts an asymmetric Key into an RFC 7517 JWK.

type JWKS

type JWKS struct {
	Keys []JWK `json:"keys"`
}

JWKS represents a JSON Web Key Set per RFC 7517.

func BuildJWKS added in v1.3.0

func BuildJWKS(km KeyManager) (*JWKS, error)

BuildJWKS generates a JWKS from the given KeyManager, exporting only asymmetric public keys. Symmetric HMAC keys are strictly excluded to prevent secret disclosure.

func (*JWKS) JSON added in v1.3.0

func (j *JWKS) JSON() ([]byte, error)

JSON serializes the JWKS to formatted JSON bytes.

type JWT added in v1.3.0

type JWT interface {
	// Issue signs and issues a new JWT token using the active signing key.
	Issue(ctx context.Context, claims Claims) (string, error)

	// IssueWithKey signs and issues a new JWT token using a specific key identifier (kid).
	IssueWithKey(ctx context.Context, keyID string, claims Claims) (string, error)

	// Verify parses the token, validates the cryptographic signature, validates standard claims
	// (iss, aud, sub, exp, nbf), prevents algorithm confusion, and checks revocation if configured.
	Verify(ctx context.Context, tokenString string, opts ...VerifyOption) (*Claims, error)

	// Revoke invalidates a specific token identifier (jti) until its expiration time.
	Revoke(ctx context.Context, jti string, expiresAt time.Time, reason string) error

	// RevokeSubject invalidates all tokens issued to the given subject before the specified cutoff timestamp.
	RevokeSubject(ctx context.Context, subject string, cutoff time.Time, reason string) error

	// IsRevoked checks if a token or subject has been marked as revoked.
	IsRevoked(ctx context.Context, jti string, subject string, issuedAt time.Time) (bool, error)

	// JWKS exports the public keys formatted as an RFC 7517 JSON Web Key Set.
	JWKS(ctx context.Context) (*JWKS, error)

	// Keys returns the active KeyManager for key registration and rotation.
	Keys() KeyManager
}

JWT defines the capability contract exposed by the JWT plugin module. Applications access it via auth.Get[plugins.JWT](app).

type Key added in v1.3.0

type Key struct {
	// ID uniquely identifies the key (kid).
	ID string

	// Algorithm declares the single cryptographic algorithm permitted for this key (alg).
	Algorithm Algorithm

	// Use defines the intended use of the key (typically "sig").
	Use string

	// PrivateKey contains the private key material (*rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey, or []byte).
	// May be nil for verification-only keys.
	PrivateKey any

	// PublicKey contains the public key material (*rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey, or []byte for HMAC).
	PublicKey any

	// CreatedAt records when the key was created or added.
	CreatedAt time.Time
}

Key represents a cryptographic key for JWT signing or verification.

func NewECDSAKey added in v1.3.0

func NewECDSAKey(id string, alg Algorithm, privKey *ecdsa.PrivateKey) (Key, error)

NewECDSAKey constructs an asymmetric ECDSA signing key.

func NewECDSAPublicKey added in v1.3.0

func NewECDSAPublicKey(id string, alg Algorithm, pubKey *ecdsa.PublicKey) (Key, error)

NewECDSAPublicKey constructs an asymmetric ECDSA verification-only key.

func NewEd25519Key added in v1.3.0

func NewEd25519Key(id string, privKey ed25519.PrivateKey) (Key, error)

NewEd25519Key constructs an Ed25519 signing key.

func NewEd25519PublicKey added in v1.3.0

func NewEd25519PublicKey(id string, pubKey ed25519.PublicKey) (Key, error)

NewEd25519PublicKey constructs an Ed25519 verification-only key.

func NewHMACKey added in v1.3.0

func NewHMACKey(id string, alg Algorithm, secret []byte) (Key, error)

NewHMACKey constructs a symmetric key for HMAC algorithms.

func NewRSAKey added in v1.3.0

func NewRSAKey(id string, alg Algorithm, privKey *rsa.PrivateKey) (Key, error)

NewRSAKey constructs an asymmetric RSA signing key.

func NewRSAPublicKey added in v1.3.0

func NewRSAPublicKey(id string, alg Algorithm, pubKey *rsa.PublicKey) (Key, error)

NewRSAPublicKey constructs an asymmetric RSA verification-only key.

func (Key) CanSign added in v1.3.0

func (k Key) CanSign() bool

CanSign reports whether the key possesses private key material to sign tokens.

type KeyManager added in v1.3.0

type KeyManager interface {
	// AddKey registers a key.
	AddKey(key Key) error

	// SetActiveSigningKey designates the default key ID used for signing.
	SetActiveSigningKey(keyID string) error

	// RotateSigningKey registers a new signing key and immediately designates it as active.
	RotateSigningKey(newKey Key) error

	// GetKey retrieves a key by its ID.
	GetKey(keyID string) (Key, error)

	// GetActiveSigningKey returns the active signing key.
	GetActiveSigningKey() (Key, error)

	// GetVerificationKey retrieves the matching key and enforces algorithm compatibility.
	GetVerificationKey(kid string, requestedAlg Algorithm) (Key, error)

	// ListKeys returns all registered keys.
	ListKeys() []Key

	// RemoveKey removes a key by ID.
	RemoveKey(keyID string) error
}

KeyManager manages multiple keys, rotation, and active signing key designation.

func NewKeyManager added in v1.3.0

func NewKeyManager() KeyManager

NewKeyManager initializes an empty, thread-safe KeyManager.

type KeyRotatedPayload added in v1.3.0

type KeyRotatedPayload struct {
	PreviousKeyID string    `json:"previous_key_id,omitempty"`
	NewKeyID      string    `json:"new_key_id"`
	Algorithm     Algorithm `json:"algorithm"`
	Time          time.Time `json:"time"`
}

KeyRotatedPayload carries metadata when a key rotation occurs.

type Module added in v1.3.0

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

Module implements auth.PluginModule for GoModularAuth JWT stateless tokens using plugin-sdk.

func New

func New(opts ...Option) *Module

New constructs a new JWT plugin module.

func (*Module) ID added in v1.3.0

func (m *Module) ID() string

ID returns the module's unique identifier within GoModularAuth.

func (*Module) Init added in v1.3.0

func (m *Module) Init(h *auth.Host) error

Init initializes the plugin module on the host and registers its capability.

func (*Module) RegisterSchema added in v1.3.0

func (m *Module) RegisterSchema(s *schema.Schema) error

RegisterSchema registers the database models for JWT revocations.

type NumericDate added in v1.3.0

type NumericDate struct {
	time.Time
}

NumericDate represents a JSON numeric date (seconds since Unix epoch) per RFC 7519 section 2.

func NewNumericDate added in v1.3.0

func NewNumericDate(t time.Time) *NumericDate

NewNumericDate creates a new NumericDate from a time.Time value, truncated to seconds.

func (*NumericDate) MarshalJSON added in v1.3.0

func (n *NumericDate) MarshalJSON() ([]byte, error)

MarshalJSON marshals the timestamp as a Unix integer.

func (*NumericDate) UnmarshalJSON added in v1.3.0

func (n *NumericDate) UnmarshalJSON(data []byte) error

UnmarshalJSON unmarshals a JSON number into a NumericDate.

type Option

type Option func(*Config)

Option modifies a Config instance.

func WithAllowedAlgorithms added in v1.3.0

func WithAllowedAlgorithms(algs ...Algorithm) Option

WithAllowedAlgorithms configures the strict whitelist of algorithms permitted.

func WithDefaultAudience added in v1.3.0

func WithDefaultAudience(aud ...string) Option

WithDefaultAudience sets the default audience list.

func WithDefaultLeeway added in v1.3.0

func WithDefaultLeeway(leeway time.Duration) Option

WithDefaultLeeway sets the default clock skew leeway duration for token verification.

func WithDefaultTTL added in v1.3.0

func WithDefaultTTL(ttl time.Duration) Option

WithDefaultTTL configures the fallback token validity duration.

func WithHooks added in v1.3.0

func WithHooks(hooks *Hooks) Option

WithHooks sets the lifecycle hooks registry.

func WithIssuer

func WithIssuer(issuer string) Option

WithIssuer configures the default issuer claim.

func WithKey added in v1.3.0

func WithKey(key Key) Option

WithKey registers a single cryptographic key.

func WithKeyManager added in v1.3.0

func WithKeyManager(km KeyManager) Option

WithKeyManager sets the KeyManager.

func WithRevocationCache added in v1.3.0

func WithRevocationCache(cache jwtcache.RevocationCache) Option

WithRevocationCache sets the revocation cache.

type RevocationRecord added in v1.3.0

type RevocationRecord struct {
	JTI       string    `json:"jti"`
	Subject   string    `json:"subject,omitempty"`
	Reason    string    `json:"reason,omitempty"`
	ExpiresAt time.Time `json:"expires_at"`
	RevokedAt time.Time `json:"revoked_at"`
}

RevocationRecord represents an explicit token revocation by unique ID (jti).

type SubjectRevocationRecord added in v1.3.0

type SubjectRevocationRecord struct {
	Subject   string    `json:"subject"`
	Cutoff    time.Time `json:"cutoff"`
	Reason    string    `json:"reason,omitempty"`
	RevokedAt time.Time `json:"revoked_at"`
}

SubjectRevocationRecord represents a blanket revocation for all tokens of a subject issued before Cutoff.

type TokenIssuedPayload added in v1.3.0

type TokenIssuedPayload struct {
	KeyID     string    `json:"key_id"`
	JTI       string    `json:"jti,omitempty"`
	Subject   string    `json:"subject,omitempty"`
	Issuer    string    `json:"issuer,omitempty"`
	Audience  []string  `json:"audience,omitempty"`
	ExpiresAt time.Time `json:"expires_at,omitempty"`
	IssuedAt  time.Time `json:"issued_at,omitempty"`
}

TokenIssuedPayload carries diagnostic metadata about an issued token. Cryptographic keys, signatures, and sensitive claims are strictly omitted.

type TokenRevokedPayload added in v1.3.0

type TokenRevokedPayload struct {
	JTI       string    `json:"jti,omitempty"`
	Subject   string    `json:"subject,omitempty"`
	Reason    string    `json:"reason,omitempty"`
	RevokedAt time.Time `json:"revoked_at"`
}

TokenRevokedPayload carries metadata about a revocation event.

type TokenVerifiedPayload added in v1.3.0

type TokenVerifiedPayload struct {
	KeyID   string    `json:"key_id"`
	JTI     string    `json:"jti,omitempty"`
	Subject string    `json:"subject,omitempty"`
	Issuer  string    `json:"issuer,omitempty"`
	Time    time.Time `json:"time"`
}

TokenVerifiedPayload carries diagnostic metadata about a verified token.

type VerifyOption added in v1.3.0

type VerifyOption func(*verifyConfig)

VerifyOption configures claim validation parameters for Verify.

func WithExpectedAudience added in v1.3.0

func WithExpectedAudience(expected string) VerifyOption

WithExpectedAudience asserts that the token's aud claim contains expected.

func WithExpectedIssuer added in v1.3.0

func WithExpectedIssuer(expected string) VerifyOption

WithExpectedIssuer asserts that the token's iss claim matches expected.

func WithExpectedSubject added in v1.3.0

func WithExpectedSubject(expected string) VerifyOption

WithExpectedSubject asserts that the token's sub claim matches expected.

func WithLeeway added in v1.3.0

func WithLeeway(leeway time.Duration) VerifyOption

WithLeeway allows clock skew tolerance when validating exp and nbf timestamps.

func WithRequiredClaims added in v1.3.0

func WithRequiredClaims(claims ...string) VerifyOption

WithRequiredClaims asserts that all specified claims are present in the token payload.

Directories

Path Synopsis
Package plugins exposes capability aliases for GoModularAuth plugins.
Package plugins exposes capability aliases for GoModularAuth plugins.

Jump to

Keyboard shortcuts

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