{"id":13582247,"url":"https://github.com/lestrrat-go/jwx","last_synced_at":"2025-05-13T20:06:25.201Z","repository":{"id":37406150,"uuid":"45516769","full_name":"lestrrat-go/jwx","owner":"lestrrat-go","description":"Complete implementation of JWx (Javascript Object Signing and Encryption/JOSE) technologies for Go. #golang #jwt #jws #jwk #jwe","archived":false,"fork":false,"pushed_at":"2025-05-06T14:49:59.000Z","size":14592,"stargazers_count":2075,"open_issues_count":5,"forks_count":173,"subscribers_count":26,"default_branch":"develop/v3","last_synced_at":"2025-05-06T19:52:17.304Z","etag":null,"topics":["go","golang","jwe","jwk","jws","jwt","oidc"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lestrrat-go.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["lestrrat"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2015-11-04T05:12:52.000Z","updated_at":"2025-05-06T16:02:47.000Z","dependencies_parsed_at":"2023-09-23T13:31:33.054Z","dependency_job_id":"8122a1a4-053c-4ee5-9b97-9972c16335ef","html_url":"https://github.com/lestrrat-go/jwx","commit_stats":{"total_commits":1692,"total_committers":66,"mean_commits":"25.636363636363637","dds":0.3427895981087471,"last_synced_commit":"f0730766974533dcd9e5f8074a0adfcc471b0f0a"},"previous_names":["lestrrat/jwx"],"tags_count":94,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fjwx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fjwx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fjwx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fjwx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lestrrat-go","download_url":"https://codeload.github.com/lestrrat-go/jwx/tar.gz/refs/heads/develop/v3","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254020478,"owners_count":22000750,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","jwe","jwk","jws","jwt","oidc"],"created_at":"2024-08-01T15:02:31.959Z","updated_at":"2025-05-13T20:06:25.153Z","avatar_url":"https://github.com/lestrrat-go.png","language":"Go","funding_links":["https://github.com/sponsors/lestrrat"],"categories":["Authentication and Authorization","Go","Recently Updated","Authentication and OAuth"],"sub_categories":["[Aug 30, 2024](/content/2024/08/30/README.md)"],"readme":"# github.com/lestrrat-go/jwx/v3 [![CI](https://github.com/lestrrat-go/jwx/actions/workflows/ci.yml/badge.svg)](https://github.com/lestrrat-go/jwx/actions/workflows/ci.yml) [![Go Reference](https://pkg.go.dev/badge/github.com/lestrrat-go/jwx/v3.svg)](https://pkg.go.dev/github.com/lestrrat-go/jwx/v3) [![codecov.io](https://codecov.io/github/lestrrat-go/jwx/coverage.svg?branch=v3)](https://codecov.io/github/lestrrat-go/jwx?branch=v3)\n\nGo module implementing various JWx (JWA/JWE/JWK/JWS/JWT, otherwise known as JOSE) technologies.\n\nIf you are using this module in your product or your company, please add  your product and/or company name in the [Wiki](https://github.com/lestrrat-go/jwx/wiki/Users)! It really helps keeping up our motivation.\n\n# Features\n\n* Complete coverage of JWA/JWE/JWK/JWS/JWT, not just JWT+minimum tool set.\n  * Supports JWS messages with multiple signatures, both compact and JSON serialization\n  * Supports JWS with detached payload\n  * Supports JWS with unencoded payload (RFC7797)\n  * Supports JWE messages with multiple recipients, both compact and JSON serialization\n  * Most operations work with either JWK or raw keys e.g. *rsa.PrivateKey, *ecdsa.PrivateKey, etc).\n* Opinionated, but very uniform API. Everything is symmetric, and follows a standard convention\n  * jws.Parse/Verify/Sign\n  * jwe.Parse/Encrypt/Decrypt\n  * Arguments are organized as explicit required parameters and optional WithXXXX() style options.\n* Extra utilities\n  * `jwk.Cache` to always keep a JWKS up-to-date\n  * [bazel](https://bazel.build)-ready\n\nSome more in-depth discussion on why you might want to use this library over others\ncan be found in the [Description section](#description)\n\nIf you are using v0 or v1, you are strongly encouraged to migrate to using v3\n(the version that comes with the README you are reading).\n\n# SYNOPSIS\n\n\u003c!-- INCLUDE(examples/jwx_readme_example_test.go) --\u003e\n```go\npackage examples_test\n\nimport (\n  \"bytes\"\n  \"fmt\"\n  \"net/http\"\n  \"time\"\n\n  \"github.com/lestrrat-go/jwx/v3/jwa\"\n  \"github.com/lestrrat-go/jwx/v3/jwe\"\n  \"github.com/lestrrat-go/jwx/v3/jwk\"\n  \"github.com/lestrrat-go/jwx/v3/jws\"\n  \"github.com/lestrrat-go/jwx/v3/jwt\"\n)\n\nfunc Example() {\n  // Parse, serialize, slice and dice JWKs!\n  privkey, err := jwk.ParseKey(jsonRSAPrivateKey)\n  if err != nil {\n    fmt.Printf(\"failed to parse JWK: %s\\n\", err)\n    return\n  }\n\n  pubkey, err := jwk.PublicKeyOf(privkey)\n  if err != nil {\n    fmt.Printf(\"failed to get public key: %s\\n\", err)\n    return\n  }\n\n  // Work with JWTs!\n  {\n    // Build a JWT!\n    tok, err := jwt.NewBuilder().\n      Issuer(`github.com/lestrrat-go/jwx`).\n      IssuedAt(time.Now()).\n      Build()\n    if err != nil {\n      fmt.Printf(\"failed to build token: %s\\n\", err)\n      return\n    }\n\n    // Sign a JWT!\n    signed, err := jwt.Sign(tok, jwt.WithKey(jwa.RS256(), privkey))\n    if err != nil {\n      fmt.Printf(\"failed to sign token: %s\\n\", err)\n      return\n    }\n\n    // Verify a JWT!\n    {\n      verifiedToken, err := jwt.Parse(signed, jwt.WithKey(jwa.RS256(), pubkey))\n      if err != nil {\n        fmt.Printf(\"failed to verify JWS: %s\\n\", err)\n        return\n      }\n      _ = verifiedToken\n    }\n\n    // Work with *http.Request!\n    {\n      req, err := http.NewRequest(http.MethodGet, `https://github.com/lestrrat-go/jwx`, nil)\n      req.Header.Set(`Authorization`, fmt.Sprintf(`Bearer %s`, signed))\n\n      verifiedToken, err := jwt.ParseRequest(req, jwt.WithKey(jwa.RS256(), pubkey))\n      if err != nil {\n        fmt.Printf(\"failed to verify token from HTTP request: %s\\n\", err)\n        return\n      }\n      _ = verifiedToken\n    }\n  }\n\n  // Encrypt and Decrypt arbitrary payload with JWE!\n  {\n    encrypted, err := jwe.Encrypt(payloadLoremIpsum, jwe.WithKey(jwa.RSA_OAEP(), jwkRSAPublicKey))\n    if err != nil {\n      fmt.Printf(\"failed to encrypt payload: %s\\n\", err)\n      return\n    }\n\n    decrypted, err := jwe.Decrypt(encrypted, jwe.WithKey(jwa.RSA_OAEP(), jwkRSAPrivateKey))\n    if err != nil {\n      fmt.Printf(\"failed to decrypt payload: %s\\n\", err)\n      return\n    }\n\n    if !bytes.Equal(decrypted, payloadLoremIpsum) {\n      fmt.Printf(\"verified payload did not match\\n\")\n      return\n    }\n  }\n\n  // Sign and Verify arbitrary payload with JWS!\n  {\n    signed, err := jws.Sign(payloadLoremIpsum, jws.WithKey(jwa.RS256(), jwkRSAPrivateKey))\n    if err != nil {\n      fmt.Printf(\"failed to sign payload: %s\\n\", err)\n      return\n    }\n\n    verified, err := jws.Verify(signed, jws.WithKey(jwa.RS256(), jwkRSAPublicKey))\n    if err != nil {\n      fmt.Printf(\"failed to verify payload: %s\\n\", err)\n      return\n    }\n\n    if !bytes.Equal(verified, payloadLoremIpsum) {\n      fmt.Printf(\"verified payload did not match\\n\")\n      return\n    }\n  }\n  // OUTPUT:\n}\n```\nsource: [examples/jwx_readme_example_test.go](https://github.com/lestrrat-go/jwx/blob/v3/examples/jwx_readme_example_test.go)\n\u003c!-- END INCLUDE --\u003e\n\n# How-to Documentation\n\n* [API documentation](https://pkg.go.dev/github.com/lestrrat-go/jwx/v3)\n* [How-to style documentation](./docs)\n* [Runnable Examples](./examples)\n\n# Description\n\nThis Go module implements JWA, JWE, JWK, JWS, and JWT. Please see the following table for the list of\navailable packages:\n\n| Package name                                              | Notes                                           |\n|-----------------------------------------------------------|-------------------------------------------------|\n| [jwt](https://github.com/lestrrat-go/jwx/tree/v3/jwt) | [RFC 7519](https://tools.ietf.org/html/rfc7519) |\n| [jwk](https://github.com/lestrrat-go/jwx/tree/v3/jwk) | [RFC 7517](https://tools.ietf.org/html/rfc7517) + [RFC 7638](https://tools.ietf.org/html/rfc7638) |\n| [jwa](https://github.com/lestrrat-go/jwx/tree/v3/jwa) | [RFC 7518](https://tools.ietf.org/html/rfc7518) |\n| [jws](https://github.com/lestrrat-go/jwx/tree/v3/jws) | [RFC 7515](https://tools.ietf.org/html/rfc7515) + [RFC 7797](https://tools.ietf.org/html/rfc7797) |\n| [jwe](https://github.com/lestrrat-go/jwx/tree/v3/jwe) | [RFC 7516](https://tools.ietf.org/html/rfc7516) |\n## History\n\nMy goal was to write a server that heavily uses JWK and JWT. At first glance\nthe libraries that already exist seemed sufficient, but soon I realized that\n\n1. To completely implement the protocols, I needed the entire JWT, JWK, JWS, JWE (and JWA, by necessity).\n2. Most of the libraries that existed only deal with a subset of the various JWx specifications that were necessary to implement their specific needs\n\nFor example, a certain library looks like it had most of JWS, JWE, JWK covered, but then it lacked the ability to include private claims in its JWT responses. Another library had support of all the private claims, but completely lacked in its flexibility to generate various different response formats.\n\nBecause I was writing the server side (and the client side for testing), I needed the *entire* JOSE toolset to properly implement my server, **and** they needed to be *flexible* enough to fulfill the entire spec that I was writing.\n\nSo here's `github.com/lestrrat-go/jwx/v3`. This library is extensible, customizable, and hopefully well organized to the point that it is easy for you to slice and dice it.\n\n## Why would I use this library?\n\nThere are several other major Go modules that handle JWT and related data formats,\nso why should you use this library?\n\nFrom a purely functional perspective, the only major difference is this:\nWhereas most other projects only deal with what they seem necessary to handle\nJWTs, this module handles the **_entire_** spectrum of JWS, JWE, JWK, and JWT.\n\nThat is, if you need to not only parse JWTs, but also to control JWKs, or\nif you need to handle payloads that are NOT JWTs, you should probably consider\nusing this module. You should also note that JWT is built _on top_ of those\nother technologies. You simply cannot have a complete JWT package without\nimplementing the entirety of JWS/JWE/JWK, which this library does.\n\nNext, from an implementation perspective, this module differs significantly\nfrom others in that it tries very hard to expose only the APIs, and not the\ninternal data. For example, individual JWT claims are not accessible through\nstruct field lookups. You need to use one of the getter methods.\n\nThis is because this library takes the stance that the end user is fully capable\nand even willing to shoot themselves on the foot when presented with a lax\nAPI. By making sure that users do not have access to open structs, we can protect\nusers from doing silly things like creating _incomplete_ structs, or access the\nstructs concurrently without any protection. This structure also allows\nus to put extra smarts in the structs, such as doing the right thing when\nyou want to parse / write custom fields (this module does not require the user\nto specify alternate structs to parse objects with custom fields)\n\nIn the end I think it comes down to your usage pattern, and priorities.\nSome general guidelines that come to mind are:\n\n* If you want a single library to handle everything JWx, such as using JWE, JWK, JWS, handling [auto-refreshing JWKs](https://github.com/lestrrat-go/jwx/blob/v3/docs/04-jwk.md#auto-refreshing-remote-keys), use this module.\n* If you want to honor all possible custom fields transparently, use this module.\n* If you want a standardized clean API, use this module.\n\nOtherwise, feel free to choose something else.\n\n# Contributions\n\n## Issues\n\nFor bug reports and feature requests, please try to follow the issue templates as much as possible.\nFor either bug reports or feature requests, failing tests are even better.\n\n## Pull Requests\n\nPlease make sure to include tests that exercise the changes you made.\n\nIf you are editing auto-generated files (those files with the `_gen.go` suffix, please make sure that you do the following:\n\n1. Edit the generator, not the generated files (e.g. internal/cmd/genreadfile/main.go)\n2. Run `make generate` (or `go generate`) to generate the new code\n3. Commit _both_ the generator _and_ the generated files\n\n## Discussions / Usage\n\nPlease try [discussions](https://github.com/lestrrat-go/jwx/tree/v3/discussions) first.\n\n# Related Modules\n\n* [github.com/lestrrat-go/echo-middleware-jwx](https://github.com/lestrrat-go/echo-middleware-jwx) - Sample Echo middleware\n* [github.com/jwx-go/crypto-signer/gcp](https://github.com/jwx-go/crypto-signer/tree/main/gcp) - GCP KMS wrapper that implements [`crypto.Signer`](https://pkg.go.dev/crypto#Signer)\n* [github.com/jwx-go/crypto-signer/aws](https://github.com/jwx-go/crypto-signer/tree/main/aws) - AWS KMS wrapper that implements [`crypto.Signer`](https://pkg.go.dev/crypto#Signer)\n\n# Credits\n\n* Initial work on this library was generously sponsored by HDE Inc (https://www.hde.co.jp)\n* Lots of code, especially JWE was initially taken from go-jose library (https://github.com/square/go-jose)\n* Lots of individual contributors have helped this project over the years. Thank each and everyone of you very much.\n\n# Quid pro quo\n\nIf you use this software to build products in a for-profit organization, we ask you to _consider_\ncontributing back to FOSS in the following manner:\n\n* For every 100 employees (direct hires) of your organization, please consider contributing minimum of $1 every year to either this project, **or** another FOSS projects that this project uses. For example, for 100 employees, we ask you contribute $100 yearly; for 10,000 employees, we ask you contribute $10,000 yearly.\n* If possible, please make this information public. You do not need to disclose the amount you are contributing, but please make the information that you are contributing to particular FOSS projects public. For this project, please consider writing your name on the [Wiki](https://github.com/lestrrat-go/jwx/wiki/Users)\n\nThis is _NOT_ a licensing term: you are still free to use this software according to the license it\ncomes with. This clause is only a plea for people to acknowledge the work from FOSS developers whose\nwork you rely on each and everyday.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flestrrat-go%2Fjwx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flestrrat-go%2Fjwx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flestrrat-go%2Fjwx/lists"}