token

package
v1.786.165 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package token mints and verifies the HS256 JWTs that the team SPA, the /v1/team/account API and the /v1/team/transactor data plane all share.

The wire format is byte-compatible with the platform `jwt-simple` HS256 tokens (foundations/core/packages/token/src/token.ts): header {"typ":"JWT","alg":"HS256"}, a COMPACT JSON payload whose keys appear in the fixed order {extra, account, workspace, sub, exp, nbf} with undefined/empty keys omitted, base64url WITHOUT padding, and a raw HMAC-SHA256 signature over `header.payload`.

account and workspace, when present, MUST be UUIDs — the upstream `generateToken` throws otherwise and the transactor client refuses a workspace token that is missing either, so we enforce the same invariant at mint time.

The secret is the shared `SERVER_SECRET` (synced from KMS in production). One secret, one wire format — every team surface signs and verifies through this package. Ported VERBATIM from github.com/hanzoai/team-go/pkg/token.

Index

Constants

View Source
const DefaultSecret = "secret"

DefaultSecret mirrors the upstream `getSecret()` fallback. Production always injects SERVER_SECRET (synced from KMS); the literal exists only so dev parity with the upstream pods (which also default to "secret") holds. It is NEVER a production secret — the Mount path fails onto the KMS-synced env value.

Variables

View Source
var ErrExpired = errors.New("token: expired")

ErrExpired is returned by Decode(verify=true) when the token's `exp` has passed.

View Source
var ErrMalformed = errors.New("token: malformed")

ErrMalformed is returned when a token is not three base64url segments.

View Source
var ErrNotYetValid = errors.New("token: not yet valid")

ErrNotYetValid is returned by Decode(verify=true) when the token's `nbf` is in the future.

View Source
var ErrSignature = errors.New("token: signature mismatch")

ErrSignature is returned when HMAC verification fails.

Functions

func Generate

func Generate(account, workspace string, extra map[string]any, exp int64, secret string) (string, error)

Generate mints an HS256 token for account (always) and workspace (optional — pass "" for an account/login token that is not yet scoped to a workspace). extra is folded in as the leading `extra` claim when non-empty (e.g. {"org":"acme"}). exp is the expiry as a unix-second timestamp — pass 0 to mint a token WITHOUT an `exp` claim (the wire-golden / non-expiring case). Both ids are validated as UUIDs.

Types

type Token

type Token struct {
	Extra     map[string]any `json:"extra,omitempty"`
	Account   string         `json:"account"`
	Workspace string         `json:"workspace,omitempty"`
	Sub       string         `json:"sub,omitempty"`
	Exp       int64          `json:"exp,omitempty"`
	Nbf       int64          `json:"nbf,omitempty"`
}

Token is the decoded payload. Field order is the jwt-simple emit order so marshalling reproduces the upstream byte layout; `omitempty` drops the keys jwt-simple leaves `undefined`. account carries no omitempty: it is always present (the upstream payload always includes `account`).

func Decode

func Decode(tok, secret string, verify bool) (*Token, error)

Decode verifies (when verify is true) and parses an HS256 token. When verify is true it enforces the temporal claims: a token whose `exp` has passed is rejected (ErrExpired) and a token whose `nbf` is in the future is rejected (ErrNotYetValid). A missing claim (0) is not enforced. This closes the permanent-replay window on a captured token (the transactor token rides in the URL path — log-prone — so a bounded lifetime is the mitigation until the front moves it off the URL, #60).

Jump to

Keyboard shortcuts

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