keyring

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 11, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package keyring provides secure storage for the credential encryption key.

Platform requirements:

  • macOS: Uses Keychain via Security framework (works out of the box)
  • Linux: Requires libsecret (GNOME), kwallet (KDE), or pass (CLI)
  • Windows: Uses Windows Credential Manager (works out of the box)
  • Headless/CI: Automatically falls back to file-based storage at ~/.moat/encryption.key

The package attempts to store keys in the system keychain first for better security. If the keychain is unavailable (e.g., in CI, headless servers, or containers), it silently falls back to file-based storage with restricted permissions (0600).

Concurrency: All key creation operations are protected by a global file lock (~/.moat/key.lock) to prevent race conditions when multiple processes attempt to create a key simultaneously. Both keychain and file backends check for existing keys before writing to avoid overwriting keys created by other processes. On Windows, file locking is a no-op, but Windows Credential Manager is the primary backend and concurrent first-run scenarios in file fallback are rare.

Security: The file backend will refuse to read keys from files with overly permissive permissions (anything other than 0600). If permissions have been changed, the key may have been compromised and should be rotated.

Index

Constants

View Source
const (
	// ServiceName is the default keyring service identifier.
	// Can be overridden with MOAT_KEYRING_SERVICE environment variable for test isolation.
	ServiceName = "moat"
	// AccountName is the keyring account identifier.
	AccountName = "encryption-key"
	// KeySize is the required encryption key size in bytes.
	KeySize = 32
)

Variables

View Source
var ErrInsecurePermissions = errors.New("key file has insecure permissions")

ErrInsecurePermissions is returned when the key file has overly permissive permissions.

View Source
var ErrNoHomeDirectory = errors.New("could not determine home directory for secure key storage")

ErrNoHomeDirectory is returned when the home directory cannot be determined.

Functions

func DefaultKeyFilePath

func DefaultKeyFilePath() (string, error)

DefaultKeyFilePath returns the default path for the fallback key file. The path is always absolute to ensure consistent key storage across different working directories. The service name (from MOAT_KEYRING_SERVICE or default "moat") is included in the filename to support test isolation. Returns an error if the home directory cannot be determined, as using temp directories is insecure (may be world-readable or cleared on reboot).

func DeleteKey

func DeleteKey() error

DeleteKey removes the encryption key from all storage backends. This is useful for testing cleanup and reset scenarios.

func GetOrCreateKey

func GetOrCreateKey() ([]byte, error)

GetOrCreateKey retrieves the encryption key from keychain or file, generating a new one if needed. The entire operation is protected by a global file lock to prevent race conditions when multiple processes attempt to create a key simultaneously.

Types

type Backend

type Backend interface {
	Get() ([]byte, error)
	Set(key []byte) error
	Delete() error
	Name() string
}

Backend defines the interface for key storage.

Jump to

Keyboard shortcuts

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