Skip to content

MicahParks/jwkset

Repository files navigation

Go Reference

JWK Set (JSON Web Key Set)

This is a JWK Set (JSON Web Key Set) implementation written in Golang.

The goal of this project is to provide a complete implementation of JWK and JWK Sets within the constraints of the Golang standard library, without implementing any cryptographic algorithms. For example, Ed25519 is supported, but Ed448 is not, because the Go standard library does not have a high level implementation of Ed448.

If you would like to generate or validate a JWK without writing any Golang code, please visit the Generate a JWK Set section.

If you would like to have a JWK Set client to help verify JWTs without writing any Golang code, you can use the JWK Set Client Proxy (JCP) project perform JWK Set client operations in the language of your choice using an OpenAPI interface.

Generate a JWK Set

If you would like to generate a JWK Set without writing Golang code, this project publishes utilities to generate a JWK Set from:

  • PEM encoded X.509 Certificates
  • PEM encoded public keys
  • PEM encoded private keys

The PEM block type is used to infer which key type to decode. Reference the Supported keys section for a list of supported cryptographic key types.

Website

Visit https://jwkset.com to use the web interface for this project. You can self-host this website by following the instructions in the README.md in the website directory.

Command line

Gather your PEM encoded keys or certificates and use the cmd/jwksetinfer command line tool to generate a JWK Set.

Install

go install github.com/MicahParks/jwkset/cmd/jwksetinfer@latest

Usage

jwksetinfer mykey.pem mycert.crt

Custom server

This project can be used in creating a custom JWK Set server. A good place to start is examples/http_server/main.go.

Golang JWK Set client

If you are using github.com/golang-jwt/jwt/v5 take a look at github.com/MicahParks/keyfunc/v3.

This project can be used to create JWK Set clients. An HTTP client is provided. See a snippet of the usage from examples/default_http_client/main.go below.

Create a JWK Set client from the server's HTTP URL.

jwks, err := jwkset.NewDefaultHTTPClient([]string{server.URL})
if err != nil {
	log.Fatalf("Failed to create client JWK set. Error: %s", err)
}

Read a key from the client.

jwk, err = jwks.KeyRead(ctx, myKeyID)
if err != nil {
	log.Fatalf("Failed to read key from client JWK set. Error: %s", err)
}

Supported keys

This project supports the following key types:

Cryptographic keys can be added, deleted, and read from the JWK Set. A JSON representation of the JWK Set can be created for hosting via HTTPS. This project includes an in-memory storage implementation, but an interface is provided for more advanced use cases.

Notes

This project aims to implement the relevant RFCs to the fullest extent possible using the Go standard library, but does not implement any cryptographic algorithms itself.

  • RFC 8037 adds support for Ed448, X448, and secp256k1, but there is no Golang standard library support for these key types.
  • In order to be compatible with non-RFC compliant JWK Set providers, this project does not strictly enforce JWK parameters that are integers and have extra or missing leading padding. See the release notes of v0.5.15 for details.
  • Base64url Encoding requires that all trailing = characters be removed. This project automatically strips any trailing = characters in an attempt to be compatible with improper implementations of JWK.
  • This project does not currently support JWK Set encryption using JWE. This would involve implementing the relevant JWE specifications. It may be implemented in the future if there is interest. Open a GitHub issue to express interest.

Related projects

A JWK Set client for the github.com/golang-jwt/jwt/v5 project.

A JWK Set client proxy. JCP for short. This project is a standalone service that uses keyfunc under the hood. It primarily exists for these use cases:

The language or shell a program is written in does not have an adequate JWK Set client. Validate JWTs with curl? Why not? Restrictive networking policies prevent a program from accessing the remote JWK Set directly. Many co-located services need to validate JWTs that were signed by a key that lives in a remote JWK Set. If you can integrate keyfunc directly into your program, you likely don't need JCP.