jwks

package
v0.0.0-...-699f79e Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package jwks provides remote JSON Web Key Set (JWKS) fetching and caching.

The main entry point is NewRemoteKeySet, which returns a *RemoteKeySet that fetches keys from a JWKS endpoint. Keys are cached in memory and refreshed using stale-while-refresh semantics: cached keys are returned immediately when fresh, and stale entries trigger a background refresh so callers never block on a cache miss after the initial fetch.

Key lookup

Use RemoteKeySet.Keys to retrieve all current keys, or RemoteKeySet.Key to look up a specific key by its "kid" header. When a key ID is not found in the cached set, the RemoteKeySet performs an immediate refresh before reporting a KeyNotFoundError.

Caching

A default in-memory CacheStore is installed automatically. Replace it with WithCache if you need a custom implementation. The cache stores one entry per JWKS URL, keyed by URL.

When to use this package directly

Most callers should use the [metadata] or [rp] packages, which construct a RemoteKeySet as part of provider discovery. Use this package directly when you have a JWKS URL and need key retrieval without OIDC discovery.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrKeyNotFound indicates the requested key was not found.
	ErrKeyNotFound = errors.New("jwks key not found")
	// ErrFetchFailed indicates JWKS fetch failure.
	ErrFetchFailed = errors.New("jwks fetch failed")
)

Functions

This section is empty.

Types

type CacheEntry

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

CacheEntry is an opaque cached JWKS entry. Its fields are intentionally unexported.

type CacheStore

type CacheStore interface {
	Get(key string) (value *CacheEntry, ok bool)
	Set(key string, value *CacheEntry)
	Delete(key string)
}

CacheStore is the minimal cache interface used by the jwks package. Implementations must be safe for concurrent use.

type FetchError

type FetchError struct {
	JWKSURL string
	Err     error
}

FetchError indicates a fetch operation failed.

func (*FetchError) Error

func (e *FetchError) Error() string

Error implements error.

func (*FetchError) Is

func (e *FetchError) Is(target error) bool

Is supports errors.Is matching against ErrFetchFailed.

func (*FetchError) Unwrap

func (e *FetchError) Unwrap() error

Unwrap returns the wrapped error.

type KeyNotFoundError

type KeyNotFoundError struct {
	JWKSURL string
	KID     string
}

KeyNotFoundError indicates a specific key ID could not be found.

func (*KeyNotFoundError) Error

func (e *KeyNotFoundError) Error() string

Error implements error.

func (*KeyNotFoundError) Is

func (e *KeyNotFoundError) Is(target error) bool

Is supports errors.Is matching against ErrKeyNotFound.

type Option

type Option func(*RemoteKeySet)

Option configures a RemoteKeySet.

func WithCache

func WithCache(store CacheStore) Option

WithCache configures the cache implementation.

func WithDefaultTTL

func WithDefaultTTL(ttl time.Duration) Option

WithDefaultTTL configures the fallback TTL when cache headers are absent.

func WithExpiryDelta

func WithExpiryDelta(delta time.Duration) Option

WithExpiryDelta configures a small delta used to proactively refresh near-expiry keys.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient configures the HTTP client.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger configures the logger.

func WithMinRefreshInterval

func WithMinRefreshInterval(interval time.Duration) Option

WithMinRefreshInterval configures minimum time between unknown-kid refreshes.

type RemoteKeySet

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

RemoteKeySet fetches and caches a remote JWKS endpoint.

func NewRemoteKeySet

func NewRemoteKeySet(jwksURL string, opts ...Option) (*RemoteKeySet, error)

NewRemoteKeySet creates a new remote key set client. Keys are fetched from the given JWKS URL and cached in an in-memory store. Cached keys are returned immediately when fresh; stale entries trigger a background refresh so callers never block after the initial fetch. Use WithCache to supply a custom CacheStore.

Example
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/Kunde21/lanyard/jwks"
)

func main() {
	server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprint(w, `{"keys":[{
			"kty":"RSA",
			"kid":"key-1",
			"use":"sig",
			"alg":"RS256",
			"n":"2ieuB-8BJ19bpi_0iqt8mi-31jPpO4NHNFeH-AeG7dIwBlhVVUGbJ2yhvHALutgeMfzn5OtbX75Szul7lmAxrGSAkYqg1SuRzJOJJ0-5rxWrismoIDBjSL4jCTL0HYFWePQzoB_RFPaLqiuye5FQV02iG2b8f-EgpCxTkN8rudtoCurIFDLxc4eu7TkLrS5prfcAj74Yub2qXlJtE0Q5syjxbiNI5gg_Tqok_Klfi7glU8cj1ahsvDqPXiMqKnQ3zZr_UTnkT3Vb_q3nyBukSZUF-gduBnAg17sCayPw1EBBFhq04VJRYDDL30b6oq8eaFfnhMD0xo6HG7gZY71caQ",
			"e":"AQAB"
		}]}`)
	}))
	defer server.Close()

	ks, err := jwks.NewRemoteKeySet(
		server.URL+"/jwks",
		jwks.WithHTTPClient(&http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			},
		}),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	keys, err := ks.Keys(context.Background())
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(len(keys) > 0)
}
Output:
true

func (*RemoteKeySet) Key

func (r *RemoteKeySet) Key(ctx context.Context, kid string) (jose.JSONWebKey, error)

Key returns a specific key by kid.

func (*RemoteKeySet) Keys

func (r *RemoteKeySet) Keys(ctx context.Context) ([]jose.JSONWebKey, error)

Keys returns keys from cache, refreshing stale or missing values as needed.

Jump to

Keyboard shortcuts

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