brief

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2025 License: Unlicense Imports: 11 Imported by: 0

README

A simple, zero-dependency library to generate (and verify) tokens of arbitrary data with an expiration date. You can think of this as a very stripped-down version of JWT.

It’s based on the Dos and Don’ts of Client Authentication on the Web, which is an oldie but goodie.

It is called brief because:

  1. Life is brief

  2. The tokens this module generates are best briefly-lived

  3. Brief means "letter" (paper & envelope!) in German, and you should sign those, too.

Installation [_installation]

To use brief in your project, run:

go get pals.dev/brief

Usage [_usage]

Below is a basic example of how to use the module to create a new Mint for generating tokens and how to verify a token’s validity.

The code below does not compile; see tests for executable code.

package main

import (
    "fmt"
    "time"

    "pals.dev/brief" // Import the module
)

func main() {
    // Create a new Mint with a secret.
    mint := brief.NewMint([]byte("your-256-bit-secret"))
    // Alternatively, use the zero-value
    mint = &Mint{}
    // If you used the zero-value, you might need the secret for another day
    sec := mint.GetSecret()
    encodedSecret := brief.Encode(sec) // string for another day.

    // Generate a token with a 1-hour expiration.
    token, err := mint.Sign([]byte("session-id-or-whatever"), time.Now().Add(time.Hour))
    if err != nil {
        // handle error
    }
    // You can also generate random data, say for a session ID.
    token, err := mint.Generate(18, time.Now().Add(time.Hour))
    if err != nil {
        // handle error
    }
    // If you need a list of key/value pairs, you can encode url.Values
    vals := url.Values{}
    vals.Add("uid", "some-user-id")
    vals.Add("host", "example.com")
    token, err := mint.SignValues(vals, time.Now().Add(time.Hour))
    if err != nil {
       // handle error
    }
    // Tokens with key/value pairs
    uid := token.Values.Get("uid")

    // Print the generated token... perhaps you want to send a cookie?
    tokenAsString := token.String()
    fmt.Println("Generated Token:", tokenAsString)

    // If you want to get the string-encoded form of random data...
    dataString := brief.Encode(token.Data)

    // Verify the token, e.g. parsing a cookie sent back from client.
    token2, err := mint.VerifyString(tokenAsString)
    if err != nil {
        fmt.Println("Token verification failed:", err)
    } else {
        fmt.Println("Token is valid. Payload:", brief.Encode(token2.Data))
    }
}

Documentation

Overview

package brief generates unforgeable tokens of cryptographically signed data with a build-in expiration. It is lighter than JWT, but more limited.

Inspired by: https://pdos.csail.mit.edu/papers/webauth:sec10.pdf

If you need something more fully-featured than arbitrary data signed and verified with an expiration date, you should look into JWT.

mint := brief.NewMint([]byte("your secret hmac key"))
...
token, err := mint.Sign([]byte("your tamper proof data"), time.Now().Add(time.Hour))
cookieValue := token.String() // serialize
...
token, err := mint.VerifyString(cookieValue)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrFormat indicates that the serialized Token was malformed.
	ErrFormat = errors.New("format invalid")

	// ErrParse indicates an error in parsing a string token.
	ErrParse = errors.New("parsing")

	// ErrFieldData indicates that there was an error with the Data field.
	ErrFieldData = errors.New("data")

	// ErrFieldSignature indicates there was an error with the Signature field.
	ErrFieldSignature = errors.New("signature")

	// ErrFieldExpiry indicates there was an error with the Expiry field parsing.
	ErrFieldExpiry = errors.New("expiry")

	// ErrDecoding indicates that badly encoding data was given to parse.
	ErrDecoding = errors.New("decoding")

	// ErrVerifySignature indicates the signature did not match the data.
	ErrVerifySignature = errors.New("invalid signature")

	// ErrVerifyExpiry indicates that the Token has expired.
	ErrVerifyExpiry = errors.New("expired")

	// ErrCrypto indicates an error occurred in the underlying crypto library.
	ErrCrypto = errors.New("crypto")
)

Functions

func Decode added in v1.1.0

func Decode(s string) ([]byte, error)

Decode decodes data using the same encoding scheme as Encode. This could be useful to create a new Mint with a secret that you've previously retrieved and encoded with Encode.

func Encode

func Encode(data []byte) string

Encode encodes arbitrary data same as the individual parts in Token.String(). It could be useful to use Encode(Token.Data).

Types

type Mint

type Mint struct {
	// contains filtered or unexported fields
}

Mint is used for constructing and verifying Tokens. The zero-value will generate a random secret the first time it needs to sign something, which then remains stable for its lifetime. Use NewMint to initialize the secret to something predictable.

func NewMint

func NewMint(secret []byte) *Mint

NewMint creates a Mint from the given secret. Any Mint instance with the same secret will product identical tokens if all parameters are the same.

func (*Mint) Generate

func (m *Mint) Generate(dataLen int, expires time.Time) (Token, error)

Generate creates a signed Token whose Data is a cryptographically random byte slice of the length provided. The Token will expire at the given time.

func (*Mint) GetSecret added in v1.1.0

func (m *Mint) GetSecret() []byte

GetSecret returns a copy of the Mint's internal secret for creating tokens. If the secret was auto-generated (e.g. due to using a zero-value Mint), this is useful to retrieve that secret and save for later use.

func (*Mint) Sign

func (m *Mint) Sign(data []byte, expires time.Time) (Token, error)

Sign generates a valid Token which expires at the given time.

func (*Mint) SignValues added in v1.2.0

func (m *Mint) SignValues(data url.Values, expires time.Time) (Token, error)

SignValues generates a Token whose Values property is set when no error occurs. Tokens created from the encoded value will also have the Value property set. Note that return token.Value property does not reference the passed url.Values, but is a deep copy.

func (*Mint) Verify

func (m *Mint) Verify(b Token) (Token, error)

Verify checks Token validity (both signature and expiry).

func (*Mint) VerifyString

func (m *Mint) VerifyString(s string) (Token, error)

VerifyString returns a Token from the serialized format and checks its validity. See Mint.Verify.

type Token

type Token struct {
	Values    url.Values
	Data      []byte
	Expiry    time.Time
	Signature []byte
}

Token is an unforgeable set of data + expiration + signature, which can be verified by the Mint which created it (or any with the same secret key).

func FromString

func FromString(s string) (Token, error)

FromString parses a serialization into a Token. A nil error indicates ONLY serialization success, NOT the validity of the Token. For that, use Mint.VerifyString.

func (Token) GetData added in v1.2.0

func (t Token) GetData() []byte

GetData returns the encoded Token.Values if non-nil, otherwise Token.Data.

func (Token) String

func (t Token) String() string

String serializes a Token in a way suitable for use in a HTTP Cookie or URL.

Source Files

  • brief.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL