keychainauth

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: May 19, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package keychainauth is the client-side integration with the keychain-auth daemon.

keychain-auth is a standalone security daemon that mediates all secret reads between AgentSecrets and the OS keychain. It verifies process identity (binary hash + PID) before granting access, and enforces namespace isolation so only secrets in the {project_id}:{environment}:{key} format are readable.

This package owns:

  • The Unix socket session lifecycle (init, request, close)
  • Auto-setup of keychain-auth (install, register, start)
  • User-facing error messages for rejection/denial

This package does NOT own:

  • Writing secrets to the OS keychain (pkg/keyring handles that)
  • keychain-auth's internal verification logic
  • The daemon process itself

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AutoSetup

func AutoSetup() error

AutoSetup performs the full keychain-auth setup sequence:

  1. Ensures keychain-auth is installed (installs if missing)
  2. Registers the AgentSecrets binary hash with keychain-auth
  3. Ensures the daemon is running (starts if not)

This is designed to be invisible to the user during normal operation. When called during an upgrade (first secret read after update), the caller should display a spinner and explanatory message.

Returns nil if everything is ready, or an error describing what failed.

func Close

func Close()

Close tears down the Unix socket connection to keychain-auth. Safe to call multiple times. Should be deferred from main or called in a signal handler.

func EnsureDaemonRunning

func EnsureDaemonRunning(keychainAuthPath string) error

EnsureDaemonRunning checks if the keychain-auth daemon is running by probing the socket. If the socket doesn't exist, it attempts to start the daemon using the platform's service manager.

func EnsureInstalled

func EnsureInstalled() (string, error)

EnsureInstalled checks if keychain-auth is in PATH. If not found, attempts to install it via the platform's package manager. Returns the absolute path to the keychain-auth binary.

func EnsureRegistered

func EnsureRegistered(keychainAuthPath string) error

EnsureRegistered registers the current AgentSecrets binary with keychain-auth. This tells keychain-auth "this binary is trusted" by recording its SHA-256 hash.

On upgrade, the new hash must be registered before the first secret read. This function is idempotent — re-registering the same hash is a no-op.

func GetSecret

func GetSecret(projectID, environment, key string) (string, error)

GetSecret sends a SECRET_REQUEST to keychain-auth and returns the plaintext value.

The key is the bare secret name (e.g., "OPENAI_API_KEY"). The projectID and environment are sent alongside it — keychain-auth constructs the full {projectID}:{environment}:{key} keychain key internally.

The returned value should be used immediately and not stored in any persistent variable, struct field, log, or error message.

func Init

func Init() error

Init connects to the keychain-auth daemon and performs the SESSION_INIT handshake.

This must be called once per process lifetime before any GetSecret() call. The session token is stored in memory only. The binary hash is computed fresh on every call — it is never cached between invocations.

If the daemon is not running, Init returns a *DaemonNotRunningError with a user-facing message explaining how to fix it.

func IsAvailable

func IsAvailable() bool

IsAvailable checks whether the keychain-auth socket file exists on disk. This is a quick probe — it does not attempt a connection.

func IsInitialized

func IsInitialized() bool

IsInitialized returns true if a session has been successfully established.

func RestartDaemon

func RestartDaemon() error

RestartDaemon kills any running keychain-auth daemon and starts a fresh one. This is needed after re-registering a binary so the daemon picks up the new hash.

func SocketPath

func SocketPath() string

SocketPath returns the keychain-auth Unix socket path. It uses platform-specific, user-writable directories to avoid permission issues.

func UserMessage

func UserMessage(err error) string

UserMessage returns the full user-facing error text for a rejection reason. These messages are specified in the integration spec and should not be changed without updating the spec.

Types

type DaemonNotRunningError

type DaemonNotRunningError struct {
	SocketPath string
	Cause      error
}

DaemonNotRunningError is returned when the keychain-auth socket does not exist or the connection is refused.

func (*DaemonNotRunningError) Error

func (e *DaemonNotRunningError) Error() string

func (*DaemonNotRunningError) Unwrap

func (e *DaemonNotRunningError) Unwrap() error

type SecretDeniedError

type SecretDeniedError struct {
	Key    string
	Reason rejectReason
}

SecretDeniedError is returned when keychain-auth denies a SECRET_REQUEST.

func (*SecretDeniedError) Error

func (e *SecretDeniedError) Error() string

type SessionRejectedError

type SessionRejectedError struct {
	Reason rejectReason
}

SessionRejectedError is returned when keychain-auth rejects a SESSION_INIT request. The Reason field matches the protocol's RejectReason constants.

func (*SessionRejectedError) Error

func (e *SessionRejectedError) Error() string

func (*SessionRejectedError) IsHashMismatch

func (e *SessionRejectedError) IsHashMismatch() bool

IsHashMismatch returns true if the rejection was due to a binary hash mismatch.

func (*SessionRejectedError) IsPathMismatch added in v1.2.0

func (e *SessionRejectedError) IsPathMismatch() bool

IsPathMismatch returns true if the rejection was due to a binary path mismatch (e.g. Homebrew upgrade).

Jump to

Keyboard shortcuts

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