AWS KMS adapter for golang-jwt/jwt-go library

May 26, 2026 · View on GitHub

Go Lint Security CodeQL OpenSSF Scorecard Go Reference Go Report Card License

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 AlgorithmJWT algNote
ECC_NIST_P256ES256
ECC_NIST_P384ES384
ECC_NIST_P521ES512
ECC_SECG_P256K1-secp256k1 is not supported by JWT
RSASSA_PKCS1_V1_5_SHA_256RS256
RSASSA_PKCS1_V1_5_SHA_384RS384
RSASSA_PKCS1_V1_5_SHA_512RS512
RSASSA_PSS_SHA_256PS256
RSASSA_PSS_SHA_384PS384
RSASSA_PSS_SHA_512PS512

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:

  1. Enable a TTL on the cache (recommended for most cases):
    import "time"
    jwtkms.SetPubKeyCacheTTL(15 * time.Minute)
    
  2. Call jwtkms.ClearPubKeyCache() explicitly when you know a rotation has occurred (e.g. from a CloudWatch / EventBridge handler).
  3. Or set verifyWithKMS=true on the Config to 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:

  • dgrijalva

    for the easy to extend GoLang JWT Library

  • golang-jwt

    for taking over the project from dgrijalva

  • Mikael Gidmark

    AWS KMS ECC returns the signature in DER-encoded object as defined by ANS X9.62–2005 as mentioned here

  • codelittinc

    for their DER to (R,S) and (R,S) to DER methods found here

  • karalabe

    for reviewing my code

  • gkelly

    for various contributions especially around the library's unit testability