Install go-paseto
dev-v1.x.xInstall the go-paseto library using go get:
go get -u aidanwoods.dev/go-pasetorepository·dev-v1.x.x·Indexed 19 days ago
https://github.com/aidantwoods/go-pasetoA Go implementation of the PASETO (Platform-Agnostic SEcurity TOkens) specification. It provides a secure alternative to JWT using versioned protocols (Version 2, 3, and 4) instead of algorithm agility. The library supports both symmetric encryption (Local) and asymmetric signing (Public), featuring a flexible Parser with customizable claim validation rules and helper methods for managing standard Paseto claims.
Install the go-paseto library using go get:
go get -u aidanwoods.dev/go-pasetoTo handle a received token, use a paseto.Parser.
paseto.NewParser() to create a parser that checks for token expiration by default.paseto.NewParserWithoutExpiryCheck() if you need to parse an expired token (e.g., for debugging or specific logic).ParseV4Public to verify and parse asymmetric (public) tokens.ParseV4Local (implied by symmetric usage) for symmetric tokens.Parsing will fail if cryptographic checks fail, validation rules are violated, or the format is invalid.
publicKey, err := paseto.NewV4AsymmetricPublicKeyFromHex("1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2")
signed := "v4.public.eyJkYXRh..."
parser := paseto.NewParser()
// parser.AddRule(...) can be used here
token, err := parser.ParseV4Public(publicKey, signed, nil)
if err != nil {
// handle error
}PASETO tokens operate in one of two modes, defined by the Purpose type:
Local: Encrypts the token, ensuring both confidentiality and integrity (equivalent to JWE/JWS combined).Public: Signs the token, ensuring integrity and authenticity but not confidentiality (equivalent to JWS).You can use the constants paseto.Local and paseto.Public to specify these modes.
The library supports multiple PASETO protocol versions via the Version type:
Version2 (v2)Version3 (v3)Version4 (v4)Versions define the cryptographic primitives used by the protocol.
You can create a new token using paseto.NewToken(), set standard claims like expiration and issued-at, and add custom string claims.
To secure the token, you can either encrypt it symmetrically using V4Encrypt or sign it asymmetrically using V4Sign.
token := paseto.NewToken()
token.SetIssuedAt(time.Now())
token.SetNotBefore(time.Now())
token.SetExpiration(time.Now().Add(2 * time.Hour))
token.SetString("user-id", "<uuid>")
// Encrypt (Symmetric)
key := paseto.NewV4SymmetricKey()
encrypted := token.V4Encrypt(key, nil)
// Sign (Asymmetric)
secretKey := paseto.NewV4AsymmetricSecretKey()
signed := token.V4Sign(secretKey, nil)The library provides full support for the following Paseto versions:
The paseto.Parser allows you to enforce specific claims using AddRule(). The following validators are available:
ForAudience(audience string) RuleIdentifiedBy(identifier string) RuleIssuedBy(issuer string) RuleNotExpired() RuleSubject(subject string) RuleValidAt(t time.Time) Ruleparser := 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()))Use V4AsymmetricSecretKey to sign Paseto tokens. This key must be kept private. You can generate a new random key, or reconstruct one from hex, bytes, or an Ed25519 seed.
Key Methods:
NewV4AsymmetricSecretKey() V4AsymmetricSecretKey: Generates a new random Ed25519 key pair.NewV4AsymmetricSecretKeyFromHex(hexEncoded string) (V4AsymmetricSecretKey, error): Creates a key from a hex string.NewV4AsymmetricSecretKeyFromBytes(privateKey []byte) (V4AsymmetricSecretKey, error): Creates a key from a 64-byte slice. Note: This validates that the bytes form a valid Ed25519 key pair.NewV4AsymmetricSecretKeyFromSeed(hexEncoded string) (V4AsymmetricSecretKey, error): Creates a key from a 32-byte hex-encoded seed.Public() V4AsymmetricPublicKey: Returns the corresponding V4AsymmetricPublicKey for this secret key.ExportHex() string: Returns the hex-encoded secret key.ExportBytes() []byte: Returns the raw 64-byte material.ExportSeedHex() string: Returns the hex-encoded 32-byte seed.// Example: Generating a new key pair
secretKey := paseto.NewV4AsymmetricSecretKey()
publicKey := secretKey.Public()
// Example: Exporting for storage
hexString := secretKey.ExportHex()Use the following methods to parse V2 tokens. These methods perform parsing, decryption/verification, and rule validation. If any step fails, an error is returned.
ParseV2Local(key V2SymmetricKey, tainted string): Decrypts a V2 local (symmetric) token.ParseV2Public(key V2AsymmetricPublicKey, tainted string): Verifies a V2 public (asymmetric) token.// Parsing a V2 Local token
token, err := parser.ParseV2Local(v2SymmetricKey, "tainted string")The Parser type is used to verify or decrypt Paseto tokens and validate them against a set of Rules. You can initialize a parser using several constructor functions depending on your validation needs:
NewParser(): Returns a parser with the NotExpired rule preloaded.NewParserWithoutExpiryCheck(): Returns a parser with no rules set (no validation performed).NewParserForValidNow(): Returns a parser that requires tokens to be valid at the current time (time.Now()).MakeParser(rules []Rule): Allows manual construction with a specific slice of rules.// Example: Initialize a parser that checks for expiration
parser := paseto.NewParser()
// Example: Initialize a parser with custom rules
parser := paseto.MakeParser([]paseto.Rule{...})You can create a new Token using several methods depending on your starting data:
NewToken(): Creates an empty token with no claims and no footer.MakeToken(claims map[string]interface{}, footer []byte): Creates a token initialized with a map of claims and a footer. It iterates through the map and calls Set for each entry.NewTokenFromClaimsJSON(claimsData []byte, footer []byte): Creates a token by parsing a raw JSON byte slice into claims and attaching a footer.// Empty token
token := paseto.NewToken()
// Token with claims and footer
claims := map[string]interface{}{"sub": "12345"}
footer := []byte("my-footer")
token, err := paseto.MakeToken(claims, footer)
// Token from JSON
jsonClaims := []byte(`{"sub": "12345"}`)
token, err := paseto.NewTokenFromClaimsJSON(jsonClaims, footer)The V2AsymmetricSecretKey type represents a Paseto Version 2 private key.
Key Operations:
NewV2AsymmetricSecretKey() to generate a new random key pair..Public() on a secret key to get its corresponding V2AsymmetricPublicKey.ed25519.PrivateKey objects, or a 32-byte hex-encoded seed via NewV2AsymmetricSecretKeyFromSeed().ExportHex() or ExportBytes() for the full key, or ExportSeedHex() to export only the underlying seed.// Generate a new secret key
secretKey := paseto.NewV2AsymmetricSecretKey()
// Get the public key to share with others
publicKey := secretKey.Public()
// Construct from a hex seed
secretKey, err := paseto.NewV2AsymmetricSecretKeyFromSeed("32_byte_hex_seed")
// Exporting
hexString := secretKey.ExportHex()
seedHex := secretKey.ExportSeedHex()