MCPcopy Index your code
hub / github.com/aidantwoods/go-paseto

github.com/aidantwoods/go-paseto @v1.6.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.6.0 ↗ · + Follow
249 symbols 856 edges 26 files 148 documented · 59% updated 6mo agov1.6.0 · 2025-12-27★ 4882 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Go Paseto Go-Paseto

A Go implementation of PASETO.

Paseto is everything you love about JOSE (JWT, JWE, JWS) without any of the many design deficits that plague the JOSE standards.

Contents

What is Paseto?

Paseto (Platform-Agnostic SEcurity TOkens) is a specification for secure stateless tokens.

Key Differences between Paseto and JWT

Unlike JSON Web Tokens (JWT), which gives developers more than enough rope with which to hang themselves, Paseto only allows secure operations. JWT gives you "algorithm agility", Paseto gives you "versioned protocols". It's incredibly unlikely that you'll be able to use Paseto in an insecure way.

Caution: Neither JWT nor Paseto were designed for stateless session management. Paseto is suitable for tamper-proof cookies, but cannot prevent replay attacks by itself.

Installation

go get -u aidanwoods.dev/go-paseto

Overview of the Go library

Okay, let's create a token:

token := paseto.NewToken()

token.SetIssuedAt(time.Now())
token.SetNotBefore(time.Now())
token.SetExpiration(time.Now().Add(2 * time.Hour))

token.SetString("user-id", "<uuid>")

Now encrypt it:

key := paseto.NewV4SymmetricKey() // don't share this!!

encrypted := token.V4Encrypt(key, nil)

Or sign it (this allows recievers to verify it without sharing secrets):


secretKey := paseto.NewV4AsymmetricSecretKey() // don't share this!!!
publicKey := secretKey.Public() // DO share this one

signed := token.V4Sign(secretKey, nil)

To handle a recieved token, let's use an example from Paseto's test vectors:

The Paseto token is as follows

v4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9v3Jt8mx_TdM2ceTGoqwrh4yDFn0XsHvvV_D0DtwQxVrJEBMl0F2caAdgnpKlt4p7xBnx1HcO-SPo8FPp214HDw.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9

And the public key, given in hex is:

1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2

Importing a public key, and then verifying a token:

publicKey, err := paseto.NewV4AsymmetricPublicKeyFromHex("1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2") // this wil fail if given key in an invalid format
signed := "v4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9v3Jt8mx_TdM2ceTGoqwrh4yDFn0XsHvvV_D0DtwQxVrJEBMl0F2caAdgnpKlt4p7xBnx1HcO-SPo8FPp214HDw.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9"

parser := paseto.NewParserWithoutExpiryCheck() // only used because this example token has expired, use NewParser() (which checks expiry by default)
token, err := parser.ParseV4Public(publicKey, signed, nil) // this will fail if parsing failes, cryptographic checks fail, or validation rules fail

// the following will succeed
require.JSONEq(t,
    "{\"data\":\"this is a signed message\",\"exp\":\"2022-01-01T00:00:00+00:00\"}",
    string(token.ClaimsJSON()),
)
require.Equal(t,
    "{\"kid\":\"zVhMiPBP9fRf2snEcT7gFTioeA9COcNy9DfgL1W60haN\"}",
    string(token.Footer()),
)
require.NoError(t, err)

Supported Claims Validators

The following validators are supported:

func ForAudience(audience string) Rule
func IdentifiedBy(identifier string) Rule
func IssuedBy(issuer string) Rule
func NotExpired() Rule
func Subject(subject string) Rule
func ValidAt(t time.Time) Rule

A token using claims all the claims which can be validated can be constructed as follows:

token := paseto.NewToken()

token.SetAudience("audience")
token.SetJti("identifier")
token.SetIssuer("issuer")
token.SetSubject("subject")

token.SetExpiration(time.Now().Add(time.Minute))
token.SetNotBefore(time.Now())
token.SetIssuedAt(time.Now())

secretKeyHex := "b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a37741eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2"
secretKey, _ := paseto.NewV4AsymmetricSecretKeyFromHex(secretKeyHex)

signed := token.V4Sign(secretKey, nil)

The token in signed can then be validated using a public key as follows:

parser := paseto.NewParser()
parser.AddRule(paseto.ForAudience("audience"))
parser.AddRule(paseto.IdentifiedBy("identifier"))
parser.AddRule(paseto.IssuedBy("issuer"))
parser.AddRule(paseto.Subject("subject"))
parser.AddRule(paseto.NotExpired())
parser.AddRule(paseto.ValidAt(time.Now()))

publicKeyHex := "1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2"
publicKey, err := paseto.NewV4AsymmetricPublicKeyFromHex(publicKeyHex)
if err != nil {
    // panic or deal with error of invalid key
}

parsedToken, err := parser.ParseV4Public(publicKey, signed, nil)
if err != nil {
    // deal with error of token which failed to be validated, or cryptographically verified
}

If everything succeeds, the value in parsedToken will be equivalent to that in token.

Supported Paseto Versions

Version 4

Version 4 is fully supported.

Version 3

Version 3 is fully supported.

Version 2

Version 2 is fully supported.

Supported Go Versions

Only officially supported versions of Go will be supported by Go Paseto. Versions of Go which have recently gone out of support may continue to work with this library for some time, however this is not guarenteed and should not be relied on.

When support for an out of date version of Go is dropped, this will be done as part of a minor version bump.

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 122
Method 97
Struct 26
TypeAlias 2
FuncType 1
Interface 1

Languages

Go100%

Modules by API surface

v4_keys.go24 symbols
v3_keys.go23 symbols
v2_keys.go22 symbols
token.go22 symbols
claims.go22 symbols
errors.go17 symbols
paseto.go15 symbols
parser.go15 symbols
token_test.go14 symbols
message.go14 symbols
claims_test.go9 symbols
vectors_test.go6 symbols

For agents

$ claude mcp add go-paseto \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page