Documentation
¶
Overview ¶
Package auth stores the CLI Privy credential.
File store (Linux and other non-macOS platforms): one JSON file per profile under the config dir, mode 0600. The file is not encrypted; it is protected by file permissions only, like ~/.ssh keys without a passphrase or the gh CLI's fallback token file. Users who want encryption at rest opt into the desktop keyring store instead.
Credentials written by older releases were sealed with a passphrase (version 1). They are still recognized: metadata stays readable, secrets return ErrLegacyCredential until MigrateLegacy converts the file once.
Index ¶
- Constants
- Variables
- func CheckStore(st Store) error
- func CheckStoreWithInteraction(st Store, interactive, gui bool) error
- func DeletePrivy(profile string) error
- func DeletePrivyIn(st Store, profile string) error
- func DeletePrivyWithInteraction(profile string, interactive, gui bool) error
- func KeychainStatus(status int, locked bool) error
- func LegacyNeedsPassphrase(profile string) (bool, error)
- func LoadPrivy(profile string) (*Metadata, *Secrets, error)
- func LoadPrivyIn(st Store, profile string) (*Metadata, *Secrets, error)
- func LoadPrivyWithInteraction(profile string, interactive, gui bool) (*Metadata, *Secrets, error)
- func LockProfile(profile string) (func(), error)
- func PrivyPath(profile string) (string, error)
- func SavePrivy(profile string, md Metadata, s Secrets) error
- func SavePrivyIn(st Store, profile string, md Metadata, s Secrets) error
- func SavePrivyInWithInteraction(st Store, profile string, md Metadata, s Secrets, interactive, gui bool) error
- func UseKeyringForTest(m *MemoryKeyring) (restore func())
- type MemoryKeyring
- type Metadata
- type Secrets
- type Store
Constants ¶
const KindPrivy = "privy"
KindPrivy marks an Accounts session credential minted from a Privy login.
Variables ¶
var ErrBadPassphrase = errors.New("credential decryption failed (wrong passphrase or corrupted file)")
ErrBadPassphrase means a legacy credential could not be decrypted.
var ErrKeychainAccessDenied = errors.New("macOS Keychain denied this binary access to the credential")
var ErrKeychainCanceled = errors.New("macOS Keychain authorization was canceled")
var ErrKeychainLocked = errors.New("macOS login Keychain is locked")
ErrKeychainUnavailable distinguishes a locked, denied, or unavailable native store from a missing credential. It must never trigger an encrypted-file fallback.
var ErrKeyringUnsupported = errors.New("the keyring credential store is only supported on Linux")
ErrKeyringUnsupported means the Secret Service store was requested on a platform that does not offer it.
var ErrLegacyCredential = errors.New("credential uses the old passphrase-protected format")
ErrLegacyCredential means the credential still uses the passphrase-sealed format of older releases and must be converted with MigrateLegacy.
var ErrNoCredentials = errors.New("no stored credentials")
ErrNoCredentials means no enrollment is stored for the profile.
var ErrUnsupportedPlatform = errors.New("native Keychain migration requires macOS with CGO")
Functions ¶
func CheckStore ¶
CheckStore verifies that a native store is reachable before anything is authorized remotely, so login can fail early with a clear error. The file store is always available.
func CheckStoreWithInteraction ¶
CheckStoreWithInteraction is CheckStore that may unlock a locked macOS Keychain in the terminal before anything is authorized remotely.
func DeletePrivy ¶
DeletePrivy removes the credential from the profile's recorded store.
func DeletePrivyIn ¶
DeletePrivyIn removes the credential from an explicit store. A missing credential is not an error.
func DeletePrivyWithInteraction ¶
DeletePrivyWithInteraction is DeletePrivy with one user-authorized macOS retry.
func KeychainStatus ¶
KeychainStatus classifies the Security framework statuses returned by a generic-password query. An interaction failure is ambiguous until the default Keychain's lock state has been checked.
func LegacyNeedsPassphrase ¶
LegacyNeedsPassphrase reports whether a profile's legacy credential was sealed with a passphrase. It returns ErrNoCredentials, or an error when the credential is not in the legacy format.
func LoadPrivy ¶
LoadPrivy loads metadata and secrets from the profile's recorded store. A file credential from an older release returns ErrLegacyCredential.
func LoadPrivyIn ¶
LoadPrivyIn reads metadata and secrets from an explicit store.
func LoadPrivyWithInteraction ¶
LoadPrivyWithInteraction permits one user-authorized macOS retry.
func LockProfile ¶
LockProfile serializes credential read-modify-write operations across CLI processes. Callers must hold it from loading through saving/deleting a record. Atomic rename alone cannot prevent a stale writer from destroying a new key.
func PrivyPath ¶
PrivyPath returns the Privy credential file for a profile. It lives in a separate directory so no profile name can collide with it.
func SavePrivy ¶
SavePrivy stores the Privy (Accounts session) credential in the profile's recorded store.
func SavePrivyIn ¶
SavePrivyIn writes the credential to an explicit store (login, migrate).
func SavePrivyInWithInteraction ¶
func SavePrivyInWithInteraction(st Store, profile string, md Metadata, s Secrets, interactive, gui bool) error
SavePrivyInWithInteraction is SavePrivyIn with one user-authorized macOS retry.
func UseKeyringForTest ¶
func UseKeyringForTest(m *MemoryKeyring) (restore func())
UseKeyringForTest swaps the Secret Service backend and returns a restore function. Tests only.
Types ¶
type MemoryKeyring ¶
type MemoryKeyring struct {
Unavailable bool
// contains filtered or unexported fields
}
MemoryKeyring is an in-memory Secret Service stand-in for tests. It is never selected unless a test installs it with UseKeyringForTest.
func (*MemoryKeyring) Get ¶
func (m *MemoryKeyring) Get(k key) ([]byte, error)
func (*MemoryKeyring) Len ¶
func (m *MemoryKeyring) Len() int
func (*MemoryKeyring) Put ¶
func (m *MemoryKeyring) Put(k key, v []byte) error
func (*MemoryKeyring) Remove ¶
func (m *MemoryKeyring) Remove(k key) error
type Metadata ¶
type Metadata struct {
Profile string `json:"profile"`
Network string `json:"network"`
APIURL string `json:"api_url"`
AgentAddress string `json:"agent_address"`
AccountAddress string `json:"account_address"`
CreatedAt string `json:"created_at"`
Status string `json:"status"`
Kind string `json:"kind,omitempty"`
PrivyUserID string `json:"privy_user_id,omitempty"`
AccountsUserID string `json:"accounts_user_id,omitempty"`
WalletAddress string `json:"wallet_address,omitempty"`
SessionID string `json:"session_id,omitempty"`
PrivyAppID string `json:"privy_app_id,omitempty"`
PrivyWalletID string `json:"privy_wallet_id,omitempty"`
AccessExpiresAt string `json:"access_expires_at,omitempty"`
SessionExpiresAt string `json:"session_expires_at,omitempty"`
Generation uint64 `json:"generation,omitempty"`
}
Metadata is the non-secret part of a credential.
func LoadPrivyMetadata ¶
LoadPrivyMetadata returns non-secret metadata. For native stores (Keychain, Secret Service) the metadata lives in the same item as the secrets.
func LoadPrivyMetadataIn ¶
LoadPrivyMetadataIn reads non-secret metadata from an explicit store.
func MigrateLegacy ¶
MigrateLegacy decrypts a profile's legacy file credential with pass (nil for an unprotected one) and rewrites it in the plain format at the same path. The caller holds LockProfile. A wrong passphrase returns ErrBadPassphrase and leaves the file untouched.
type Secrets ¶
type Secrets struct {
// SessionToken is the Accounts session token.
SessionToken string `json:"session_token,omitempty"`
AccessToken string `json:"access_token,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
}
Secrets are the tokens that grant access.
type Store ¶
type Store string
Store names where a profile's credential lives.
const ( // StoreFile is a plain 0600 file (default on Linux and other non-macOS // platforms). StoreFile Store = "file" // StoreKeyring is the freedesktop Secret Service (GNOME Keyring, KWallet, // KeePassXC). Opt-in, Linux only. StoreKeyring Store = "keyring" // StoreKeychain is the native macOS Keychain (always used on macOS). StoreKeychain Store = "keychain" )
func DefaultStore ¶
func DefaultStore() Store
DefaultStore is the store used when a profile records none.
func ParseStore ¶
ParseStore validates a user-supplied store name (flag or OKU_CREDENTIAL_STORE). Empty means the platform default.