jwt

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: GPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package jwt provides RS256 signing, JWKS publication, and 30-day key rotation for authlet's authorization server. Private keys are stored encrypted via pkg/crypto.

Index

Constants

View Source
const OverlapWindow = 24 * time.Hour

OverlapWindow is how long a retired key remains queryable for signature verification after rotation, to allow in-flight tokens to validate.

View Source
const RSAKeyBits = 2048

RSAKeyBits is the modulus size used for newly generated signing keys.

View Source
const RotationInterval = 30 * 24 * time.Hour

RotationInterval is how long an active signing key is used before the Manager rotates in a fresh one.

Variables

View Source
var (
	// ErrPEMDecode is returned when input bytes contain no decodable PEM block.
	ErrPEMDecode = errors.New("jwt: pem decode failed")
	// ErrPEMType is returned when the PEM block type is not the one expected
	// (e.g. parsing a public key from a "PRIVATE KEY" block).
	ErrPEMType = errors.New("jwt: unexpected pem block type")
)

Sentinel errors for PEM parsing.

View Source
var (
	// ErrUnknownKID is returned when the resolver cannot find a key for the
	// kid present in the token header.
	ErrUnknownKID = errors.New("jwt: unknown kid")
	// ErrInvalidIssuer is returned when the token's iss claim does not match
	// VerifyOptions.ExpectedIssuer.
	ErrInvalidIssuer = errors.New("jwt: invalid issuer")
	// ErrInvalidAud is returned when the token's aud claim does not match
	// VerifyOptions.ExpectedAudience.
	ErrInvalidAud = errors.New("jwt: invalid audience")
	// ErrExpired is returned when the token's exp claim is at or before
	// VerifyOptions.Now.
	ErrExpired = errors.New("jwt: expired")
	// ErrNotYetValid is returned when the token's nbf claim is in the
	// future relative to VerifyOptions.Now.
	ErrNotYetValid = errors.New("jwt: not yet valid")
)

Sentinel errors returned by Verify.

View Source
var ErrNoActiveKey = errors.New("jwt: no active signing key")

ErrNoActiveKey is returned by Signer when storage has no active key.

Functions

func GenerateRSA

func GenerateRSA() (*rsa.PrivateKey, error)

GenerateRSA creates a new RSA-2048 key pair suitable for RS256 signing.

func MarshalPrivatePEM

func MarshalPrivatePEM(k *rsa.PrivateKey) ([]byte, error)

MarshalPrivatePEM returns PKCS#8 PEM bytes for the given RSA private key.

func MarshalPublicPEM

func MarshalPublicPEM(k *rsa.PublicKey) ([]byte, error)

MarshalPublicPEM returns PKIX PEM bytes for the given RSA public key.

func ParsePrivatePEM

func ParsePrivatePEM(p []byte) (*rsa.PrivateKey, error)

ParsePrivatePEM parses PKCS#8 PEM bytes into an RSA private key.

func ParsePublicPEM

func ParsePublicPEM(p []byte) (*rsa.PublicKey, error)

ParsePublicPEM parses PKIX PEM bytes into an RSA public key.

func Sign

func Sign(c Claims, kid string, priv *rsa.PrivateKey) (string, error)

Sign returns a signed RS256 JWT carrying the given claims and kid header.

Types

type Claims

type Claims struct {
	Issuer    string         `json:"iss"`
	Subject   string         `json:"sub"`
	Audience  string         `json:"aud"`
	ClientID  string         `json:"client_id"`
	Scope     string         `json:"scope"`
	IssuedAt  int64          `json:"iat"`
	ExpiresAt int64          `json:"exp"`
	NotBefore int64          `json:"nbf,omitempty"`
	JTI       string         `json:"jti"`
	Extra     map[string]any `json:"-"`
}

Claims is the set of JWT claims authlet's AS mints. Apps may inject additional custom claims via Extra; reserved standard claim names cannot be overridden through Extra.

func Verify

func Verify(tokenString string, resolve PublicKeyFunc, opts VerifyOptions) (Claims, error)

Verify parses tokenString, checks the RS256 signature against the kid-resolved public key, and validates the iss, aud and exp claims.

type JWK

type JWK struct {
	Kty string `json:"kty"`
	Use string `json:"use"`
	Alg string `json:"alg"`
	Kid string `json:"kid"`
	N   string `json:"n"`
	E   string `json:"e"`
}

JWK is a JSON Web Key entry as published at the jwks_uri endpoint. Only RSA verification keys are emitted by authlet.

type JWKS

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

JWKS is the JSON Web Key Set wrapper served at jwks_uri.

func PublishJWKS

func PublishJWKS(keys map[string]*rsa.PublicKey) JWKS

PublishJWKS builds a JWKS from a kid -> public key map. Each entry is tagged kty=RSA, use=sig, alg=RS256.

type Manager

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

Manager owns the active RSA signing key, the rotation policy, and a kid->public key cache for verification. It wraps storage.SigningKeyStore and decrypts/encrypts private keys via pkg/crypto.

func NewManager

func NewManager(store storage.SigningKeyStore, masterKey []byte) *Manager

NewManager wires a Manager around a SigningKeyStore and the 32-byte master key used to encrypt private key material at rest.

The masterKey slice is copied; the caller may zero its copy after construction without affecting the Manager. This prevents accidental secret corruption if the caller reuses the buffer for a different purpose.

func (*Manager) Bootstrap

func (m *Manager) Bootstrap(ctx context.Context) error

Bootstrap ensures at least one active signing key exists. Idempotent: returns nil if storage already has an active signer.

func (*Manager) PublicKeyFunc

func (m *Manager) PublicKeyFunc(ctx context.Context) PublicKeyFunc

PublicKeyFunc returns a resolver suitable for Verify(). The resolver honours the Manager's clock so retired keys past the overlap window are not returned, even if the underlying store has not yet pruned them.

func (*Manager) PublishJWKS

func (m *Manager) PublishJWKS(ctx context.Context) (JWKS, error)

PublishJWKS returns a JWKS of every key currently considered active by the Manager, i.e. unretired or still within the overlap window.

func (*Manager) RotateIfDue

func (m *Manager) RotateIfDue(ctx context.Context) error

RotateIfDue creates a new active key if the current signer is older than RotationInterval, scheduling the old key to retire after OverlapWindow. No-op when the active signer is younger than RotationInterval.

func (*Manager) SetNow

func (m *Manager) SetNow(f func() time.Time)

SetNow swaps the Manager's clock. Intended for tests. Safe for use from any goroutine; locks the manager's internal mutex.

func (*Manager) Signer

func (m *Manager) Signer(ctx context.Context) (*rsa.PrivateKey, string, error)

Signer returns the active private key with its kid, decrypting from storage on first call and caching the result.

type PublicKeyFunc

type PublicKeyFunc func(kid string) (*rsa.PublicKey, error)

PublicKeyFunc resolves a kid header value to the public key that signed it.

type VerifyOptions

type VerifyOptions struct {
	ExpectedIssuer   string
	ExpectedAudience string
	Now              func() time.Time
}

VerifyOptions narrows what Verify will accept. Zero values disable the corresponding check; Now defaults to time.Now.

Jump to

Keyboard shortcuts

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