Documentation

Overview

Package tokens provides means to generate and validate base64 encoded tokens compatible with luci-py's components.auth implementation.

Example
kind := TokenKind{
	Algo:       TokenAlgoHmacSHA256,
	Expiration: 30 * time.Minute,
	SecretKey:  "secret_key_name",
	Version:    1,
}

ctx := context.Background()
ctx, _ = testclock.UseTime(ctx, time.Unix(1444945245, 0))
ctx = secrets.Use(ctx, &testsecrets.Store{})

// Make a token.
token, err := kind.Generate(ctx, []byte("state"), map[string]string{"k": "v"}, 0)
if err != nil {
	fmt.Printf("error - %s\n", err)
	return
}
fmt.Printf("token - %s\n", token)

// Validate it, extract embedded data.
embedded, err := kind.Validate(ctx, token, []byte("state"))
if err != nil {
	fmt.Printf("error - %s\n", err)
	return
}
fmt.Printf("embedded - %s\n", embedded)
Output:

token - AXsiX2kiOiIxNDQ0OTQ1MjQ1MDAwIiwiayI6InYifQJ85lxSuuoYaZ2q0ecPB5-E8Wv9J2Llh0D4Y4wRWCbx
embedded - map[k:v]

Index

Examples

Constants

View Source
const (
	// TokenAlgoHmacSHA256 algorithm stores public portion of the token as plain
	// text and uses HMAC SHA256 to authenticate its integrity.
	TokenAlgoHmacSHA256 = "HMAC-SHA256"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type TokenAlgo

type TokenAlgo string

TokenAlgo identifies how token is authenticated.

type TokenKind

type TokenKind struct {
	Algo       TokenAlgo
	Expiration time.Duration // how long generated token lives
	SecretKey  string        // name of the secret key in secrets.Store
	Version    byte          // tokens with another version will be rejected
}

TokenKind is a configuration of particular type of a token. It can be defined statically in a module and then its Generate() and Validate() methods can be used to produce and verify tokens.

func (*TokenKind) Generate

func (k *TokenKind) Generate(c context.Context, state []byte, embedded map[string]string, exp time.Duration) (string, error)

Generate produces an urlsafe base64 encoded string that contains 'embedded' and MAC tag for 'state' + 'embedded' (but not the 'state' itself). The exact same 'state' then must be used in Validate to successfully verify the token.

'embedded' is an optional map with additional data to add to the token. It is embedded directly into the token and can be easily extracted from it by anyone who has the token. Should be used only for publicly visible data. It is tagged by token's MAC, so 'Validate' function can detect any modifications (and reject tokens tampered with).

The context is used to grab secrets.Store and the current time.

func (*TokenKind) Validate

func (k *TokenKind) Validate(c context.Context, token string, state []byte) (map[string]string, error)

Validate checks token MAC and expiration, decodes data embedded into it.

'state' must be exactly the same as passed to Generate when creating a token. If it's different, the token is considered invalid. It usually contains some implicitly passed state that should be the same when token is generated and validated. For example, it may be an account ID of a current caller. Then if such token is used by another account, it is considered invalid.

The context is used to grab secrets.Store and the current time.

Source Files