AWS KMS adapter for golang-jwt/jwt-go library
May 26, 2026 · View on GitHub
This library provides an AWS KMS(Key Management Service) adapter to be used with the popular GoLang JWT library golang-jwt/jwt-go.
It will Sign a JWT token using an asymmetric key stored in AWS KMS.
Verification can be done both using KMS Verify method or locally with a cached public key (default).
Supported key types
| Signature Algorithm | JWT alg | Note |
|---|---|---|
| ECC_NIST_P256 | ES256 | |
| ECC_NIST_P384 | ES384 | |
| ECC_NIST_P521 | ES512 | |
| ECC_SECG_P256K1 | - | secp256k1 is not supported by JWT |
| RSASSA_PKCS1_V1_5_SHA_256 | RS256 | |
| RSASSA_PKCS1_V1_5_SHA_384 | RS384 | |
| RSASSA_PKCS1_V1_5_SHA_512 | RS512 | |
| RSASSA_PSS_SHA_256 | PS256 | |
| RSASSA_PSS_SHA_384 | PS384 | |
| RSASSA_PSS_SHA_512 | PS512 |
Usage example
See example.go
Public-key cache and KMS key rotation
When verifyWithKMS=false (the default), the first verification call fetches
the KMS key's public key via GetPublicKey and caches it in process memory.
Subsequent verifications use the cached key and standard golang-jwt
verification — no KMS calls. This is efficient for high-volume verification but
has an important caveat: the cache has no TTL by default, so KMS-side key
rotations are not picked up until the process restarts.
For deployments where keys can rotate, either:
- Enable a TTL on the cache (recommended for most cases):
import "time" jwtkms.SetPubKeyCacheTTL(15 * time.Minute) - Call
jwtkms.ClearPubKeyCache()explicitly when you know a rotation has occurred (e.g. from a CloudWatch / EventBridge handler). - Or set
verifyWithKMS=trueon theConfigto have every verification hit KMS — always uses current key material, at the cost of latency and per-call billing.
Security
Found a vulnerability? Please report it privately — see SECURITY.md.
Contributing
See CONTRIBUTING.md for the development workflow, required checks, and backward-compatibility expectations.
Installation
go get github.com/matelang/jwt-go-aws-kms/v2
Versioning
This module follows semantic import versioning
and is published as github.com/matelang/jwt-go-aws-kms/v2.
Historical release tags (2.0.0 through 2.2.0) were published without the
leading v required by the Go modules spec.
Those tags are intentionally preserved so that existing consumers (who pin via
pseudo-versions such as v2.0.0-YYYYMMDDhhmmss-abcdef012345) continue to
resolve. As a side effect, go get github.com/matelang/jwt-go-aws-kms/v2@vX.Y.Z
will not work against those legacy tags — use a pseudo-version or @latest
instead.
Starting with the next release, all tags will use the canonical vX.Y.Z
format, enabling normal version pinning:
go get github.com/matelang/jwt-go-aws-kms/v2@vX.Y.Z
Special thanks
Shouting out to:
-
for the easy to extend GoLang JWT Library
-
for taking over the project from dgrijalva
-
AWS KMS ECC returns the signature in DER-encoded object as defined by ANS X9.62–2005 as mentioned here
-
for their DER to (R,S) and (R,S) to DER methods found here
-
for reviewing my code
-
for various contributions especially around the library's unit testability