token

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2026 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Overview

Package token is the console-facing TokenService handler: the typed management surface for the daemon's auth tokens. It LISTS, REVOKES, and MINTS tokens, but the mint path is narrow: only the two console scopes (CONSOLE and CONSOLE_READ) are mintable, and OPERATOR and CONNECTOR are refused (mintableScope), so a compromised browser session can never forge an /mcp credential or reach the operator token. A browser-minted token is bounded further still - it always expires and its TTL is clamped (CreateToken, consoleTokenExpiry) - so an XSS cannot mint a durable, never- expiring credential. It is a SECOND door onto the exact stores the CLI and the share flow already use - the on-disk connector store (internal/auth) and the daemon's in-memory share manager (internal/share) - never a second store of its own. Two tokens are deliberately beyond its reach: the OPERATOR token (the built-in cli credential, auto-seeded on first daemon start) and any renew/extend operation (a token is reminted via the CLI, never extended). The operator boundary is by CONSTRUCTION, not convention: the cli token lives in a store this handler never opens (auth.Load, distinct from the connector store), so ListTokens cannot enumerate it and RevokeToken keyed on its fingerprint falls through to the connector store and returns NotFound, leaving the cli token file untouched - the management UI can never lock the operator out of the daemon it authenticates against. TestOperatorTokenInvisibleAndImmutable proves it. The daemon mounts it on the loopback listener behind a CLI-TOKEN-ONLY bearer guard (auth.VerifyCLIBearer): token management is operator-tier, so a connector token - a mere MCP-client credential - is rejected at the guard and can never revoke credentials. It is NEVER mounted on the LAN share listener and never served unauthenticated.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Service

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

Service implements tokenv1alpha1connect.TokenServiceHandler over the shared connector store and the daemon's share manager. loadStore is injectable so the list/revoke mapping is unit-testable without a live daemon; it defaults to the real store loader.

func NewService

func NewService(mgr *share.Manager) *Service

NewService builds a TokenService handler that manages connector tokens through the shared on-disk store and the share token through mgr. It takes the CONCRETE *share.Manager (not the shareView interface) on purpose: a typed-nil manager passed straight into an interface field would be non-nil at the interface level - the classic typed-nil trap - and every `s.share != nil` guard would then pass and nil-deref. Converting only a non-nil manager keeps "no share feature" a true nil, so a nil mgr simply means no share token is ever listed or revoked.

func (*Service) CreateToken added in v0.4.0

CreateToken mints a console or viewer token and returns its secret once. The token always expires: a zero, absent, or past expire_time is refused, and one further out than maxConsoleTokenTTL is clamped to that ceiling, so a credential minted from the browser origin can never be made permanent (see consoleTokenExpiry).

There is no caller-class check here on purpose. The service is mounted behind BearerGuard(VerifyCLIBearer) (see internal/daemon), so only the operator tier can reach this method at all, and that tier already dominates both scopes it may mint - there is no escalation to check for. What IS checked is the requested scope, because "operator may mint anything" is not the same claim as "anything may be minted from a browser": OPERATOR is refused because it lives in a file this service never opens, and CONNECTOR because an /mcp bearer must not be mintable from the console surface.

func (*Service) ListTokens

ListTokens returns every connector token plus the active share token, each as a secret-free TokenInfo. The cli token is deliberately absent: it is neither read from nor exposed here, so this surface cannot reveal or target it. last_used is left unset - see the package note; there is no cheap seam to record it.

func (*Service) RevokeToken

RevokeToken removes the token matching identifier. It checks the active share token first: when identifier names it, CloseIf revokes the token AND tears the LAN listener down (the share's own teardown, not a reimplementation), but ONLY if that exact share is still live - if a supersede won the race between Active and CloseIf, the revoke reports NotFound rather than tearing down whatever share replaced it. Otherwise it falls to the connector store. The cli token is never consulted, so it cannot be revoked here even if its fingerprint is supplied.

Jump to

Keyboard shortcuts

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