credentials

package
v0.0.7 Latest Latest
Warning

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

Go to latest
Published: Jul 12, 2026 License: MIT Imports: 10 Imported by: 0

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.
  • We never shell out to `gh auth token`, and we never silently adopt an ambient GitHub token (GH_TOKEN / GITHUB_TOKEN or the gh CLI config file). Consulting those ambient sources is strictly opt-in via STING_ALLOW_AMBIENT_GITHUB_TOKEN, so a stored Sting credential is never transparently replaced by whatever identity happens to live in the surrounding shell.

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 Provider

type Provider string

Provider identifies a source control system.

const (
	ProviderGitHub Provider = "github"
	ProviderGitLab Provider = "gitlab"
)

type Source

type Source string

Source describes where a token came from (for status + messaging).

const (
	SourceKeyring Source = "keyring"
	SourceFile    Source = "file"
	SourceEnv     Source = "environment" // legacy PATs from STING_TOKEN etc.
	SourceConfig  Source = "config"      // legacy PATs from config file (viper)
)

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

func New() (Store, error)

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

func NewInsecure() (Store, error)

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.

type Token

type Token struct {
	Type        TokenType
	AccessToken string
	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.

type TokenType

type TokenType string

TokenType distinguishes the kind of credential.

const (
	TokenTypeOAuth TokenType = "oauth"
	TokenTypePAT   TokenType = "pat"
)

Jump to

Keyboard shortcuts

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