vault

package
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// SmallVaultThreshold is the entry count below which defragmentation is never needed
	SmallVaultThreshold = 500

	// MediumVaultThreshold is the entry count above which stricter fragmentation rules apply
	MediumVaultThreshold = 2000

	// SmallVaultFragmentationThreshold is the fragmentation ratio above which
	// a medium-sized vault should be defragmented (40%)
	SmallVaultFragmentationThreshold = 0.40

	// LargeVaultFragmentationThreshold is the fragmentation ratio above which
	// a large vault should be defragmented (30%)
	LargeVaultFragmentationThreshold = 0.30
)

Defragmentation thresholds

View Source
const (
	// LatestFormatVersion is the current vault format version used for new vaults
	LatestFormatVersion = 2
	// MinSupportedVersion is the minimum vault format version that can be read
	MinSupportedVersion = 1
	// FormatVersion is kept for backward compatibility, use LatestFormatVersion instead
	FormatVersion = LatestFormatVersion
)

Format version constants

View Source
const (
	EntryTypeIdentity = "identity"
	EntryTypeSecret   = "secret"
	EntryTypeValue    = "value"
)

Entry types for JSONL records

View Source
const (
	// HeaderMarker is the constant marker line that precedes the vault header JSON.
	HeaderMarker = "# === VAULT HEADER ==="
	// DataMarker separates the header from data entries.
	DataMarker = "# === VAULT DATA ==="
)

Vault section markers

View Source
const HeaderMarkerV1 = "# === VAULT HEADER v1 ==="

HeaderMarkerV1 is the header marker for v1 vaults.

View Source
const HeaderMarkerV2 = "# === VAULT HEADER v2 ==="

HeaderMarkerV2 is the header marker for v2 vaults.

View Source
const SecretKeySeparator = "::"

SecretKeySeparator is the delimiter between namespace and key name.

Variables

This section is empty.

Functions

func CheckAndUpgradeVault added in v0.0.9

func CheckAndUpgradeVault(w *Writer, path string, requireExplicitUpgrade bool) (bool, error)

CheckAndUpgradeVault checks if a vault needs upgrading and handles it based on requireExplicitUpgrade. Returns true if the vault was upgraded (caller may need to reload). If requireExplicitUpgrade is true: warns but doesn't modify the vault. If requireExplicitUpgrade is false: upgrades the vault in-place.

func CompareSecretKeys added in v0.0.9

func CompareSecretKeys(key1, key2 string) bool

CompareSecretKeys compares two secret keys for equality, case-insensitively. Both keys are normalized before comparison.

func ComputeSecretHash

func ComputeSecretHash(secret *Secret, algorithmBits int) string

ComputeSecretHash computes the canonical hash for a secret. The canonical format includes: added_at:key:signed_by

func ComputeSecretValueHash

func ComputeSecretValueHash(value *SecretValue, secretKey string, algorithmBits int) string

ComputeSecretValueHash computes the canonical hash for a secret value. The canonical format includes: added_at:available_to:signed_by:value The available_to list is joined with commas for deterministic representation.

func DetectVaultVersion added in v0.0.9

func DetectVaultVersion(path string) (int, error)

DetectVaultVersion reads just the first line of a vault file and extracts the version from the header marker without parsing the full header JSON.

func ExpandPath

func ExpandPath(path string) string

ExpandPath expands ~ to home directory using platform-aware resolution

func FormatSecretKeyError added in v0.0.9

func FormatSecretKeyError(err error) string

FormatSecretKeyError formats a validation error with usage help.

func GetSecretSigningData

func GetSecretSigningData(secret *Secret) string

GetSecretSigningData returns the canonical data string used for signing a secret. This is the data that should be hashed and signed when creating a secret signature.

func GetSecretValueSigningData

func GetSecretValueSigningData(value *SecretValue) string

GetSecretValueSigningData returns the canonical data string used for signing a secret value. This is the data that should be hashed and signed when creating a secret value signature.

func HeaderMarkerForVersion added in v0.0.9

func HeaderMarkerForVersion(_ int) string

HeaderMarkerForVersion returns the header marker (version-independent). Deprecated: The version parameter is ignored. Use HeaderMarker constant directly.

func IsValidSecretKey added in v0.0.9

func IsValidSecretKey(key string) bool

IsValidSecretKey returns true if the key is valid.

func MarshalEntry

func MarshalEntry(e Entry) ([]byte, error)

MarshalEntry creates a JSON line for an entry

func MarshalHeader

func MarshalHeader(h *Header) ([]byte, error)

MarshalHeader creates the JSON representation of the header using the latest format. This is kept for backward compatibility with existing code.

func MarshalHeaderV1 added in v0.0.9

func MarshalHeaderV1(h *Header) ([]byte, error)

MarshalHeaderV1 creates the JSON representation of the header in v1 format. Identities are serialized as [[fingerprint, line], ...] sorted by line number.

func MarshalHeaderV2 added in v0.0.9

func MarshalHeaderV2(h *Header) ([]byte, error)

MarshalHeaderV2 creates the JSON representation of the header in v2 format. Identities are serialized as {fingerprint: line, ...} dict.

func MarshalHeaderVersioned added in v0.0.9

func MarshalHeaderVersioned(h *Header, version int) ([]byte, error)

MarshalHeaderVersioned creates the JSON representation of the header in the specified version format.

func NormalizeKeyForLookup added in v0.0.9

func NormalizeKeyForLookup(key string) string

NormalizeKeyForLookup normalizes a secret key for lookup operations. If normalization fails (e.g., legacy key format), returns the original key unchanged. This provides backward compatibility for existing vaults with non-conforming keys.

func NormalizeSecretKey added in v0.0.9

func NormalizeSecretKey(key string) (string, error)

NormalizeSecretKey normalizes a secret key to canonical form. Returns the normalized key and any validation error.

func OptimalOrderEstimate

func OptimalOrderEstimate(header *Header) int

OptimalOrderEstimate calculates what the line count would be after defragmentation

func SortAvailableTo

func SortAvailableTo(value *SecretValue)

SortAvailableTo sorts the available_to fingerprints alphabetically (in-place). This should be called before signing to ensure deterministic output.

func ValidateAvailableToOrder

func ValidateAvailableToOrder(value *SecretValue) error

ValidateAvailableToOrder checks that available_to fingerprints are sorted alphabetically. This ensures deterministic output for version control.

func ValidateDataMarker added in v0.0.9

func ValidateDataMarker(markerLine string) error

ValidateDataMarker checks if a data marker line is valid. Returns nil if the marker is valid, or an error if invalid.

func ValidateHeaderMarker added in v0.0.9

func ValidateHeaderMarker(markerLine string) error

ValidateHeaderMarker checks if a header marker line is valid. Accepts both the new versionless format and old versioned formats for backward compatibility. Returns nil if the marker is valid, or an error if invalid.

func ValidateSecret

func ValidateSecret(secret *Secret, signingIdentity *Identity) error

ValidateSecret performs comprehensive validation of a secret. It checks:

  • Required fields are present (Signature, SignedBy)
  • Signature is valid hex encoding
  • Signature is cryptographically valid
  • All secret values are valid

Returns nil if valid, or an error describing the validation failure.

func ValidateSecretMetadata

func ValidateSecretMetadata(secret *Secret, vault *Vault) error

ValidateSecretMetadata checks that all available_to fingerprints reference valid identities.

func ValidateSecretValue

func ValidateSecretValue(value *SecretValue, secretKey string, signingIdentity *Identity) error

ValidateSecretValue performs comprehensive validation of a secret value. It checks:

  • Required fields are present (Signature, SignedBy)
  • Signature is valid hex encoding
  • Value is valid base64 encoding
  • Signature is cryptographically valid

Returns nil if valid, or an error describing the validation failure.

func ValidateSecretsOrder

func ValidateSecretsOrder(secrets []Secret) error

ValidateSecretsOrder checks that secrets values are sorted by AddedAt (most recent last). This is required for append-only vault operations.

func ValidateVaultConfigExists

func ValidateVaultConfigExists(config VaultConfig) error

ValidateVaultConfigExists checks that at least one vault file exists Returns error if no vaults exist

func VerifySecretSignature

func VerifySecretSignature(secret *Secret, signingIdentity *Identity) (bool, error)

VerifySecretSignature verifies the cryptographic signature of a secret. It performs a two-step verification: 1. Computes the hash of canonical data and verifies it matches the stored hash 2. Verifies the signature of the hash using the signer's public key

Returns true if both verifications pass, false otherwise.

func VerifySecretValueSignature

func VerifySecretValueSignature(value *SecretValue, secretKey string, signingIdentity *Identity) (bool, error)

VerifySecretValueSignature verifies the cryptographic signature of a secret value. It performs a two-step verification: 1. Computes the hash of canonical data and verifies it matches the stored hash 2. Verifies the signature of the hash using the signer's public key

Returns true if both verifications pass, false otherwise.

func WrapVaultError added in v0.0.9

func WrapVaultError(path string, err error) error

WrapVaultError adds vault path context to an error for better debugging.

Types

type Entry

type Entry struct {
	Type      string          `json:"type"`
	SecretKey string          `json:"secret,omitempty"` // only for value entries
	Data      json.RawMessage `json:"data"`
}

Entry represents a single line entry in the vault file

func CreateIdentityEntry

func CreateIdentityEntry(id identity.Identity) (*Entry, error)

CreateIdentityEntry creates an Entry for an identity

func CreateSecretEntry

func CreateSecretEntry(s Secret) (*Entry, error)

CreateSecretEntry creates an Entry for a secret definition

func CreateValueEntry

func CreateValueEntry(secretKey string, sv SecretValue) (*Entry, error)

CreateValueEntry creates an Entry for a secret value

func UnmarshalEntry

func UnmarshalEntry(data []byte) (*Entry, error)

UnmarshalEntry parses a JSON line into an Entry

type FragmentationStats

type FragmentationStats struct {
	// TotalEntries is the total number of data entries
	TotalEntries int

	// TotalLines is the total number of lines in the file (including header)
	TotalLines int

	// HeaderLines is the number of header/comment lines
	HeaderLines int

	// FragmentationRatio is the overall fragmentation (0.0 = perfect, 1.0 = completely fragmented)
	FragmentationRatio float64

	// AverageSecretSpread is the average distance between a secret definition and its values
	AverageSecretSpread float64

	// MaxSecretSpread is the maximum spread for any single secret
	MaxSecretSpread int

	// SecretsWithSpread is the number of secrets whose values are not consecutive
	SecretsWithSpread int

	// RecommendDefrag indicates whether defragmentation is recommended
	RecommendDefrag bool

	// Reason explains why defragmentation is or isn't recommended
	Reason string
}

FragmentationStats contains detailed fragmentation metrics

func CalculateFragmentation

func CalculateFragmentation(r *Reader) (*FragmentationStats, error)

CalculateFragmentation analyzes the vault and returns fragmentation statistics

func Defragment

func Defragment(w *Writer) (*FragmentationStats, error)

Defragment rewrites the vault file with all entries in optimal order: - All identities first (sorted by AddedAt) - Each secret followed immediately by its values (secrets sorted by key, values by AddedAt)

func DefragmentIfNeeded

func DefragmentIfNeeded(w *Writer) (*FragmentationStats, bool, error)

DefragmentIfNeeded checks fragmentation and defragments only if recommended

type Header struct {
	Version    int                    `json:"version"`
	Identities map[string]int         `json:"identities"` // fingerprint -> line number
	Secrets    map[string]SecretIndex `json:"secrets"`    // key -> secret index
}

Header contains the vault index for efficient lookups. It maps fingerprints to line numbers for identities, and secret keys to their definition and value line numbers.

func NewHeader

func NewHeader() *Header

NewHeader creates a new empty header

func UnmarshalHeader

func UnmarshalHeader(data []byte) (*Header, error)

UnmarshalHeader parses JSON into a Header, auto-detecting the version.

func UnmarshalHeaderV1 added in v0.0.9

func UnmarshalHeaderV1(data []byte) (*Header, error)

UnmarshalHeaderV1 parses v1 header JSON into a Header. Converts [[fingerprint, line], ...] back to map[string]int.

func UnmarshalHeaderV2 added in v0.0.9

func UnmarshalHeaderV2(data []byte) (*Header, error)

UnmarshalHeaderV2 parses v2 header JSON into a Header. Identities are already in map[string]int format.

func UnmarshalHeaderVersioned added in v0.0.9

func UnmarshalHeaderVersioned(data []byte, version int) (*Header, error)

UnmarshalHeaderVersioned parses header JSON using the specified version's parser.

type HeaderV1Raw added in v0.0.9

type HeaderV1Raw struct {
	Version    int                    `json:"version"`
	Identities [][2]interface{}       `json:"identities"` // [[fingerprint, line], ...]
	Secrets    map[string]SecretIndex `json:"secrets"`
}

HeaderV1Raw is the on-disk format for v1 headers. Identities are stored as an array of [fingerprint, line] pairs.

type HeaderV2Raw added in v0.0.9

type HeaderV2Raw struct {
	Version    int                    `json:"version"`
	Identities map[string]int         `json:"identities"` // {fingerprint: line, ...}
	Secrets    map[string]SecretIndex `json:"secrets"`
}

HeaderV2Raw is the on-disk format for v2 headers. Identities are stored as a dict {fingerprint: line, ...}.

type Identity

type Identity = identity.Identity

Type aliases

type IdentityData

type IdentityData struct {
	AddedAt       time.Time  `json:"added_at"`
	Algorithm     string     `json:"algorithm"`
	AlgorithmBits int        `json:"algorithm_bits"`
	Curve         string     `json:"curve,omitempty"`
	CreatedAt     time.Time  `json:"created_at"`
	ExpiresAt     *time.Time `json:"expires_at,omitempty"`
	Fingerprint   string     `json:"fingerprint"`
	Hash          string     `json:"hash"`
	PublicKey     string     `json:"public_key"`
	SignedBy      string     `json:"signed_by"`
	Signature     string     `json:"signature"`
	UID           string     `json:"uid"`
}

IdentityData represents an identity entry's data

func IdentityDataFromIdentity

func IdentityDataFromIdentity(id identity.Identity) IdentityData

IdentityDataFromIdentity converts Identity to IdentityData

func ParseIdentityData

func ParseIdentityData(e *Entry) (*IdentityData, error)

ParseIdentityData extracts IdentityData from an Entry

func (*IdentityData) ToIdentity

func (d *IdentityData) ToIdentity() identity.Identity

ToIdentity converts IdentityData to the Identity type

type Manager

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

Manager handles vault file operations with locking

func NewManager

func NewManager(path string, requireExplicitUpgrade bool) *Manager

NewManager creates a new vault manager for the specified path. requireExplicitUpgrade controls whether vaults are auto-upgraded (false) or only warned about (true).

func (*Manager) AddIdentity

func (m *Manager) AddIdentity(id Identity)

AddIdentity adds an identity to the vault

func (*Manager) AddSecret

func (m *Manager) AddSecret(secret Secret)

AddSecret adds a new secret or updates an existing one with a new value. Secret keys are compared case-insensitively using CompareSecretKeys.

func (*Manager) CanIdentityAccessSecret

func (m *Manager) CanIdentityAccessSecret(fingerprint, secretKey string) bool

CanIdentityAccessSecret checks if an identity can access a secret

func (*Manager) Defragment

func (m *Manager) Defragment() (*FragmentationStats, error)

Defragment performs vault defragmentation

func (*Manager) FragmentationStats

func (m *Manager) FragmentationStats() (*FragmentationStats, error)

FragmentationStats returns defragmentation statistics for the vault

func (*Manager) Get

func (m *Manager) Get() Vault

Get returns the vault data

func (*Manager) GetAccessibleSecretValue

func (m *Manager) GetAccessibleSecretValue(fingerprint, secretKey string, strict bool) *SecretValue

GetAccessibleSecretValue gets the most recent accessible secret value. If strict is true, only returns a value if the identity has access to the LATEST value.

func (*Manager) GetAllAccessibleSecretValues

func (m *Manager) GetAllAccessibleSecretValues(fingerprint, secretKey string) []*SecretValue

GetAllAccessibleSecretValues returns all unique secret values accessible to an identity

func (*Manager) GetHeader

func (m *Manager) GetHeader() *Header

GetHeader returns the vault header for validation Returns nil if the vault hasn't been loaded yet

func (*Manager) GetIdentityByFingerprint

func (m *Manager) GetIdentityByFingerprint(fingerprint string) *Identity

GetIdentityByFingerprint retrieves an identity by fingerprint

func (*Manager) GetLines

func (m *Manager) GetLines() []string

GetLines returns the raw lines of the vault file for validation Returns nil if the vault hasn't been loaded yet

func (*Manager) GetSecretByKey

func (m *Manager) GetSecretByKey(key string) *Secret

GetSecretByKey retrieves a secret by key

func (*Manager) IsReadOnly

func (m *Manager) IsReadOnly() bool

IsReadOnly returns true if the vault is opened in read-only mode

func (*Manager) ListIdentityFingerprints

func (m *Manager) ListIdentityFingerprints() []string

ListIdentityFingerprints returns all identity fingerprints in the vault

func (*Manager) ListSecretKeys

func (m *Manager) ListSecretKeys() []string

ListSecretKeys returns all secret keys in the vault

func (*Manager) OpenAndLock

func (m *Manager) OpenAndLock() error

OpenAndLock opens the vault file and locks it for exclusive access Creates the file with defaults if it doesn't exist

func (*Manager) Path

func (m *Manager) Path() string

Path returns the vault file path

func (*Manager) Save

func (m *Manager) Save() error

Save is a no-op kept for API compatibility. Writer methods already persist changes via flush().

func (*Manager) Unlock

func (m *Manager) Unlock() error

Unlock releases the lock and closes the vault file

func (*Manager) Version added in v0.0.9

func (m *Manager) Version() int

Version returns the vault format version

type MarkerType added in v0.0.9

type MarkerType int

MarkerType identifies the type of vault marker line

const (
	// MarkerUnknown indicates the line is not a recognized marker
	MarkerUnknown MarkerType = iota
	// MarkerHeader indicates a current-format header marker
	MarkerHeader
	// MarkerHeaderLegacy indicates an old versioned header marker (e.g., "# === VAULT HEADER v1 ===")
	MarkerHeaderLegacy
	// MarkerData indicates a data section marker
	MarkerData
)

func DetectMarkerType added in v0.0.9

func DetectMarkerType(line string) MarkerType

DetectMarkerType identifies what type of marker a line is

type Reader

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

Reader provides efficient access to vault data using the header index

func NewReader

func NewReader(path string) (*Reader, error)

NewReader creates a new vault reader and parses the header

func (*Reader) EntryCount

func (r *Reader) EntryCount() int

EntryCount returns the count of data entries (excluding header lines)

func (*Reader) GetAllIdentities

func (r *Reader) GetAllIdentities() ([]IdentityData, error)

GetAllIdentities retrieves all identities from the vault

func (*Reader) GetIdentity

func (r *Reader) GetIdentity(fingerprint string) (*IdentityData, error)

GetIdentity retrieves a specific identity by fingerprint

func (*Reader) GetSecret

func (r *Reader) GetSecret(key string) (*SecretData, error)

GetSecret retrieves a secret definition by key

func (*Reader) GetSecretValues

func (r *Reader) GetSecretValues(key string) ([]SecretValue, error)

GetSecretValues retrieves all values for a secret

func (*Reader) HasIdentity

func (r *Reader) HasIdentity(fingerprint string) bool

HasIdentity checks if an identity exists by fingerprint

func (*Reader) HasSecret

func (r *Reader) HasSecret(key string) bool

HasSecret checks if a secret exists by key

func (*Reader) Header

func (r *Reader) Header() Header

Header returns the vault header (read-only copy)

func (*Reader) ListIdentityFingerprints

func (r *Reader) ListIdentityFingerprints() []string

ListIdentityFingerprints returns all identity fingerprints in the vault

func (*Reader) ListSecretKeys

func (r *Reader) ListSecretKeys() []string

ListSecretKeys returns all secret keys in the vault

func (*Reader) ReadEntry

func (r *Reader) ReadEntry(lineNum int) (*Entry, error)

ReadEntry reads and parses an entry at a specific line (1-indexed)

func (*Reader) StreamEntries

func (r *Reader) StreamEntries(handler func(entry *Entry) error) error

StreamEntries iterates through all entries in the vault, calling the handler for each

func (*Reader) TotalLines

func (r *Reader) TotalLines() int

TotalLines returns the total number of lines in the vault

func (*Reader) Version added in v0.0.9

func (r *Reader) Version() int

Version returns the detected vault format version

type Secret

type Secret struct {
	AddedAt   time.Time     `json:"added_at"`
	Hash      string        `json:"hash"`
	Key       string        `json:"key"`
	Signature string        `json:"signature"`
	SignedBy  string        `json:"signed_by"`
	Values    []SecretValue `json:"values"`
}

Secret represents a secret with its encrypted values. Secrets are identified by a key (name) and can have multiple versioned values for different sets of recipients.

func (Secret) IsDeleted added in v0.0.9

func (s Secret) IsDeleted() bool

IsDeleted returns true if the secret's latest value is a deletion marker.

type SecretData

type SecretData struct {
	AddedAt   time.Time `json:"added_at"`
	Hash      string    `json:"hash"`
	Key       string    `json:"key"`
	Signature string    `json:"signature"`
	SignedBy  string    `json:"signed_by"`
}

SecretData represents a secret definition entry's data

func ParseSecretData

func ParseSecretData(e *Entry) (*SecretData, error)

ParseSecretData extracts SecretData from an Entry

type SecretIndex

type SecretIndex struct {
	Definition int   `json:"secret"` // line number of secret definition
	Values     []int `json:"values"` // line numbers of secret values
}

SecretIndex tracks line numbers for a secret and its values

type SecretKey added in v0.0.9

type SecretKey struct {
	Namespace *string // nil for non-namespaced keys
	Name      string  // UPPERCASE
	Raw       string  // original input for error messages
}

SecretKey represents a parsed and normalized secret key. Keys can be either namespaced (namespace::KEY_NAME) or non-namespaced (KEY_NAME).

func ParseSecretKey added in v0.0.9

func ParseSecretKey(raw string) (*SecretKey, error)

ParseSecretKey parses a raw key input and returns a normalized SecretKey. Accepts case-insensitive input and normalizes to canonical form.

Valid formats:

  • Namespaced: "namespace::KEY_NAME" -> "namespace::KEY_NAME"
  • Non-namespaced: "KEY_NAME" -> "KEY_NAME"

func (SecretKey) IsNamespaced added in v0.0.9

func (sk SecretKey) IsNamespaced() bool

IsNamespaced returns true if this key has a namespace.

func (SecretKey) String added in v0.0.9

func (sk SecretKey) String() string

String returns the canonical form of the secret key. For namespaced: "namespace::KEY_NAME" For non-namespaced: "KEY_NAME"

type SecretKeyInfo added in v0.4.3

type SecretKeyInfo struct {
	Key      string `json:"key"`
	Vault    string `json:"vault"`
	VaultIdx int    `json:"vault_idx"`
	Deleted  bool   `json:"deleted,omitempty"`
}

SecretKeyInfo contains information about a secret key and its location

type SecretValue

type SecretValue struct {
	AddedAt     time.Time `json:"added_at"`
	AvailableTo []string  `json:"available_to"` // List of fingerprints that can decrypt
	Deleted     bool      `json:"deleted,omitempty"`
	Hash        string    `json:"hash"`
	Signature   string    `json:"signature"`
	SignedBy    string    `json:"signed_by"`
	Value       string    `json:"value"` // Base64-encoded encrypted value
}

SecretValue represents an encrypted secret value with access control. Each secret can have multiple values (versions), each with its own list of identities that can decrypt it.

func ParseSecretValue added in v0.4.4

func ParseSecretValue(e *Entry) (*SecretValue, error)

ParseSecretValue extracts SecretValue from an Entry

type Vault

type Vault struct {
	Identities []Identity `json:"identities,omitempty"`
	Secrets    []Secret   `json:"secrets,omitempty"`
}

Vault represents the complete vault file structure. A vault contains identities (public keys) and secrets (encrypted values).

func NewVault

func NewVault() Vault

NewVault creates an empty vault.

func (Vault) CanIdentityAccessSecret

func (v Vault) CanIdentityAccessSecret(fingerprint, secretKey string) bool

CanIdentityAccessSecret checks if an identity can access any value of a secret. It searches from most recent to oldest value.

func (Vault) GetAccessibleSecretValue

func (v Vault) GetAccessibleSecretValue(fingerprint, secretKey string, strict bool) *SecretValue

GetAccessibleSecretValue returns the most recent secret value accessible to the identity. Returns nil if identity cannot access any version of the secret. Returns nil if the secret is deleted (latest value has Deleted=true). If strict is true, only returns a value if the identity has access to the LATEST value.

func (Vault) GetIdentityByFingerprint

func (v Vault) GetIdentityByFingerprint(fingerprint string) *Identity

GetIdentityByFingerprint finds an identity by its GPG fingerprint. Returns nil if no identity with the given fingerprint exists.

func (Vault) GetSecretByKey

func (v Vault) GetSecretByKey(key string) *Secret

GetSecretByKey finds a secret by its key (name). Lookup is case-insensitive - keys are normalized before comparison. Returns nil if no secret with the given key exists.

type VaultConfig

type VaultConfig struct {
	Entries                     []VaultEntry
	RequireExplicitVaultUpgrade bool // If true, don't auto-upgrade vaults
}

VaultConfig represents parsed vault configuration

func ParseVaultConfig

func ParseVaultConfig(vaultPaths []string) (VaultConfig, error)

ParseVaultConfig parses vault configuration from a list of paths

func (VaultConfig) GetEntriesInOrder

func (vc VaultConfig) GetEntriesInOrder() []VaultEntry

GetEntriesInOrder returns all entries in order

type VaultEntry

type VaultEntry struct {
	Path     string `json:"path"`
	Optional bool   `json:"optional,omitempty"` // If true, missing vault is not an error
}

VaultEntry represents a single vault configuration entry

type VaultInfo added in v0.0.9

type VaultInfo struct {
	Path          string     // Path to the vault file
	Version       int        // Vault format version
	MarkerFormat  MarkerType // Header marker format (current vs legacy)
	IdentityCount int        // Number of identities in the vault
	SecretCount   int        // Number of secrets in the vault
}

VaultInfo contains lightweight metadata about a vault file. It can be obtained without fully parsing all vault entries.

func InspectVault added in v0.0.9

func InspectVault(path string) (*VaultInfo, error)

InspectVault returns lightweight metadata about a vault without fully loading it. This is useful for quick vault inspection or validation.

type VaultPathWithIndex added in v0.0.9

type VaultPathWithIndex struct {
	Path  string
	Index int
}

VaultPathWithIndex pairs a vault path with its original configuration index

type VaultResolver

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

VaultResolver manages multiple vault files

func NewVaultResolver

func NewVaultResolver(config VaultConfig) *VaultResolver

NewVaultResolver creates a new vault resolver from configuration

func (*VaultResolver) AddIdentity

func (vr *VaultResolver) AddIdentity(identity Identity, index int) error

AddIdentity adds an identity to all open vaults (or a specific vault if index >= 0)

func (*VaultResolver) AddSecret

func (vr *VaultResolver) AddSecret(secret Secret, index int) error

AddSecret adds a secret to a specific vault index (0-based)

func (*VaultResolver) CloseAll

func (vr *VaultResolver) CloseAll() error

CloseAll closes all open vaults

func (*VaultResolver) FindSecretVaultIndex

func (vr *VaultResolver) FindSecretVaultIndex(key string) int

FindSecretVaultIndex finds the first vault index containing the secret key Returns -1 if not found

func (*VaultResolver) GetAccessibleSecretFromAnyVault

func (vr *VaultResolver) GetAccessibleSecretFromAnyVault(key, fingerprint string, strict bool) (*SecretValue, error)

GetAccessibleSecretFromAnyVault retrieves the most recent accessible secret value from any vault, searching in order. If strict is true, only returns a value if the identity has access to the LATEST value of the secret.

func (*VaultResolver) GetAvailableVaultPathsWithIndices added in v0.0.9

func (vr *VaultResolver) GetAvailableVaultPathsWithIndices() []VaultPathWithIndex

GetAvailableVaultPathsWithIndices returns only vault paths that were successfully loaded, paired with their original configuration indices. This is useful for interactive selection where we need to map the selected item back to the correct vault index.

func (*VaultResolver) GetConfig

func (vr *VaultResolver) GetConfig() VaultConfig

GetConfig returns the vault configuration

func (*VaultResolver) GetIdentityByFingerprint

func (vr *VaultResolver) GetIdentityByFingerprint(fingerprint string) *Identity

GetIdentityByFingerprint finds an identity by fingerprint in any vault

func (*VaultResolver) GetLoadError

func (vr *VaultResolver) GetLoadError(index int) error

GetLoadError returns the error encountered when loading a vault at index

func (*VaultResolver) GetSecret

func (vr *VaultResolver) GetSecret(index int, key string) (*SecretValue, error)

GetSecret retrieves a secret from a specific vault index (0-based)

func (*VaultResolver) GetSecretByKeyFromVault

func (vr *VaultResolver) GetSecretByKeyFromVault(index int, key string) *Secret

GetSecretByKeyFromVault gets a secret by key from a specific vault index Used for operations that need to modify a secret in place

func (*VaultResolver) GetSecretFromAnyVault

func (vr *VaultResolver) GetSecretFromAnyVault(key string, stderr io.Writer) (*SecretValue, error)

GetSecretFromAnyVault retrieves a secret value from any vault, searching in order

func (*VaultResolver) GetVaultManager

func (vr *VaultResolver) GetVaultManager(index int) *Manager

GetVaultManager returns the vault manager for a specific index

func (*VaultResolver) GetVaultPaths

func (vr *VaultResolver) GetVaultPaths() []string

GetVaultPaths returns all vault paths in configuration order

func (*VaultResolver) IdentityExistsInVault

func (vr *VaultResolver) IdentityExistsInVault(fingerprint string, index int) bool

IdentityExistsInVault checks if an identity exists in a specific vault index

func (*VaultResolver) IsPathInConfig

func (vr *VaultResolver) IsPathInConfig(path string) bool

IsPathInConfig checks if a vault path is configured

func (*VaultResolver) ListAllSecretKeys added in v0.4.3

func (vr *VaultResolver) ListAllSecretKeys() []SecretKeyInfo

ListAllSecretKeys returns all secret keys from all valid vaults

func (*VaultResolver) ListSecretKeysFromVault added in v0.4.3

func (vr *VaultResolver) ListSecretKeysFromVault(index int) []SecretKeyInfo

ListSecretKeysFromVault returns all secret keys from a specific vault

func (*VaultResolver) OpenVaults

func (vr *VaultResolver) OpenVaults(stderr io.Writer) error

OpenVaults opens all vault files in the configuration Returns error if no vaults could be opened

func (*VaultResolver) OpenVaultsFromPaths

func (vr *VaultResolver) OpenVaultsFromPaths(paths []string, stderr io.Writer) error

OpenVaultsFromPaths opens vaults from explicit -v command-line paths Replaces the current configuration with these paths

func (*VaultResolver) SaveAll

func (vr *VaultResolver) SaveAll() error

SaveAll saves all open vaults

func (*VaultResolver) SaveVault

func (vr *VaultResolver) SaveVault(index int) error

SaveVault saves a specific vault by index

func (*VaultResolver) VaultCount

func (vr *VaultResolver) VaultCount() int

VaultCount returns the number of vaults in the resolver.

type Writer

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

Writer handles append-only vault modifications with atomic header updates

func NewWriter

func NewWriter(path string) (*Writer, error)

NewWriter creates a new vault writer If the file doesn't exist, it creates a new vault If it exists, it loads the current header

func NewWriterReadOnly

func NewWriterReadOnly(path string) (*Writer, error)

NewWriterReadOnly creates a vault writer in read-only mode It will not create new vaults or temp files - only read existing data

func (*Writer) AddIdentity

func (w *Writer) AddIdentity(id identity.Identity) error

AddIdentity adds a new identity to the vault

func (*Writer) AddSecret

func (w *Writer) AddSecret(s Secret) error

AddSecret adds a new secret definition to the vault

func (*Writer) AddSecretValue

func (w *Writer) AddSecretValue(secretKey string, sv SecretValue) error

AddSecretValue adds a new value to an existing secret

func (*Writer) AddSecretWithValues

func (w *Writer) AddSecretWithValues(s Secret) error

AddSecretWithValues adds a secret definition and its initial values

func (*Writer) GetLine

func (w *Writer) GetLine(lineNum int) (string, error)

GetLine returns a specific line (1-indexed)

func (*Writer) Header

func (w *Writer) Header() Header

Header returns a copy of the current header

func (*Writer) IsEmpty

func (w *Writer) IsEmpty() bool

IsEmpty returns true if the vault has no entries

func (*Writer) Path

func (w *Writer) Path() string

Path returns the vault file path

func (*Writer) ReadVault

func (w *Writer) ReadVault() (Vault, error)

ReadVault reconstructs the full Vault struct from the file

func (*Writer) Reload

func (w *Writer) Reload() error

Reload reloads the vault from disk

func (*Writer) RewriteFromVault

func (w *Writer) RewriteFromVault(v Vault) error

RewriteFromVault completely rewrites the vault file from a Vault struct using the latest format version. This is used for defragmentation.

func (*Writer) RewriteFromVaultWithVersion added in v0.0.9

func (w *Writer) RewriteFromVaultWithVersion(v Vault, version int) error

RewriteFromVaultWithVersion completely rewrites the vault file from a Vault struct using the specified format version. This is used for upgrades and defragmentation.

func (*Writer) String

func (w *Writer) String() string

String returns a string representation of the vault for debugging

func (*Writer) TotalLines

func (w *Writer) TotalLines() int

TotalLines returns the current number of lines

func (*Writer) UpdateHeader

func (w *Writer) UpdateHeader(h *Header) error

UpdateHeader updates only the header without modifying data entries Used when the header needs to be refreshed (e.g., after external modification)

func (*Writer) Version added in v0.0.9

func (w *Writer) Version() int

Version returns the current vault format version

Jump to

Keyboard shortcuts

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