temptoken

package
v1.3.14 Latest Latest
Warning

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

Go to latest
Published: May 29, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MCPAuthScopeName names the scope that authorizes the MCP per-user OAuth
	// auth page to call the per-user flow endpoints. Bound resource_id is the
	// OAuth flow ID.
	MCPAuthScopeName = "mcp_auth"

	// MCPHeadersAuthScopeName names the scope that authorizes the MCP
	// per-user-headers auth page to call the per-user-headers submission
	// flow endpoints. Bound resource_id is the headers flow ID. Parallel
	// of MCPAuthScopeName for the per-user-headers surface.
	MCPHeadersAuthScopeName = "mcp_headers_auth"
)

Well-known scope names. The framework reserves the canonical strings here so that issuers (e.g. framework/oauth2) and registrants (the handlers package that defines the routes) reference a single source of truth. The actual Scope definition — routes, TTL, single-use — is owned by the transports/handlers layer that registers the scope with a Service.

Variables

View Source
var (
	// ErrTokenNotFound is returned when the presented token does not match any row.
	ErrTokenNotFound = errors.New("temptoken: token not found")
	// ErrTokenExpired is returned when the matched row's expires_at is in the past.
	ErrTokenExpired = errors.New("temptoken: token expired")
	// ErrScopeUnknown is returned when the row's scope column does not match any
	// registered scope. Indicates either a stale row (scope was deregistered) or
	// a corrupted row.
	ErrScopeUnknown = errors.New("temptoken: token scope is not registered")
	// ErrRouteNotAllowed is returned when the (method, path) of the request does
	// not satisfy any of the scope's AllowedRoutes (after resource_id substitution).
	ErrRouteNotAllowed = errors.New("temptoken: request method and path are not allowed by token scope")
	// ErrTTLExceedsMax is returned by Mint when the caller-requested TTL is
	// larger than the scope's MaxTTL.
	ErrTTLExceedsMax = errors.New("temptoken: requested TTL exceeds scope MaxTTL")
)

Errors returned by the service. Callers (notably the auth middleware) should treat these as opaque "not authorized" signals — they're typed so tests can assert on them without coupling to error message text.

Functions

This section is empty.

Types

type Registry

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

Registry holds the process-global set of declared scopes. Scopes register at startup; the middleware looks them up on every validation. Registration is keyed by Scope.Name and double-registration is an error so misconfiguration fails loudly at boot rather than silently overwriting.

func NewRegistry

func NewRegistry() *Registry

NewRegistry constructs an empty registry.

func (*Registry) Lookup

func (r *Registry) Lookup(name string) (Scope, bool)

Lookup returns the Scope registered under the given name, or false if none.

func (*Registry) Register

func (r *Registry) Register(s Scope) error

Register adds a Scope. Returns an error if a scope with the same Name is already registered, or if the Scope is invalid (missing Name, missing routes, missing placeholder when ResourceIDInPath references one).

type RoutePattern

type RoutePattern struct {
	Method string // "GET", "POST", ... — case-insensitive on the wire, normalized to upper-case here.
	Path   string // e.g. "/api/oauth/per-user/flows/{id}"
}

RoutePattern is one (method, path) pair a Scope grants access to. The path may include the placeholder declared in the owning Scope's ResourceIDInPath field; at validation time the placeholder is substituted with the row's resource_id and the result is exact-matched against the request path.

type Scope

type Scope struct {
	Name             string
	AllowedRoutes    []RoutePattern
	ResourceIDInPath string // e.g. "{id}" — empty means routes have no resource_id substitution
	MaxTTL           time.Duration
}

Scope describes one class of temp token. The Name is the contract key stored on each row's scope column; AllowedRoutes + ResourceIDInPath define which requests the token authorizes; MaxTTL caps how long Mint will set expires_at. Invalidation is by row deletion — callers either let the expiry pass, the sweep worker collect, or explicitly Delete / DeleteByResourceID when the work the token authorized is complete.

type Service

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

Service mints and validates temp tokens. It composes the scope registry with the configstore-backed persistence layer; nothing else needs the row format directly.

func NewService

func NewService(store configstore.ConfigStore, registry *Registry) *Service

NewService constructs a Service backed by the given store and registry. The registry can be empty at construction time — scopes can be Register()'d before the first Validate call (in practice, at server startup).

func (*Service) DeleteByResourceID

func (s *Service) DeleteByResourceID(ctx context.Context, scope, resourceID string) (int64, error)

DeleteByResourceID removes every token row matching (scope, resourceID). Lifecycle owners call this when the underlying resource the token authorized is finished — e.g. the OAuth provider after a per-user flow terminates (success or failure) so the link stops working immediately instead of waiting for TTL. Returns the number of rows removed; both 0 and N are considered successful outcomes — callers should not treat 0 as an error.

func (*Service) DeleteExpired

func (s *Service) DeleteExpired(ctx context.Context, before time.Time) (int64, error)

DeleteExpired removes every token row whose expires_at is at or before `before`. Called by SweepWorker on its tick; callers passing time.Now() reap everything currently past its TTL. Returns the number of rows removed.

func (*Service) Mint

func (s *Service) Mint(ctx context.Context, scopeName, resourceID string, ttl time.Duration) (string, error)

Mint creates a new temp token under the given scope, bound to resourceID, with the requested TTL. The TTL must be > 0 and <= the scope's MaxTTL. The returned plaintext is the value the caller embeds in URLs or hands back to the user; it is never persisted in plaintext when encryption is enabled.

func (*Service) Registry

func (s *Service) Registry() *Registry

Registry exposes the underlying scope registry so callers can register scopes without holding a separate reference. Useful for transports that receive only the Service from server startup.

func (*Service) Validate

func (s *Service) Validate(ctx context.Context, plaintext, method, path string) (*ValidatedToken, error)

Validate authenticates the presented plaintext for the given request (method, path).

type SweepWorker

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

SweepWorker periodically deletes temp_tokens rows whose expires_at is in the past. It's the centralized expiry janitor for the temp-token table, mirroring the pattern used by PerUserOAuthSweepWorker for oauth_user_sessions.

Tokens are also deleted eagerly by lifecycle owners (see Service.DeleteByResourceID, called from OAuth flow terminal transitions). The sweeper exists to catch rows whose owning resource timed out before any terminal transition fired, or whose scope no longer participates in lifecycle-driven cleanup at all.

func NewSweepWorker

func NewSweepWorker(service *Service, logger schemas.Logger) *SweepWorker

NewSweepWorker constructs a worker bound to the given service. Returns nil when service is nil so callers can wire it unconditionally and check the result before starting.

func (*SweepWorker) SetSweepInterval

func (w *SweepWorker) SetSweepInterval(d time.Duration)

SetSweepInterval updates the sweep cadence (for testing).

func (*SweepWorker) Start

func (w *SweepWorker) Start(ctx context.Context)

Start begins the sweep loop in a background goroutine.

func (*SweepWorker) Stop

func (w *SweepWorker) Stop()

Stop gracefully stops the sweep worker. sync.Once guards against double-close panics from redundant shutdown paths.

type ValidatedToken

type ValidatedToken struct {
	ID         string
	Scope      string
	ResourceID string
}

ValidatedToken is the result of a successful Validate call. Callers attach these values to the request context so handlers can apply defense-in-depth checks.

Jump to

Keyboard shortcuts

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