tokenstore

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package tokenstore provides a pluggable credential store shared by the entiredb and entire-core CLIs.

By default it delegates to the OS keyring (macOS Keychain, Linux Secret Service, etc.). Set ENTIRE_TOKEN_STORE=file to use a JSON file instead, which is useful in CI environments that lack a keyring daemon.

When using the file backend the tokens are stored in $ENTIRE_TOKEN_STORE_PATH (default: tokens.json in the per-user config directory — see internal/entireclient/userdirs).

Service-name conventions:

  • "entire:<cluster-host>" — entiredb cluster login tokens
  • "entire-core:<core-base-url>" — entire-core control-plane tokens
  • "<service>:refresh" — refresh-token entry paired with the corresponding access-token service

Index

Constants

View Source
const (
	ClusterKeyringPrefix = "entire:"      // entiredb cluster-issued tokens
	CoreKeyringPrefix    = "entire-core:" // entire-core control-plane tokens
)

Keyring service-name prefixes. Tokens are filed under whichever issuer vouched for them, so a JWT obtained via an entire-core login flow lives at "entire-core:<base-url>" regardless of which CLI wrote it. Two CLIs sharing this prefix on the same machine read each other's writes.

View Source
const (
	BackendEnvVar = "ENTIRE_TOKEN_STORE"
	PathEnvVar    = "ENTIRE_TOKEN_STORE_PATH"
)

BackendEnvVar selects the credential backend: set to "file" to use the JSON file store instead of the OS keyring. PathEnvVar overrides where the file store lives (default: tokens.json in the per-user config directory). Exported so user-facing guidance (e.g. login's headless hint) names the same variables this package actually reads.

View Source
const TokenExpirationBuffer = 5 * time.Minute

TokenExpirationBuffer is how long before expiration we should refresh.

View Source
const TokenExpirationSeparator = "|"

TokenExpirationSeparator separates the token from its expiration timestamp. Format: "token|expires_at_unix"

Variables

View Source
var ErrNotFound = keyring.ErrNotFound

ErrNotFound is returned when a credential is not present in the store.

Functions

func BackendDescription added in v0.9.0

func BackendDescription() string

BackendDescription names the credential backend the current environment resolves to, for user-facing provenance lines (e.g. `entire auth status`). It mirrors resolveBackendLocked's env semantics — the production resolution — rather than introspecting the live backend, so test-only overrides don't leak into user-facing wording.

func CoreKeyringService

func CoreKeyringService(coreURL string) string

CoreKeyringService returns the service name for tokens issued by entire-core. coreURL is the base URL of the issuer; trailing slashes are normalized away so callers don't have to.

func DecodeTokenWithExpiration

func DecodeTokenWithExpiration(encoded string) (token string, expiresAt time.Time)

DecodeTokenWithExpiration decodes a token that may have an expiration timestamp. Returns the token and expiration time. If no expiration is encoded, returns the token as-is and a zero time.

func Delete

func Delete(service, user string) error

Delete removes a credential.

func EncodeTokenWithExpiration

func EncodeTokenWithExpiration(token string, expiresIn int64) string

EncodeTokenWithExpiration encodes a token with its expiration time as a "token|expires_at_unix" suffix. Callers must pass a positive expiresIn — the encoded suffix is the contract that tells future readers when to refresh, and a zero/negative TTL would record an immediately-expired token.

func FileBackendPath added in v0.9.0

func FileBackendPath() string

FileBackendPath resolves where the file backend stores (or would store) tokens: PathEnvVar when set, else tokens.json in the per-user config directory. Exported so user-facing guidance can name the concrete path.

func FileBackendSelected added in v0.9.0

func FileBackendSelected() bool

FileBackendSelected reports whether the environment selects the file backend — the single predicate shared by backend resolution, provenance wording, and login's headless hint, so they can never disagree.

func Get

func Get(service, user string) (string, error)

Get retrieves a credential.

func IsTokenExpiredOrExpiring

func IsTokenExpiredOrExpiring(expiresAt time.Time) bool

IsTokenExpiredOrExpiring checks if a token is expired or will expire soon. A zero expiresAt is treated as "unknown, assume expired".

func RefreshService added in v0.7.4

func RefreshService(service string) string

RefreshService returns the paired refresh-token service name for an access-token service, following the "<service>:refresh" convention documented in this package's service-name conventions. Callers store the raw refresh token under (RefreshService(service), user) alongside the access token at (service, user).

func Set

func Set(service, user, password string) error

Set stores a credential.

func UseFailingBackendForTesting added in v0.7.4

func UseFailingBackendForTesting(path string, failSet func(service, user string) bool) func()

UseFailingBackendForTesting wraps a file backend so Set returns an error for any (service, user) pair where failSet reports true; all other operations behave normally. It lets tests exercise partial-write failure paths (e.g. the refresh-then-access ordering in contextTokenStore) without exposing the unexported store interface. Returns a cleanup function.

func UseFailingDeleteBackendForTesting added in v0.7.7

func UseFailingDeleteBackendForTesting(path string, failDelete func(service, user string) bool) func()

UseFailingDeleteBackendForTesting is the delete-side analogue: Delete returns an error for any (service, user) pair where failDelete reports true. Used to test that logout treats credential deletion as part of its success contract.

func UseFailingGetBackendForTesting added in v0.7.4

func UseFailingGetBackendForTesting(path string, failGet func(service, user string) bool) func()

UseFailingGetBackendForTesting is the read-side analogue: Get returns an error for any (service, user) pair where failGet reports true. Used to test that callers surface a real store failure rather than swallowing it.

func UseFileBackendForTesting

func UseFileBackendForTesting(path string) func()

UseFileBackendForTesting points the package-level token store at a per-test JSON file and returns a cleanup function that restores the previous backend (re-resolving on next use). It serializes against concurrent Get/Set/Delete calls via the same mutex they use, so it is safe to call from any test even if other goroutines are mid-call.

Each call replaces the active backend; tests that invoke this from parallel subtests will trample each other and should arrange their own per-subtest paths if they actually need isolation.

Types

This section is empty.

Jump to

Keyboard shortcuts

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