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.
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.
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.
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
This project can be used in creating a custom JWK Set server. A good place to start is examples/http_server/main.go
.
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.
jwks, err := jwkset.NewDefaultHTTPClient([]string{server.URL})
if err != nil {
log.Fatalf("Failed to create client JWK set. Error: %s", err)
}
jwk, err = jwks.KeyRead(ctx, myKeyID)
if err != nil {
log.Fatalf("Failed to read key from client JWK set. Error: %s", err)
}
This project supports the following key types:
- Edwards-curve Digital Signature Algorithm (EdDSA) (Ed25519 only)
- Go Types:
ed25519.PrivateKey
anded25519.PublicKey
- Go Types:
- Elliptic-curve Diffie–Hellman (ECDH) (X25519
only)
- Go Types:
*ecdh.PrivateKey
and*ecdh.PublicKey
- Go Types:
- Elliptic Curve Digital Signature Algorithm (ECDSA)
- Go Types:
*ecdsa.PrivateKey
and*ecdsa.PublicKey
- Go Types:
- Rivest–Shamir–Adleman (RSA)
- Go Types:
*rsa.PrivateKey
and*rsa.PublicKey
- Go Types:
- HMAC, AES Key Wrap, and other
symmetric keys
- Go Type:
[]byte
- Go Type:
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.
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
, andsecp256k1
, 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.
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.