Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsDBEncrypted ¶
IsDBEncrypted checks whether a SQLite database file is encrypted. An encrypted DB will not have the standard "SQLite format 3" magic header.
func KMSConfigFromEnv ¶ added in v0.7.0
KMSConfigFromEnv reads KMS KEK configuration from environment variables. Returns nil config and empty provider name if LANGO_KMS_PROVIDER is not set.
Provider-specific env vars:
aws-kms/gcp-kms: LANGO_KMS_KEY_ID, LANGO_KMS_REGION, LANGO_KMS_ENDPOINT
azure-kv: + LANGO_KMS_AZURE_VAULT_URL, LANGO_KMS_AZURE_KEY_VERSION
pkcs11: LANGO_KMS_PKCS11_MODULE, LANGO_KMS_PKCS11_SLOT_ID,
LANGO_KMS_PKCS11_KEY_LABEL, LANGO_PKCS11_PIN
func OpenDatabaseReadOnly ¶ added in v0.7.0
func OpenDatabaseReadOnly(dbPath, encryptionKey string, rawKey bool, cipherPageSize int) (*ent.Client, *sql.DB, error)
OpenDatabaseReadOnly opens the SQLite/SQLCipher database in read-only mode without invoking ent schema migration.
Contract:
- Read-only: the connection uses `file:path?mode=ro`, so writes fail at the SQLite layer.
- No schema migration: `client.Schema.Create` is not called, so this function can be used by commands that must not modify the DB.
- No prompt: the caller is responsible for obtaining the encryption key non-interactively. Failure to open returns an error; callers must gracefully degrade (zero counts, "unavailable" fields).
rawKey semantics match openDatabase: rawKey=true uses `PRAGMA key = "x'<hex>'"`, rawKey=false uses `PRAGMA key = '<passphrase>'`, and an empty encryptionKey skips the PRAGMA entirely (plaintext).
The returned *ent.Client shares the underlying *sql.DB so callers should Close() the client (which closes the DB) when done.
Types ¶
type Options ¶
type Options struct {
// LangoDir is the lango data directory (default: ~/.lango/).
// When set, envelope.json, keyfile (if default), and skills/ are placed under this path.
// Primarily used by tests to isolate state in t.TempDir().
LangoDir string
// DBPath is the SQLite database path (default: <LangoDir>/lango.db).
DBPath string
// KeyfilePath is the path to the passphrase keyfile (default: <LangoDir>/keyfile).
KeyfilePath string
// ForceProfile overrides the active profile selection.
ForceProfile string
// KeepKeyfile prevents the keyfile from being shredded after crypto initialization.
// Default (false) shreds the keyfile for security.
KeepKeyfile bool
// DBEncryption configures SQLCipher transparent database encryption.
DBEncryption config.DBEncryptionConfig
// SkipSecureDetection disables secure hardware provider detection (biometric/TPM).
// When true, the bootstrap falls back to keyfile or interactive prompt only.
// Useful for testing and headless environments.
SkipSecureDetection bool
// KMSConfig provides KMS settings for KMS KEK slot unwrapping during bootstrap.
// When set and the envelope has a hardware slot, bootstrap attempts KMS-based
// MK unwrap before falling back to passphrase.
KMSConfig *config.KMSConfig
// KMSProviderName identifies which KMS backend to use for KEK unwrap (e.g., "aws-kms").
KMSProviderName string
}
Options configures the bootstrap process.
type Phase ¶
type Phase struct {
Name string
Run func(ctx context.Context, state *State) error
Cleanup func(state *State) // called in reverse order if a later phase fails
}
Phase represents a single step in the bootstrap pipeline.
func DefaultPhases ¶
func DefaultPhases() []Phase
DefaultPhases returns the standard bootstrap phase sequence (11 phases).
Envelope-aware order: envelope loads BEFORE DB open so recovery credentials (mnemonic) and MK-derived DB keys are available when we actually open SQLCipher. Legacy installations follow the same pipeline but land in MigrateEnvelope which performs a one-time upgrade.
type PhaseTimingEntry ¶ added in v0.7.0
type PhaseTimingEntry struct {
Phase string `json:"phase"`
Duration time.Duration `json:"duration"`
}
PhaseTimingEntry records the duration of a bootstrap phase.
type Pipeline ¶
type Pipeline struct {
// contains filtered or unexported fields
}
Pipeline executes phases sequentially. If a phase fails, cleanup functions of all previously completed phases are called in reverse order.
func NewPipeline ¶
NewPipeline creates a pipeline from the given phases.
type Result ¶
type Result struct {
// Config is the decrypted, active configuration.
Config *config.Config
// ExplicitKeys tracks which context-related config keys the user explicitly set.
// nil for legacy profiles or when explicit key tracking is unavailable.
ExplicitKeys map[string]bool
// AutoEnabled records which context subsystems were auto-enabled during config resolution.
AutoEnabled config.AutoEnabledSet
// DBClient is the shared ent.Client for the application database.
DBClient *ent.Client
// RawDB is the underlying *sql.DB for direct SQL operations (e.g., sqlite-vec).
RawDB *sql.DB
// Crypto is the initialized CryptoProvider for the session.
Crypto security.CryptoProvider
// ConfigStore provides encrypted profile CRUD operations.
ConfigStore *configstore.Store
// ProfileName is the name of the loaded profile.
ProfileName string
// LangoDir is the resolved data directory (Options.LangoDir or ~/.lango).
// Downstream components (CLI, status, change-passphrase) use this to locate
// the envelope file without reaching into bootstrap internals.
LangoDir string
// IdentityKey is the Ed25519 identity key derived from the Master Key (Phase 3).
// nil when MK is unavailable (legacy mode).
IdentityKey ed25519.PrivateKey
// PQSigningKeySeed is the 32-byte HKDF seed for ML-DSA-65 PQ signing (Phase 5).
// nil when MK is unavailable. Downstream calls mldsa65.NewKeyFromSeed to derive the key.
PQSigningKeySeed []byte
// KMSUnwrap indicates the MK was unwrapped via a KMS KEK slot (not passphrase/mnemonic).
KMSUnwrap bool
// PhaseTiming records the duration of each bootstrap phase.
PhaseTiming []PhaseTimingEntry `json:"phaseTiming,omitempty"`
}
Result holds everything produced by the bootstrap process.
type State ¶
type State struct {
Options Options
Result Result
// Internal state passed between phases.
Home string
LangoDir string
// Encryption detection.
DBEncrypted bool
NeedsDBKey bool
// Passphrase acquisition.
Passphrase string
PassSource passphrase.Source
SecureProvider keyring.Provider
SecurityTier keyring.SecurityTier
FirstRunGuess bool
// Database handles (set by phaseOpenDatabase).
Client *ent.Client
RawDB *sql.DB
// Security state from DB (legacy path).
Salt []byte
Checksum []byte
FirstRun bool
// Crypto.
DBKey string
Crypto security.CryptoProvider
// Envelope-based crypto state.
Envelope *security.MasterKeyEnvelope
MasterKey []byte // unwrapped MK (zeroed on cleanup)
LegacyMode bool // no envelope, not first run — needs legacy→envelope migration
RecoveryMode bool // reserved for future use; no longer set during bootstrap
// Identity key derived from MK via HKDF (Phase 3).
IdentityKey ed25519.PrivateKey
// PQ signing key seed derived from MK via HKDF (Phase 5).
// 32-byte seed for ML-DSA-65. Downstream code calls mldsa65.NewKeyFromSeed.
PQSigningKeySeed []byte
// KMS KEK state (Phase 6).
KMSProvider security.CryptoProvider // transient, for KMS KEK unwrap only
KMSUnwrap bool // MK was unwrapped via KMS (not passphrase)
}
State carries data between pipeline phases. Each phase can read from and write to State.