credentials

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package credentials is a small local store for provider API keys, so Kram's accounts screen has somewhere to put a key the user pastes in instead of asking them to export an env var by hand every session (the friction that motivated this package in the first place — env vars only take effect in the exact shell they were exported in, which is an easy thing to get wrong).

This is OS-permission-based protection (like gh/aws CLI's own credential files), not encryption at rest — there's no key-management story for a local single-user CLI tool that would make "encrypted JSON readable only by code that also ships the decryption key" meaningfully safer than a 0600 file. Treat it the same way you'd treat ~/.aws/credentials.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type OAuthToken

type OAuthToken struct {
	Access    string    `json:"access"`
	Refresh   string    `json:"refresh"`
	ExpiresAt time.Time `json:"expires_at"`
}

OAuthToken is a refreshable credential — a short-lived access token plus the refresh token that can mint a new one, as returned by Anthropic's and OpenAI's browser-login flows (internal/oauthflow). Unlike the plain keys map, these expire and must be refreshed before use; see Store.Resolve.

type Store

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

Store is a flat env-var-name -> API-key map, persisted as JSON, plus a separate map of refreshable OAuth tokens (see OAuthToken) for accounts connected via a browser-login subscription flow rather than a pasted developer API key.

func Load

func Load() (*Store, error)

Load reads the credentials file (kramhome.Path("credentials.json")) and the OAuth token file (kramhome.Path("oauth_tokens.json")), or leaves either empty if it doesn't exist yet — a missing file is the normal first-run state, not an error. The two are kept in separate files rather than one so the well-established plain-key format and its existing callers are never touched by the OAuth addition.

func (*Store) All

func (s *Store) All() map[string]string

All returns every stored env-var -> key pair (plain keys only, not OAuth tokens).

func (*Store) Delete

func (s *Store) Delete(envVar string) error

Delete removes a stored key and persists immediately.

func (*Store) DeleteOAuth

func (s *Store) DeleteOAuth(envVar string) error

DeleteOAuth removes a stored OAuth token and persists immediately.

func (*Store) Get

func (s *Store) Get(envVar string) string

Get returns the stored key for envVar, or "" if none is set. This never looks at OAuth tokens — a caller that needs a currently-valid credential regardless of which kind was stored should use Resolve instead.

func (*Store) GetOAuth

func (s *Store) GetOAuth(envVar string) (OAuthToken, bool)

GetOAuth returns the stored OAuth token for envVar and whether one exists — note this can be expired; callers that need a currently-valid token should use Resolve, which refreshes automatically.

func (*Store) Resolve

func (s *Store) Resolve(ctx context.Context, envVar string, refresh func(ctx context.Context, refreshToken string) (OAuthToken, error)) (string, error)

Resolve returns a currently-valid credential for envVar. If a stored OAuth token exists and isn't within refreshSkew of expiring, its access token is returned as-is; if it's expired or about to be, refresh is called with the stored refresh token, the result is persisted (via SetOAuth) before returning, and — since some providers don't rotate the refresh token on every refresh — an empty Refresh in the result is treated as "unchanged" rather than discarding the still-valid one. If no OAuth token is stored for envVar at all, this falls back to the plain Get(envVar) value, so callers that don't care which kind of credential is configured can always call Resolve.

func (*Store) Set

func (s *Store) Set(envVar, key string) error

Set stores a key for envVar and persists immediately — the accounts screen has no separate "save" step, so a key is durable the moment it's entered.

func (*Store) SetOAuth

func (s *Store) SetOAuth(envVar string, tok OAuthToken) error

SetOAuth stores an OAuth token for envVar and persists immediately.

Jump to

Keyboard shortcuts

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