Documentation
¶
Overview ¶
Package credentials provides secure (preferred) + plaintext (fallback) storage for Sting authentication material.
Isolation Guarantee ¶
This package is deliberately isolated from the user's real GitHub CLI (gh) configuration:
- We never mutate the GH_CONFIG_DIR environment variable.
- We never use github.com/cli/go-gh/v2/pkg/config for writing credentials. (That package only supports configuration via GH_CONFIG_DIR, which creates too much risk of accidental leakage or corruption of ~/.config/gh during development, testing, or error conditions.)
- All insecure (plaintext) credential storage is written exclusively to Sting's own hosts.yml using our own minimal implementation.
The design follows the same logical "hosts.<composite>" structure that gh uses for familiarity, but everything under Sting's own directory.
This package is intentionally internal. The public config package remains focused on query defaults and does not grow auth token concerns.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CredentialRef ¶
type CredentialRef struct {
Provider Provider
Host string
Username string // may be empty
Source Source
}
CredentialRef is a lightweight reference returned by List.
type KeyringBackend ¶
type KeyringBackend interface {
Set(service, user, secret string) error
Get(service, user string) (string, error)
Delete(service, user string) error
}
KeyringBackend is the minimal interface we need from a keyring implementation. This allows tests to inject a mock.
type Store ¶
type Store interface {
// Save persists a credential for the given provider + host.
// secureOnly=true forces an error instead of falling back to plaintext.
Save(ctx context.Context, provider Provider, host string, tok Token, secureOnly bool) (usedInsecure bool, err error)
// Load returns the best available token for (provider, host).
// It applies precedence rules (OAuth > PAT for the same provider+host)
// and returns the Source so callers (e.g. auth status) can produce
// appropriate messaging.
Load(ctx context.Context, provider Provider, host string) (tok Token, src Source, err error)
// Delete removes credentials for the given provider + host.
// It attempts to clean both secure and insecure locations.
Delete(ctx context.Context, provider Provider, host string) error
// List returns known (provider, host) combinations that have stored credentials.
// Useful for `auth status --all` or similar.
List(ctx context.Context) ([]CredentialRef, error)
}
Store is the main abstraction for credential lifecycle.
func New ¶
New creates a Store using the default discovery order: 1. Try secure keyring via our internal/keyring wrapper. 2. Fall back to our own hosts.yml (no env var mutation, no risk to gh config). The returned Store is safe for concurrent use.
func NewInsecure ¶
NewInsecure creates a Store rooted at Sting's config directory that never uses the system keyring: credentials are always written to the plaintext hosts.yml. This backs the `--insecure-storage` flag so it deterministically forces file storage instead of merely permitting fallback.
func WithFilePath ¶
WithFilePath returns a file-only Store that uses a specific directory for plaintext storage (primarily for hermetic tests). It never consults the system keyring and never touches GH_CONFIG_DIR, so test behavior is deterministic regardless of whether a real keyring is available on the host.
func WithKeyringForTest ¶
func WithKeyringForTest(backend KeyringBackend, configDir string) Store
WithKeyringForTest returns a Store that uses the provided KeyringBackend for the secure path (useful for hermetic tests). A nil backend selects file-only mode (no keyring), matching WithFilePath. The insecure path uses our own file-based storage under the given directory.
type Token ¶
type Token struct {
Type TokenType
AccessToken string
RefreshToken string // may be empty for some providers
Expiry time.Time // zero value means no expiry / does not expire
Username string // best-effort; populated after successful auth
}
Token represents a stored credential. For PATs, only AccessToken is populated. For OAuth, the full set may be present.