Library / SDK
golang-jwt/jwt avatar
golang-jwt/jwt

golang-jwt/jwt: a Go JWT library for parsing, signing and validating tokens

Go implementation of JSON Web Tokens (JWT).

9,231 stars448 forksGoMIT

At a glance

What is it?
golang-jwt/jwt is the maintained fork of dgrijalva/jwt-go, with v5 tightening token validation. It suits Go services that issue and verify Bearer tokens, and it asks you to check the alg yourself.
Who is it for?
Adopt golang-jwt/jwt if you are writing a Go service that issues or verifies JWTs and you want an API the README calls stable, with v5's stricter validation. Do not adopt it if you expect the library to decide which algorithm is acceptable: the README explicitly puts that step on you, and alg=none is only accepted when jwt.UnsafeAllowNoneSignatureType is passed as the key.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem golang-jwt/jwt solves, and who it is for

A JWT is a signed JSON object split into three dot-separated parts: a base64url header, the claims, and a base64url signature. Doing that by hand in Go means handling base64url encoding, key types, claim validation and the parsing of untrusted input. golang-jwt/jwt covers that ground. The README states the library supports parsing and verification as well as generation and signing of JWTs, with HMAC SHA, RSA, RSA-PSS and ECDSA as the current signing algorithms and hooks for adding your own.

The audience is Go developers building authentication. The README points to OAuth 2 Bearer tokens as the common case, and the repository ships http_example_test.go and a request/ directory, which suggests HTTP request handling is a first-class use. If your service issues a token at login and verifies it on every subsequent call, this is the library's job.

The project's own history matters here. After the original author of jwt-go suggested migrating maintenance, a team of maintainers cloned the library into this repository, and the README links dgrijalva/jwt-go#462 for that discussion. So the practical problem is not only JWT handling. It is also that the older import path stopped being the place where fixes land.

How the library works: signing methods, keyfuncs and the parser

The repository layout shows the mechanism. signing_method.go defines the SigningMethod interface, and each algorithm has its own file: hmac.go, rsa.go, rsa_pss.go, ecdsa.go, ed25519.go, plus none.go for the unsecured case. token.go handles token construction and signing; parser.go and parser_option.go handle the other direction; validator.go and registered_claims.go cover claim checking.

Extensions are part of the design. The README says you can implement the SigningMethod interface and register a factory method with RegisterSigningMethod, or supply a jwt.Keyfunc. The listed use case is integrating third-party signature providers such as cloud key management services, HSMs, or additional standards. The README's extension table names GCP integrations, AWS KMS, and a JWKS keyfunc from MicahParks/keyfunc. That table is the clearest signal that the library expects key material to live outside your process.

The security model is the part worth reading twice. The README's second security notice says it is important to validate that the alg presented is what you expect, and that while the library requires key types to match the expected alg, you should take the extra step to verify it in your usage. A keyfunc that returns a key based on the token's own header is exactly the pattern that notice warns about. On the unsecured side, the project deviates from RFC 7519 deliberately: tokens with alg=none are only accepted if the constant jwt.UnsafeAllowNoneSignatureType is provided as the key.

Installing golang-jwt/jwt v5 and signing a first token

Go has to be installed first. The README's installation section then gives one command to add the module as a dependency, and the import path carries the v5 major version.

bash
go get -u github.com/golang-jwt/jwt/v5

In code, the import is the module path. The repository's go.mod declares go 1.21, so that is the floor for the toolchain.

go
import "github.com/golang-jwt/jwt/v5"

The README does not paste a full signing example inline. It links to the documentation website at golang-jwt.github.io/jwt/usage/create/ for signing and verifying, and to pkg.go.dev for runnable examples, including a simple parsing and validating example and a simple building and signing example. Follow those rather than inventing an API shape. When you do, note the README's instruction to verify the alg you expect, because the examples are the place that step is demonstrated.

A first real use is a login handler that mints a token with your claims and a middleware that parses it on later requests. The http_example_test.go file in the repository root is the closest thing to a worked HTTP flow, and request/ exists for extracting tokens from incoming requests.

Where golang-jwt/jwt pushes work back onto you

The alg check is the main one, and it is not a documentation footnote. The README asks you to verify the algorithm in your own usage. In practice that means your keyfunc must not select a verification key purely from the token's header, because the header is attacker-controlled until the signature is checked. The library reduces the blast radius by requiring key types to match the expected alg, but it does not choose the expected alg for you.

The second limitation is version compatibility. The README states that v5.0.0 introduces major improvements to the validation of tokens but is not entirely backward compatible. Breaking changes are collected in VERSION_HISTORY.md, and MIGRATION_GUIDE.md covers updating your code. If you are on v4 or on the upstream github.com/dgrijalva/jwt-go import, plan for code changes rather than a version bump.

The third is the Go toolchain. The README says support follows Go's release policy, so a major Go version is supported until two newer major releases exist, and building with unsupported Go versions is no longer supported because those versions contain unfixed security problems. The README also carries an older notice recommending at least Go 1.15 because of a crypto/elliptic issue. A team pinned to an old toolchain is not the target user.

One more boundary: the README describes the library as production ready with a stable API, and says backward-incompatible changes should be rare outside major versions. That is a statement about API stability, not a promise about which algorithms or key sources you should trust.

golang-jwt/jwt compared with JWKS keyfunc libraries

The closest real alternative in the same ecosystem is not a different JWT format, it is a different division of labour. MicahParks/keyfunc, listed in the README's extension table, provides JWKS support (RFC 7517) as a jwt.Keyfunc. That means it plugs into golang-jwt/jwt rather than replacing it.

The difference in approach is where key discovery lives. golang-jwt/jwt gives you the parser and the Keyfunc interface, and leaves fetching and rotating keys to you or to an extension. A JWKS keyfunc handles retrieving a key set from an endpoint, which is the shape you need when tokens are issued by an external identity provider that rotates signing keys. If you only ever verify tokens your own service signed with a key you already hold, the extension adds a dependency you do not need.

The same pattern applies to the cloud entries in that table: GCP integrations and AWS KMS exist so that signing happens in a managed service or HSM instead of in your process. Choosing between them is a question about where the private key lives, not about which library parses the token.

Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-09-14. The most recent tagged release is v5.3.1 from 2026-01-28, preceded by v5.3.0 on 2025-07-30 and v5.2.3 on 2025-07-15. The README says accepted pull requests land on main and that versions are tagged from main periodically, so a gap between the last push and the last tag is normal for this project rather than a sign of abandonment.

Upgrade cost is concentrated in major versions. The README directs you to VERSION_HISTORY.md for the full list of breaking changes and to MIGRATION_GUIDE.md for updating code, and it states that v5 is not entirely backward compatible with v4. Minor releases should be cheaper given the stated stability policy, but the module path includes /v5, so the major version is visible in every import line and in go.mod.

The licence is MIT. That is permissive and short, and it is the licence the repository carries in its LICENSE file. This is not legal advice; if your organisation has rules about attribution or about vendoring dependencies, read the licence text and your own policy rather than this paragraph.

Editorial conclusion

Adopt golang-jwt/jwt if you are writing a Go service that issues or verifies JWTs and you want an API the README calls stable, with v5's stricter validation. Do not adopt it if you expect the library to decide which algorithm is acceptable: the README explicitly puts that step on you, and alg=none is only accepted when jwt.UnsafeAllowNoneSignatureType is passed as the key. Before you commit, verify your Go toolchain is at least 1.21, since go.mod declares go 1.21, and read MIGRATION_GUIDE.md and VERSION_HISTORY.md if you are coming from v4 or from github.com/dgrijalva/jwt-go.

Frequently asked questions

What is golang-jwt/jwt and why would I use it?

It is a Go implementation of JSON Web Tokens that supports parsing and verification as well as generation and signing, with HMAC SHA, RSA, RSA-PSS and ECDSA among the supported algorithms. You would use it when a Go service needs to issue or check JWTs, commonly as OAuth 2 Bearer tokens.

How can I implement JWTs in Golang with golang-jwt/jwt?

Install Go, run go get -u github.com/golang-jwt/jwt/v5, and import github.com/golang-jwt/jwt/v5. The README points to golang-jwt.github.io/jwt/usage/create/ for signing and verifying and to pkg.go.dev for runnable examples.

Can a JWT never expire?

The library handles parsing, signing and claim validation, but the README does not describe an option for tokens without an expiry. Expiry is a property of the claims you put in the token, and the repository's validator.go and registered_claims.go are where claim checking lives.

Official sources

  1. golang-jwt/jwt on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/golang-jwt-jwt.svg)](https://hysenlabs.com/projects/golang-jwt-jwt)