go-paseto

repository·dev-v1.x.x·Indexed 19 days ago

https://github.com/aidantwoods/go-paseto

A 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.

Tokens
6.8K
Snippets
28
Records
35
Agent score
67%

What's inside go-paseto

  1. Parse and verify Paseto tokens

    dev-v1.x.x

    To handle a received token, use a paseto.Parser.

    • Use paseto.NewParser() to create a parser that checks for token expiration by default.
    • Use paseto.NewParserWithoutExpiryCheck() if you need to parse an expired token (e.g., for debugging or specific logic).
    • Use ParseV4Public to verify and parse asymmetric (public) tokens.
    • Use 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
    }
  2. Understand Paseto Purpose: Local vs Public

    dev-v1.x.x

    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.

  3. Create, encrypt, and sign Paseto tokens

    dev-v1.x.x

    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)
  4. Configure claims validation rules

    dev-v1.x.x

    The paseto.Parser allows you to enforce specific claims using AddRule(). The following validators are available:

    • ForAudience(audience string) Rule
    • IdentifiedBy(identifier string) Rule
    • IssuedBy(issuer string) Rule
    • NotExpired() Rule
    • Subject(subject string) Rule
    • ValidAt(t time.Time) Rule
    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()))
  5. Manage V4 Asymmetric Secret Keys

    dev-v1.x.x

    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()
  6. Parse and verify Paseto V2 tokens

    dev-v1.x.x

    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")
  7. Initialize a Paseto Parser

    dev-v1.x.x

    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{...})
  8. Initialize a Token

    dev-v1.x.x

    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)
  9. Manage V2 Asymmetric Secret Keys

    dev-v1.x.x

    The V2AsymmetricSecretKey type represents a Paseto Version 2 private key.

    Key Operations:

    • Generation: Use NewV2AsymmetricSecretKey() to generate a new random key pair.
    • Derivation: Use .Public() on a secret key to get its corresponding V2AsymmetricPublicKey.
    • Construction: Keys can be created from hex strings, raw bytes (must be 64 bytes), standard Go ed25519.PrivateKey objects, or a 32-byte hex-encoded seed via NewV2AsymmetricSecretKeyFromSeed().
    • Exporting: Use 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()