Help us shape the future of Go! Take the 2026 Go Developer Survey

token

package
v0.1.430 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: Apache-2.0 Imports: 17 Imported by: 2

Documentation

Overview

Package token manages the on-disk cache of Chainguard OIDC access and refresh tokens, organized by audience and optional alias. Refresh tokens read and written WithIssuer are kept in refresh-token families, one per login, and are exchanged through Refresh, which serializes every process sharing the cache.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrLockUnavailable is returned when the store lock could not be taken:
	// another process held it past the timeout, the context ended, or the
	// filesystem does not support locking. Nothing was exchanged. A caller
	// should fail with a retryable error rather than serve a cached access
	// token, which may be for another scope, issuer or principal, and must
	// not exchange the refresh token without the lock.
	ErrLockUnavailable = errors.New("token: the refresh-token store lock is unavailable")

	// ErrSuccessorNotStored is returned by Refresh when the exchange succeeded
	// but the successor it returned could not be written. The family has been
	// discarded, so the superseded token is never presented again, and the
	// access token the exchange minted is still valid; the next refresh needs
	// a new login.
	ErrSuccessorNotStored = errors.New("token: the rotated refresh token could not be stored")
)
View Source
var (
	AllKinds = []Kind{KindAccess, KindRefresh}
)

Functions

func Delete

func Delete(kind Kind, audience string, opts ...Option) error

Delete removes the token for the given audience, if it exists. No error is returned if the token doesn't exist.

For KindRefresh it also removes audience from the coverage of every family (of the given issuer only, when WithIssuer is passed), deleting a family left covering nothing.

func DeleteAll

func DeleteAll() error

DeleteAll removes all Chainguard tokens and empty audience directories, including every refresh-token family. The store's lock file holds no token and is left in place.

func DeleteFamilies added in v0.1.424

func DeleteFamilies() error

DeleteFamilies removes every refresh-token family and the per-audience copies of each family's token, leaving other per-audience token files and the store's lock file in place. Every family holds a Chainguard platform refresh token, so a caller clearing platform credentials by walking audience directories needs this as well: a family can cover audiences that have no directory.

func ListAudiences added in v0.1.164

func ListAudiences() ([]string, error)

ListAudiences returns the set of audiences for which an access token (KindAccess) currently exists in the local token cache.

Audiences are recovered from each token's "aud" claim rather than from the on-disk directory name, since the directory name is a lossy encoding of the audience (e.g. "/" is replaced with "-"). The returned slice is sorted and de-duplicated. Files that cannot be read or parsed as tokens are skipped.

func Load

func Load(kind Kind, audience string, opts ...Option) ([]byte, error)

Load returns the token for the given audience if it exists, or an error if it doesn't.

func Path

func Path(kind Kind, audience string, opts ...Option) (string, error)

Path is the filepath of the token for the given audience.

func Refresh added in v0.1.424

func Refresh(ctx context.Context, audience string, exchange ExchangeFunc, opts ...Option) error

Refresh loads the refresh token from the issuer named by WithIssuer that covers audience, passes it to exchange, and stores the successor exchange returns, all while holding a lock shared with every other process using the cache. The token is loaded after the lock is taken, so a process that waited on another's rotation presents the successor, never the parent it would have read before waiting.

It returns exchange's error unchanged, ErrLockUnavailable without calling exchange, an error wrapping fs.ErrNotExist when no token covers audience, or ErrSuccessorNotStored after a successful exchange whose result could not be written.

func RemainingLife

func RemainingLife(kind Kind, audience string, less time.Duration, opts ...Option) time.Duration

RemainingLife returns the amount of time remaining before the token for the given audience expires. Returns 0 for expired and non-existent tokens.

func Save

func Save(token []byte, kind Kind, audience string, opts ...Option) error

Save saves the given token to cache/audience. A KindRefresh token saved WithIssuer is stored as a family covering audience alone, the same as SaveFamily with that one audience.

func SaveFamily added in v0.1.424

func SaveFamily(tok []byte, audiences []string, opts ...Option) error

SaveFamily stores tok, a refresh token obtained from the issuer named by WithIssuer, as that issuer's family serving audiences. Those audiences are removed from every other family of that issuer, so each audience resolves to exactly one token, and tok is written to each one's per-audience file unless that file holds a live token from another issuer and the audience is not the one named by WithPrimaryAudience.

The family is recorded under the issuer the caller names, which is where the token is presented, not under the token's iss claim: an issuer reached through another name, such as a cluster-internal issuer behind a mapped domain, mints tokens whose iss is a URL the client never dials.

Types

type ExchangeFunc added in v0.1.424

type ExchangeFunc func(ctx context.Context, refreshToken string) (successor string, err error)

ExchangeFunc presents refreshToken to the issuer and returns the refresh token the issuer answered with. Returning "" or refreshToken itself stores nothing, which is how a caller that found it no longer needs an exchange declines one. It runs with the store lock held, so it must not call back into Refresh, SaveFamily or a KindRefresh Save or Delete.

type Kind added in v0.1.10

type Kind string
const (
	KindAccess  Kind = "oidc-token"
	KindRefresh Kind = "refresh-token"
)

type Option added in v0.1.44

type Option func(*token)

func WithAlias added in v0.1.44

func WithAlias(a string) Option

WithAlias allows callers to organize tokens into subdirectories under an audience to manage multiple tokens for the same audience without overwriting.

Example

ExampleWithAlias demonstrates creating an Option that sets a token alias.

package main

import (
	"fmt"

	"chainguard.dev/sdk/auth/token"
)

func main() {
	opt := token.WithAlias("my-alias")
	fmt.Println(opt != nil)
}
Output:
true

func WithIssuer added in v0.1.424

func WithIssuer(iss string) Option

WithIssuer scopes a refresh token to the issuer that minted it. For KindRefresh, Load and RemainingLife then return only a token from that issuer, resolved through the family store (see SaveFamily), and Save and Delete act on that issuer's families. A caller that passes no issuer sees only the per-audience file, exactly as it would without the family store, and never a family. Other kinds ignore the option, and so do aliased tokens, which never belong to a family.

func WithPrimaryAudience added in v0.1.424

func WithPrimaryAudience(aud string) Option

WithPrimaryAudience names the audience a login was requested for. SaveFamily always writes that audience's per-audience copy, even over a live token from another issuer, which it keeps in every other audience it covers.

Jump to

Keyboard shortcuts

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