Documentation
¶
Overview ¶
Package jwt provides tools for parsing, verifying, and signing JSON Web Tokens (JWTs).
This package uses generics to allow users to define their own custom claims structures. A common pattern is to embed the provided Reserved claims struct and add extra fields for any other claims present in the token.
Basic Verification ¶
Start by defining custom claims:
type Claims struct {
jwt.Reserved
Scope string `json:"scp"`
Extra map[string]any `json:",unknown"`
}
The top-level Verify function can be used for simple, one-off signature verification without claim validation:
keySet, err := jwk.ParseSet(`{"keys": [...]}`)
if err != nil { /* handle parsing error */ }
claims, err := jwt.Verify[Claims](keySet, []byte("eyJhb..."))
Advanced Validation ¶
For advanced validation of claims like issuer, audience, and token age, create a reusable Verifier with the desired configuration:
verifier := jwt.NewVerifier[Claims](keySet).
WithIssuer("foo", "bar").
WithAudience("baz").
WithLeeway(1 * time.Minute).
WithMaxAge(1 * time.Hour)
claims, err := verifier.Verify([]byte("eyJhb..."))
if err != nil { /* handle validation error */ }
fmt.Println("Scope:", claims.Scope)
Basic Signing ¶
The top-level Sign function can be used to create signed tokens from any JSON-serializable struct or map. This is useful for simple tokens where you manually handle all claims:
// keyPair must be a jwk.KeyPair (containing a private key)
claims := map[string]any{"sub": "user_123", "admin": true}
token, err := jwt.Sign(keyPair, claims)
Advanced Signing ¶
To enforce policies like expiration or consistent issuers, create a reusable Signer. Your claims struct must implement MutableClaims (embedding jwt.Reserved handles this automatically).
signer := jwt.NewSigner(keyPair).
WithIssuer("https://api.example.com").
WithLifetime(1 * time.Hour)
// The signer will automatically set "iss", "iat", and "exp" on the struct.
claims := &MyClaims{
Reserved: jwt.Reserved{Subject: "user_123"},
Scope: "admin",
}
token, err := signer.Sign(claims)
Index ¶
- Variables
- func Sign(k jwk.KeyPair, claims any) ([]byte, error)
- func Verify[T Claims](set jwk.Set, in []byte) (T, error)
- type Claims
- type Header
- type MutableClaims
- type Reserved
- func (r *Reserved) Audience() []string
- func (r *Reserved) ExpiresAt() time.Time
- func (r *Reserved) ID() string
- func (r *Reserved) IssuedAt() time.Time
- func (r *Reserved) Issuer() string
- func (r *Reserved) NotBefore() time.Time
- func (r *Reserved) SetAudience(aud []string)
- func (r *Reserved) SetExpiresAt(t time.Time)
- func (r *Reserved) SetID(id string)
- func (r *Reserved) SetIssuedAt(t time.Time)
- func (r *Reserved) SetIssuer(iss string)
- func (r *Reserved) SetNotBefore(t time.Time)
- func (r *Reserved) SetSubject(sub string)
- func (r *Reserved) Subject() string
- type Signer
- func (s *Signer) Sign(claims MutableClaims) ([]byte, error)
- func (s *Signer) WithAudience(aud ...string) *Signer
- func (s *Signer) WithClock(now func() time.Time) *Signer
- func (s *Signer) WithIssuedAt(use bool) *Signer
- func (s *Signer) WithIssuer(iss string) *Signer
- func (s *Signer) WithLifetime(d time.Duration) *Signer
- type Token
- type Verifier
- func (v *Verifier[T]) Verify(in []byte) (T, error)
- func (v *Verifier[T]) WithAudiences(aud ...string) *Verifier[T]
- func (v *Verifier[T]) WithClock(now func() time.Time) *Verifier[T]
- func (v *Verifier[T]) WithIssuers(iss ...string) *Verifier[T]
- func (v *Verifier[T]) WithLeeway(d time.Duration) *Verifier[T]
- func (v *Verifier[T]) WithMaxAge(d time.Duration) *Verifier[T]
Constants ¶
This section is empty.
Variables ¶
var ( // ErrKeyNotFound is returned when no matching key is found in the JWK set. ErrKeyNotFound = errors.New("no matching key found") // ErrInvalidSignature is returned when the token's signature differs from // the computed signature. ErrInvalidSignature = errors.New("invalid signature") )
var ( // ErrInvalidIssuer signals that the "iss" claim did not match any of the // expected issuers. ErrInvalidIssuer = errors.New("invalid issuer") // ErrInvalidAudience signals that the "aud" claim did not match any of the // expected audiences. ErrInvalidAudience = errors.New("invalid audience") // ErrTokenExpired signals that the "exp" claim is in the past. ErrTokenExpired = errors.New("token is expired") // ErrTokenNotYetActive signals that the "nbf" claim is in the future. ErrTokenNotYetActive = errors.New("token not yet active") // ErrTokenTooOld signals that the "iat" claim is further in the past than // the configured maximum age. ErrTokenTooOld = errors.New("token is too old") )
Functions ¶
func Sign ¶
Sign creates a new signed JWT using the provided KeyPair and claims.
It marshals the claims using encoding/json/v2, creates a header based on the key's properties, and signs the payload. The claims argument can be any type that serializes to a JSON object.
func Verify ¶
Verify first parses a JWT and then verifies its signature against a given key set. The type parameter T specifies the target struct for the token's claims.
This function only checks the cryptographic signature, not the content of the claims. For claim validation (e.g., issuer, audience, expiration), create and configure a Verifier. It is a shorthand for Parse followed by calling Verify on the resulting Token.
Types ¶
type Claims ¶
type Claims interface {
// ID returns the "jti" (JWT ID) claim, or an empty string if absent.
ID() string
// Subject returns the "sub" (Subject) claim, or an empty string if absent.
Subject() string
// Issuer returns the "iss" (Issuer) claim, or an empty string if absent.
Issuer() string
// Audience returns the "aud" (Audience) claim, or nil if absent.
Audience() []string
// IssuedAt returns the "iat" (Issued At) claim, or the zero time if absent.
IssuedAt() time.Time
// ExpiresAt returns the "exp" (Expires At) claim, or the zero time if absent.
ExpiresAt() time.Time
// NotBefore returns the "nbf" (Not Before) claim, or the zero time if absent.
NotBefore() time.Time
}
Claims provides access to the standard JWT claims. It is used by Verifier for claim validation.
type MutableClaims ¶
type MutableClaims interface {
Claims
// SetID sets the "jti" (JWT ID) claim.
SetID(id string)
// SetSubject sets the "sub" (Subject) claim.
SetSubject(sub string)
// SetIssuer sets the "iss" (Issuer) claim.
SetIssuer(iss string)
// SetAudience sets the "aud" (Audience) claim.
SetAudience(aud []string)
// SetIssuedAt sets the "iat" (Issued At) claim.
SetIssuedAt(t time.Time)
// SetExpiresAt sets the "exp" (Expires At) claim.
SetExpiresAt(t time.Time)
// SetNotBefore sets the "nbf" (Not Before) claim.
SetNotBefore(t time.Time)
}
MutableClaims extends Claims with setters for standard JWT claims.
The setter methods are not safe for concurrent use and should only be called during token creation.
type Reserved ¶
type Reserved struct {
Jti string `json:"jti,omitempty"` // JWT ID
Sub string `json:"sub,omitempty"` // Subject
Iss string `json:"iss,omitempty"` // Issuer
Aud audience `json:"aud,omitempty"` // Audience
Iat time.Time `json:"iat,omitzero,format:unix"` // Issued At
Exp time.Time `json:"exp,omitzero,format:unix"` // Expires At
Nbf time.Time `json:"nbf,omitzero,format:unix"` // Not Before
}
Reserved contains the standard registered claims for a JWT. It implements the Claims interface and should be embedded in custom claims structs to enable standard claim handling.
func (*Reserved) SetAudience ¶
func (*Reserved) SetExpiresAt ¶
func (*Reserved) SetIssuedAt ¶
func (*Reserved) SetNotBefore ¶
func (*Reserved) SetSubject ¶
type Signer ¶
type Signer struct {
// contains filtered or unexported fields
}
Signer is a configured, reusable JWT creator. It allows setting default claims (like Issuer and Audience) and enforcing token lifetime (Expiration).
func NewSigner ¶
NewSigner creates a new Signer that uses the provided key pool for signing. At least one key pair must be provided; otherwise, it panics. If multiple keys are given, they will be rotated through in a round-robin fashion to ensure even usage across the key pool. Further configuration can be applied using the With... setters.
func (*Signer) Sign ¶
func (s *Signer) Sign(claims MutableClaims) ([]byte, error)
Sign applies the signer's configuration (issuer, audience, and temporal validity) directly to the mutable claims object, then signs it.
func (*Signer) WithAudience ¶
WithAudience sets the "aud" (Audience) claim. If the user-provided claims already contain an audience, this configuration will overwrite it.
This method is not thread-safe and should be called only during setup.
func (*Signer) WithClock ��
WithClock sets the function used to retrieve the current time when timestamping tokens ("iat", "nbf", "exp"). This is useful for deterministic testing. The default is time.Now.
This method is not thread-safe and should be called only during setup.
func (*Signer) WithIssuedAt ¶
WithIssuedAt enables or disables automatic setting of the "iat" (Issued At) claim for all tokens created by this signer. It is enabled by default and will be stamped with the current time.
This method is not thread-safe and should be called only during setup.
func (*Signer) WithIssuer ¶
WithIssuer sets the "iss" (Issuer) claim for all tokens created by this signer. If the user-provided claims already contain an issuer, this configuration will overwrite it.
This method is not thread-safe and should be called only during setup.
func (*Signer) WithLifetime ¶
WithLifetime sets the duration for which tokens are valid. It calculates the "exp" (Expires At) claim by adding this duration to the current time. If zero (default), no "exp" claim is added unless provided in the input claims.
This method is not thread-safe and should be called only during setup.
type Token ¶
type Token[T Claims] interface { // Header returns the token's header parameters. Header() Header // Claims returns the token's payload claims. Claims() T // Verify checks the token's signature using the provided JWK set. // It returns ErrKeyNotFound if no matching key is found or // ErrInvalidSignature if the signature is incorrect. Verify(set jwk.Set) error }
Token represents a parsed, but not necessarily verified, JWT. The generic type T is the user-defined claims structure.
func Parse ¶
Parse decodes a JWT from its compact serialization format into a Token without verifying the signature. The type parameter T specifies the target struct for the token's claims. If the token is malformed or the payload does not unmarshal into T (using encoding/json/v2), an error is returned.
type Verifier ¶
type Verifier[T Claims] struct { // contains filtered or unexported fields }
Verifier is a configured, reusable JWT verifier. The type parameter T is the user-defined struct for the token's claims. It must implement the Claims interface, or else verification will always fail.
func NewVerifier ¶
NewVerifier creates a new verifier bound to a specific JWK set. The type parameter T is the user-defined struct for the token's claims. Further configuration can be applied using the With... setters.
func (*Verifier[T]) Verify ¶
Verify parses a token from its compact serialization, verifies its signature against the verifier's key set, and validates its claims according to the verifier's configuration.
func (*Verifier[T]) WithAudiences ¶
WithAudiences adds one or more trusted audiences to the verifier. If the token's "aud" claim is missing or does not contain at least one of these values, it will be rejected. This option can be used multiple times to append additional values. By default, no audience validation is performed.
This method is not thread-safe and should be called only during setup.
func (*Verifier[T]) WithClock ¶
WithClock sets the function used to retrieve the current time during validation. This is useful for deterministic testing or synchronizing with an external time source. The default is time.Now.
This method is not thread-safe and should be called only during setup.
func (*Verifier[T]) WithIssuers ¶
WithIssuers adds one or more trusted issuers to the verifier. If a token's "iss" claim is missing or does not match one of these, it will be rejected. This option can be used multiple times to append additional values. By default, no issuer validation is performed.
This method is not thread-safe and should be called only during setup.
func (*Verifier[T]) WithLeeway ¶
WithLeeway sets a grace period to allow for clock skew in temporal validations of the "exp", "nbf", and "iat" claims. It is subtracted from or added to the current time as appropriate. The default is zero, meaning no leeway. Negative values will be ignored.
This method is not thread-safe and should be called only during setup.
func (*Verifier[T]) WithMaxAge ¶
WithMaxAge sets the maximum age for tokens based on their "iat" claim. Tokens without an "iat" claim will no longer be accepted. The default is zero, meaning no age validation. Negative values will be ignored.
This method is not thread-safe and should be called only during setup.