tokenstore

package
v0.38.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package tokenstore keeps the forge credential in the operating system's secret store, keyed by the forge's host, so a local aeman — `aeman mcp` under an MCP client, `aeman serve` on a laptop — needs no token in its environment or in a client configuration file. `aeman login` writes the item; every command reads it as one source among several.

Index

Constants

View Source
const Service = "aeman"

Service is the secret store's service name for every item aeman writes. The account is the forge host, so one machine holds one token per forge instance.

Variables

View Source
var ErrNotFound = keychain.ErrNotFound

ErrNotFound is a host with no token stored, re-exported so a caller tells that apart from every other failure without importing the library behind this package.

It is the only distinction the store can actually make. On macOS every operation goes through /usr/bin/security (see open), whose only classified outcome is exit 44 for a missing item; everything else — a locked keychain over SSH, a denied partition — arrives as the tool's own error text. So a caller has two cases, "nothing stored here" and "something went wrong, and here is what the tool said".

Functions

This section is empty.

Types

type CLI

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

CLI is the secret store standing in for the forge's command-line tool: the token `aeman login` put there, and the person the forge says that token belongs to. It is the peer of ghcli.TokenSource and glabcli.CLI, and is asked before either of them.

func NewCLI

func NewCLI(store Store, f forge.Forge, client *http.Client) *CLI

NewCLI returns the store's forge.CLI for the token held under the forge's own host — the account is not a separate argument, so it cannot be given one that disagrees with the forge asked about the token's owner. A nil client is one bounded by forgeTimeout.

func (*CLI) Login

func (c *CLI) Login(ctx context.Context) (string, error)

Login is who the forge says the stored token belongs to, which need not be whoever gh or glab is signed in as on this machine — a stored bot token belongs to the bot, and that is who its commits are by. It is asked once per token, not once per process: this is on the path of every request in the local mode, but `aeman login` in another terminal replaces the token under a running server, and the owner asked about has to be the owner of the token now in use.

func (*CLI) Token

func (c *CLI) Token(context.Context) (string, error)

Token is the stored token, with the store's own error untouched — the caller decides what a failure means, and the only distinction the store can offer it is ErrNotFound against everything else.

It is cached for tokenTTL because the server asks for it on every request in the local mode, and reading it runs the platform's secret tool — tens of milliseconds, behind a process-wide lock. A read that found nothing is not cached, so a token appearing under this source while the process runs is picked up at once rather than after the window. That is about THIS source only: a chain that has already elected a lower-priority one stays with it until it empties, so `aeman login` on a machine where gh answers takes effect at the next start.

func (*CLI) TokenAndLogin

func (c *CLI) TokenAndLogin(ctx context.Context) (string, string, error)

TokenAndLogin answers both from ONE read of the store, so a caller needing the pair cannot catch this source between two tokens of its own — the window Token-then-Login leaves when the cache lapses in between and the item has changed since.

type Store

type Store interface {
	Get(host string) (string, error)
	Set(host, token string) error
	Delete(host string) error
}

Store is the secret store as aeman uses it: one token per forge host. Get reports a host with no token as ErrNotFound; Delete is idempotent.

func Open

func Open(log *slog.Logger) Store

Open returns the operating system's secret store.

Directories

Path Synopsis
Package tokenstoretest provides an in-memory tokenstore.Store for tests of the packages that read a credential — the commands and the server — so a test never touches the machine's own secret store.
Package tokenstoretest provides an in-memory tokenstore.Store for tests of the packages that read a credential — the commands and the server — so a test never touches the machine's own secret store.

Jump to

Keyboard shortcuts

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