jwtkit

package
v0.86.1 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AccessTokenType          = "access+jwt"
	DelegatedAccessTokenType = "delegated-access+jwt"
	// RemoteApplicationAccessTokenType is the JOSE `typ` for a remote application
	// access token. It carries neither sub nor delegated_sub; identity is the
	// validated iss -> remote_application mapping.
	RemoteApplicationAccessTokenType = "remote-application-access+jwt"
)

AuthKit JOSE `typ` header values. These separate AuthKit JWT classes before claims are mapped into principals.

View Source
const (
	// DefaultAuthKeysPath is the default directory where External Secrets mounts auth keys
	DefaultAuthKeysPath = "/vault/auth"

	// DefaultKeyReloadInterval is how often a FileKeySource re-stats
	// keys.json for changes. Short keeps the post-rotation multi-replica skew
	// window small; the cost is one stat() per tick. See authkit #90.
	DefaultKeyReloadInterval = 10 * time.Second
)

Variables

View Source
var ErrPayloadSignerRequired = errors.New("payload signer required")

ErrPayloadSignerRequired means a Signer can issue JWT claims but cannot sign an exact caller-supplied JWS payload.

View Source
var ErrUnsupportedJWK = errors.New("unsupported_jwk")

Functions

func AlgorithmForPublicKey

func AlgorithmForPublicKey(pub crypto.PublicKey) string

AlgorithmForPublicKey returns a default JWS alg for a public key when none is specified.

func BaseRegisteredClaims

func BaseRegisteredClaims(subject string, audiences []string, ttl time.Duration) jwt.RegisteredClaims

Helper to make base registered claims.

func JWKSToPublicKeys

func JWKSToPublicKeys(ks JWKS) (map[string]crypto.PublicKey, error)

JWKSToPublicKeys parses all supported keys in a JWKS document.

func JWKToPublicKey

func JWKToPublicKey(j JWK) (crypto.PublicKey, error)

JWKToPublicKey parses a single JWK into a crypto.PublicKey.

func ParsePublicKeyFromPEM

func ParsePublicKeyFromPEM(pemText string) (crypto.PublicKey, error)

ParsePublicKeyFromPEM parses a PKIX/SPKI, certificate, or PKCS#1 RSA public key PEM.

func ParsePublicKeyFromPEMBytes

func ParsePublicKeyFromPEMBytes(pemBytes []byte) (crypto.PublicKey, error)

ParsePublicKeyFromPEMBytes parses a supported public key PEM block.

func ServeJWKS

func ServeJWKS(w http.ResponseWriter, r *http.Request, ks JWKS)

ServeJWKS writes JWKS JSON to the ResponseWriter.

func SetLogger

func SetLogger(l Logger)

SetLogger installs the package-level logger used for key-load warnings. Pass nil to restore the default no-op logger.

func SignPayloadWithType added in v0.86.0

func SignPayloadWithType(ctx context.Context, signer Signer, payload []byte, typ string) (string, error)

SignPayloadWithType signs payload exactly as supplied and stamps typ. It is used for signed documents, whose digest covers the same bytes carried by the compact JWS payload.

func SignWithType

func SignWithType(ctx context.Context, signer Signer, claims jwt.MapClaims, typ string, requireHeader bool) (string, error)

SignWithType signs claims, optionally stamping the JOSE `typ` header. It is the single home for the "assert HeaderSigner and set typ, or fall back" idiom that AuthKit's token-minting paths share:

  • typ == "": plain Sign (no typ header).
  • typ != "" && requireHeader: assert HeaderSigner; error if the signer can't stamp headers.
  • typ != "" && !requireHeader: stamp via HeaderSigner when available, else fall back to a plain Sign.

Types

type Ed25519Signer

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

Ed25519Signer signs JWTs with EdDSA (Ed25519).

func NewEd25519Signer

func NewEd25519Signer(kid string) (*Ed25519Signer, error)

NewEd25519Signer generates a new Ed25519 key pair for development/testing.

func (*Ed25519Signer) Algorithm

func (s *Ed25519Signer) Algorithm() string

func (*Ed25519Signer) KID

func (s *Ed25519Signer) KID() string

func (*Ed25519Signer) PublicKey

func (s *Ed25519Signer) PublicKey() crypto.PublicKey

func (*Ed25519Signer) Sign

func (s *Ed25519Signer) Sign(_ context.Context, claims jwt.MapClaims) (string, error)

func (*Ed25519Signer) SignPayload added in v0.86.0

func (s *Ed25519Signer) SignPayload(_ context.Context, payload []byte, headers map[string]any) (string, error)

func (*Ed25519Signer) SignWithHeaders

func (s *Ed25519Signer) SignWithHeaders(_ context.Context, claims jwt.MapClaims, headers map[string]any) (string, error)

type FileKeySource added in v0.79.0

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

FileKeySource wraps a file-backed StaticKeySource and hot-reloads it when keys.json changes on disk (e.g. re-rendered by Vault Agent), so signing- key rotation never requires a process restart. It implements KeySource; reads are lock-free via an atomic pointer. A background poller re-stats keys.json at the configured interval and, on change, atomically swaps in a NEW validated keystore. A malformed/unreadable file keeps the last-good keystore — a bad render never bricks signing. See authkit #90 (AK-IMPL-3).

func NewFileKeySource added in v0.79.0

func NewFileKeySource(path string, interval time.Duration) (*FileKeySource, error)

NewFileKeySource loads keys.json from the given directory and starts a background poller that hot-reloads it every interval (<=0 → DefaultKeyReloadInterval). It errors when no valid keys.json is present, so use it only where a file source is expected — static/dev sources don't reload (in-memory material is immutable in a running process; generated keys are dev-only).

ResolveKeySource calls this with DefaultKeyReloadInterval; call it directly instead of ResolveKeySource when you need a non-default interval — e.g. a short interval in a test asserting rotation is observed within a bound, or a host that wants to trade the default's stat() cost for faster/slower pickup. The caller owns the returned source's lifecycle (Close stops its poller goroutine).

func (*FileKeySource) ActiveSigner added in v0.79.0

func (r *FileKeySource) ActiveSigner() Signer

func (*FileKeySource) Close added in v0.79.0

func (r *FileKeySource) Close()

Close stops the background poller. Safe to call multiple times; optional for process-lifetime sources (primarily for tests and clean shutdown).

func (*FileKeySource) PublicKeys added in v0.79.0

func (r *FileKeySource) PublicKeys() map[string]crypto.PublicKey

func (*FileKeySource) Reload added in v0.79.0

func (r *FileKeySource) Reload() error

Reload re-reads keys.json, validates it, and atomically swaps it in. On any read/parse/validation failure it KEEPS the current keystore and returns the error — it never serves a partial or empty key set.

type HeaderSigner

type HeaderSigner interface {
	Signer
	// SignWithHeaders signs claims and merges the provided extra JOSE header
	// params into the token header (kid is still set by the signer).
	SignWithHeaders(ctx context.Context, claims jwt.MapClaims, headers map[string]any) (token string, err error)
}

HeaderSigner is an extension of Signer that lets callers set extra JOSE header parameters (e.g. `typ`) on the signed token. AuthKit token minting uses it to stamp the token profile header.

type JWK

type JWK struct {
	Kty string `json:"kty"`
	Use string `json:"use,omitempty"`
	Kid string `json:"kid,omitempty"`
	Alg string `json:"alg,omitempty"`
	// RSA
	N string `json:"n,omitempty"`
	E string `json:"e,omitempty"`
	// EC / OKP
	Crv string `json:"crv,omitempty"`
	X   string `json:"x,omitempty"`
	Y   string `json:"y,omitempty"`
}

JWK represents a JSON Web Key (RSA, EC, or OKP).

func PublicToJWK

func PublicToJWK(pub crypto.PublicKey, kid, alg string) JWK

PublicToJWK converts a supported public key to a JWK.

type JWKS

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

type KeySource

type KeySource interface {
	ActiveSigner() Signer
	PublicKeys() map[string]crypto.PublicKey
}

KeySource provides the active signer and public keys for JWKS.

func ResolveKeySource

func ResolveKeySource(path string, allowEphemeralDevKeys bool) (KeySource, error)

ResolveKeySource resolves the local signing-key source with a fixed, explicit precedence. It reads NO environment variables (#231 — AuthKit is a library; env is read once, at the binary boundary, and flows in as explicit arguments/config):

  1. <path>/keys.json (path empty ⇒ DefaultAuthKeysPath "/vault/auth"), served through a FileKeySource so signing-key rotation (e.g. Vault Agent re-rendering the file) takes effect without a process restart.
  2. No keys.json: when allowEphemeralDevKeys is true, an auto-generated RSA dev keypair persisted under .runtime/authkit/ (DEVELOPMENT ONLY); when false — the default, fail-closed posture — a hard error.

Callers that hold key material in memory should build a source directly (NewStaticKeySourceFromPEM / StaticKeySource) instead.

type Logger

type Logger func(format string, args ...any)

Logger receives non-fatal key-loading warnings from jwtkit. The default is a no-op logger so libraries do not write to stdout.

type PayloadSigner added in v0.86.0

type PayloadSigner interface {
	Signer
	SignPayload(ctx context.Context, payload []byte, headers map[string]any) (token string, err error)
}

PayloadSigner is the optional Signer extension for compact JWS payloads that must be signed byte-for-byte. Unlike Sign, it does not marshal a MapClaims. AuthKit's built-in RSA, ECDSA, and Ed25519 signers implement it.

type PublicKeySigner

type PublicKeySigner interface {
	Signer
	PublicKey() crypto.PublicKey
}

PublicKeySigner is implemented by in-memory signers that expose their public key.

type RSASigner

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

Minimal in-memory RSA signer for bootstrap/dev. Production should load from KMS or DB.

func NewRSASigner

func NewRSASigner(bits int, kid string) (*RSASigner, error)

func NewRSASignerFromPEM

func NewRSASignerFromPEM(kid string, pemBytes []byte) (*RSASigner, error)

NewRSASignerFromPEM constructs an RSASigner from a PEM-encoded RSA private key.

func (*RSASigner) Algorithm

func (s *RSASigner) Algorithm() string

func (*RSASigner) KID

func (s *RSASigner) KID() string

func (*RSASigner) PrivateKey

func (s *RSASigner) PrivateKey() *rsa.PrivateKey

func (*RSASigner) PublicKey

func (s *RSASigner) PublicKey() crypto.PublicKey

func (*RSASigner) Sign

func (s *RSASigner) Sign(_ context.Context, claims jwt.MapClaims) (string, error)

func (*RSASigner) SignPayload added in v0.86.0

func (s *RSASigner) SignPayload(_ context.Context, payload []byte, headers map[string]any) (string, error)

func (*RSASigner) SignWithHeaders

func (s *RSASigner) SignWithHeaders(_ context.Context, claims jwt.MapClaims, headers map[string]any) (string, error)

SignWithHeaders implements HeaderSigner: it signs claims and merges extra JOSE header params (e.g. `typ`) into the token header. The signer's own kid is set last and cannot be overridden by the supplied headers.

type Signer

type Signer interface {
	// Algorithm returns the JWS algorithm (e.g., RS256, EdDSA).
	Algorithm() string
	// KID returns current key id.
	KID() string
	// Sign creates a signed JWT with provided claims.
	Sign(ctx context.Context, claims jwt.MapClaims) (token string, err error)
}

Signer issues and verifies asymmetric JWTs.

func NewSignerFromPEM

func NewSignerFromPEM(kid string, pemBytes []byte) (Signer, error)

NewSignerFromPEM constructs a Signer from a PEM-encoded private key (RSA, EC, or Ed25519).

type StaticKeySource

type StaticKeySource struct {
	Active Signer
	Pubs   map[string]crypto.PublicKey
}

StaticKeySource is a simple in-memory implementation.

func NewStaticKeySourceFromPEM

func NewStaticKeySourceFromPEM(activeKeyID, activePrivateKeyPEM string, publicKeysPEM map[string]string) (StaticKeySource, error)

NewStaticKeySourceFromPEM builds a StaticKeySource from explicit key material: the active signing key (kid + private-key PEM) plus optional extra verification-only public keys (kid -> public-key PEM, e.g. retired keys kept in the JWKS during rotation). It performs no I/O and reads no environment variables — callers (binaries, hosts) own where the material comes from (#231). Unparseable extra public keys are skipped with a warning, matching the keys.json loader.

func (StaticKeySource) ActiveSigner

func (s StaticKeySource) ActiveSigner() Signer

func (StaticKeySource) PublicKeys

func (s StaticKeySource) PublicKeys() map[string]crypto.PublicKey

Jump to

Keyboard shortcuts

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