application

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package application implements the Vault Security context use cases: creation, unlock, lock, panic lock, and master-password change. This is the only package that ever holds the root vault key or its derived subkeys.

Index

Constants

This section is empty.

Variables

View Source
var ErrRateLimited = errors.New("vault: unlock rate limited")

ErrRateLimited is returned when unlock attempts arrive faster than the failure backoff allows (PRD 19.3).

Functions

This section is empty.

Types

type Keyring

type Keyring struct {
	Metadata []byte
	Secret   []byte
	Audit    []byte
	Backup   []byte
	// Catalog keys the authenticated vault-state root (see internal/catalog).
	Catalog []byte
}

Keyring holds the derived subkeys for one unlocked period. It lives only in daemon memory and is wiped on lock.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service is the vault security application service.

func NewService

func NewService(store *sqlite.Store, clock shared.Clock) *Service

func (*Service) ChangeMasterPassword

func (s *Service) ChangeMasterPassword(ctx context.Context, current, next []byte, params crypto.KDFParams) error

ChangeMasterPassword re-wraps only the root key under a new KEK and swaps the envelope atomically, then locks (PRD 15.6).

func (*Service) Epoch

func (s *Service) Epoch() uint64

Epoch returns the current vault epoch for session binding.

func (*Service) Init

func (s *Service) Init(ctx context.Context, password []byte, params crypto.KDFParams) error

Init creates the vault: random root key, Argon2id envelope, verified canary (PRD 15.1). It fails if a vault already exists.

func (*Service) IsUnlocked

func (s *Service) IsUnlocked() bool

IsUnlocked reports the lock state without touching key material or the database, so authorization and the idle-lock loop can consult it cheaply.

func (*Service) Keys

func (s *Service) Keys() (*Keyring, error)

Keys returns the keyring while unlocked. Callers must not retain it across operations; it is invalidated on lock.

func (*Service) Lock

func (s *Service) Lock()

Lock clears key material, bumps the epoch, and fires lock callbacks (PRD 15.3). Locking an already locked vault is a no-op.

func (*Service) LockPolicy

func (s *Service) LockPolicy() domain.LockPolicy

LockPolicy returns the loaded vault's lock policy. It is the zero policy until a vault is loaded, so callers must gate on IsUnlocked first.

func (*Service) NoteCatalogCounter

func (s *Service) NoteCatalogCounter(counter int64)

NoteCatalogCounter raises the in-process high-water mark. Every mutating write calls it with the counter it stamped, *after* its transaction commits — a counter that never landed would make the next unlock see a lower one and report a rollback that did not happen.

This is what gives in-run rollback detection its reach: without it the mark would only advance at unlock, and swapping the file back to a state from earlier in this same session — undoing a revocation performed a minute ago, say — would verify cleanly, because that state really was valid once.

func (*Service) OnLock

func (s *Service) OnLock(fn func())

OnLock registers a callback invoked (under lock) whenever the vault locks: session invalidation and index destruction hook in here.

func (*Service) PanicLock

func (s *Service) PanicLock()

PanicLock is the Level 3 response (PRD 19.1): identical to Lock today, kept as a separate entry point so callers express intent and events differ.

func (*Service) Reset

func (s *Service) Reset()

Reset locks and forgets the cached vault row so the next operation reloads it from the (possibly replaced) database. Used after backup restore.

It also clears the catalog high-water mark. A restore *is* a rollback — the snapshot's counter is behind where this process had got to — but an authorized one: the operator asked for it, and the container was authenticated before a byte of it was installed. Keeping the old mark would make the next unlock call that restore an attack and panic-lock a vault the user had just deliberately recovered.

func (*Service) Status

func (s *Service) Status(ctx context.Context) (Status, error)

func (*Service) Unlock

func (s *Service) Unlock(ctx context.Context, password []byte) error

Unlock derives the KEK, unwraps the root key, verifies the canary, derives subkeys, and bumps the epoch (PRD 15.2). Every failure mode returns the same generic authentication error.

func (*Service) VaultInfo

func (s *Service) VaultInfo() (vaultID []byte, formatVersion, keyVersion uint32, err error)

VaultInfo exposes identity values needed for AADs.

func (*Service) VerifyCatalog

func (s *Service) VerifyCatalog(ctx context.Context) (bootstrapped bool, err error)

VerifyCatalog checks the authenticated vault-state root and reports whether the catalog is what this vault last committed. Call it at unlock, after the record index has loaded.

Three outcomes:

  • the root matches: normal, nothing to say.
  • no anchor exists: a vault created before this table. Trust on first use — adopt the current state as the baseline and say so. The limitation is real and worth stating plainly: tampering that happened before this first unlock is what gets adopted. There is no way around that; the key needed to have anchored it earlier did not exist on disk to be used.
  • the root does not match, or the counter went backwards: fail closed with ErrIntegrityFailure. The caller panic-locks. It never destroys anything (invariant 7) — a false positive from a bug of ours must not be fatal to someone's vault.

func (*Service) VerifyPassword

func (s *Service) VerifyPassword(ctx context.Context, password []byte) error

VerifyPassword checks the master password without changing state, for reauthentication before destructive operations.

type Status

type Status struct {
	Initialized bool
	Unlocked    bool
	Epoch       uint64
	RecordCount int64
}

Status returns the current state without touching key material.

Jump to

Keyboard shortcuts

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