Skip to content

gilbsgilbs/jwit

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

License Apache 2.0 Godoc Actions Status Coverage Status

JWIT

JWIT is a tiny Go library built around go-jose that brings JSON Web Tokens (JWTs) and JSON Web Key Sets (JWKS) into your apps.

JWIT features:

  • A high-level API to sign and verify your asymmetric JWTs.
  • A high-level API to publish your public JWKS.

💡 As JWIT sticks to the standards and is not tight to any framework, you can actually pick which features you want to use. You can use it to just sign JWTs, just verify JWTs you get from a third-party and your own servers, or just expose your public JWKS.

One neat use-case:

  1. Your authorization server uses JWIT to sign new JWTs.
  2. Your authorization server uses JWIT to expose its public keys as a JWKS (usually at /.well-known/jwks.json).
  3. Your resource server uses JWIT to unmarshal incoming JWTs and validate them against your authorization server's JWKS.

🤯 JWIT will automatically catch changes to the JWKS. Rotating your secrets has never been so easy.

Installation

go get github.com/gilbsgilbs/jwit

Overview

This section shows a few basic examples that'll give you a sneak peak of how simple it is to work with JWIT. For more in-depth examples (such as working with private claims, loading keys from PEM, …), please head to the godoc page.

Create a signed JWT

// 1. Create a signer from a JSON Web Key Set (JWKS). The JWKS payload will typically reside your
//    authorization server's config or in a secure vault.
signer, err := jwit.NewSigner([]byte(`{"keys": [ ... ]}`))

// 2. Create a JWT that expires in one hour.
rawJWT, err := signer.SignJWT(jwit.C{Duration: 1 * time.Hour})

// 3. That's it, simple as that. rawJWT is a signed JWT token that is ready to serve.
fmt.Println(rawJWT)

Verify a JWT

// 1. Create a verifier
verifier, err := jwit.NewVerifier(
    // Specify an URL to the issuer's public JWKS.
    &jwit.Issuer{
        // This should correspond to the "iss" claims of the JWTs
        Name: "myVeryOwnIssuer",

        // This is an HTTP(S) URL where the authorization server publishes its public keys.
        // It will be queried the first time a JWT is verified and then periodically.
        // If this URL is let empty, remote JWKS are disabled.
        JWKSURL: "https://my-very-own-issuer.com/.well-known/jwks.json",

        // You can specify how long the issuer's public keys should be kept in cache.
        // Passed that delay, the JWKS will be re-fetched once asynchronously.
        // Defaults to 24 hours.
        TTL: 10 * time.Hour,

        // Alternatively, you can specify a set of public keys directly:
        PublicKeys: []interface{}{
            rsaPublicKey, ecdsaPublicKey,
            []byte(`--- BEGIN RSA PUBLIC KEY --- ...`),
            []byte(`{"keys":[ ... JWKS ... ]}`),
        },
    },
    // ... you can specify as many issuers as you want
)

// 2. Verify the JWT using its "iss" claim.
isValid, err := verifier.VerifyJWT(rawJWT)

// Alternatively, if your JWT doesn't have an "iss" claim, you can also pass public keys explicitely.
isValid, err := verifier.VerifyJWTWithKeys(rawJWT, []crypto.PublicKey{ecdsaPublicKey, rsaPublicKey})

Expose the public JWKS

http.HandleFunc(
    "/.well-known/jwks.json",
    func (w http.ResponseWriter, req *http.Request) {
        // Just get the public JWKS from the signer.
        jwks, err := signer.DumpPublicJWKS()

        // And write it to the response body.
        w.Write(jwks)
    },
)

🔒 Security

If you found a security vulnerability in JWIT itslef, do not reveal it publicly and adopt a responsible disclosure. You may open a GitHub issue stating that you found a vulnerability and specifying a safe way to get in touch with you.

Note that JWIT is not another JWT/JWKS implementation by any mean. JWIT relies on go-jose, a popular JWx implementation by Square. On top of that, go-jose and Go's stdlib are the only dependencies to this library. This greatly reduces the attack surface of JWIT. If you found a security vulnerability in go-jose, please refer to their bug bounty program.