Documentation
¶
Overview ¶
Package store provides key-value storage implementations.
Index ¶
- Variables
- func IsSecret(key string) bool
- func NormalizeKey(key string) string
- type AuditEntry
- type AuditQuery
- type Cached
- func (c *Cached) Close() error
- func (c *Cached) Delete(ctx context.Context, key string) error
- func (c *Cached) Get(ctx context.Context, key string) ([]byte, error)
- func (c *Cached) GetInfo(ctx context.Context, key string) (KeyInfo, error)
- func (c *Cached) GetWithFormat(ctx context.Context, key string) ([]byte, string, error)
- func (c *Cached) List(ctx context.Context, filter enum.SecretsFilter) ([]KeyInfo, error)
- func (c *Cached) SecretsEnabled() bool
- func (c *Cached) Set(ctx context.Context, key string, value []byte, format string) (created bool, err error)
- func (c *Cached) SetWithVersion(ctx context.Context, key string, value []byte, format string, ...) error
- func (c *Cached) Stats() lcw.CacheStat
- type ConflictError
- type ConflictInfo
- type Crypto
- type DBType
- type Encryptor
- type Interface
- type KeyInfo
- type Option
- type RWLocker
- type Store
- func (s *Store) Close() error
- func (s *Store) CreateSession(ctx context.Context, token, username string, expiresAt time.Time) error
- func (s *Store) Delete(ctx context.Context, key string) error
- func (s *Store) DeleteAllSessions(ctx context.Context) error
- func (s *Store) DeleteAuditOlderThan(ctx context.Context, olderThan time.Time) (int64, error)
- func (s *Store) DeleteExpiredSessions(ctx context.Context) (int64, error)
- func (s *Store) DeleteSession(ctx context.Context, token string) error
- func (s *Store) DeleteSessionsByUsername(ctx context.Context, username string) error
- func (s *Store) Get(ctx context.Context, key string) ([]byte, error)
- func (s *Store) GetInfo(ctx context.Context, key string) (KeyInfo, error)
- func (s *Store) GetSession(ctx context.Context, token string) (username string, expiresAt time.Time, err error)
- func (s *Store) GetWithFormat(ctx context.Context, key string) ([]byte, string, error)
- func (s *Store) List(ctx context.Context, filter enum.SecretsFilter) ([]KeyInfo, error)
- func (s *Store) LogAudit(ctx context.Context, entry AuditEntry) error
- func (s *Store) QueryAudit(ctx context.Context, q AuditQuery) ([]AuditEntry, int, error)
- func (s *Store) SecretsEnabled() bool
- func (s *Store) Set(ctx context.Context, key string, value []byte, format string) (created bool, err error)
- func (s *Store) SetWithVersion(ctx context.Context, key string, value []byte, format string, ...) error
Constants ¶
This section is empty.
Variables ¶
var ( DBTypeSQLite = enum.DbTypeSQLite DBTypePostgres = enum.DbTypePostgres )
Database type constants for convenience.
var ErrConflict = errors.New("version conflict")
ErrConflict is returned when optimistic locking fails due to concurrent modification.
var ErrDecryptionFailed = errors.New("decryption failed")
ErrDecryptionFailed is returned when decryption fails (wrong key or corrupted data).
var ErrInvalidZKPayload = errors.New("invalid ZK payload: must be $ZK$ followed by valid base64 of encrypted data")
ErrInvalidZKPayload is returned when a ZK-prefixed value has invalid format.
var ErrNotFound = errors.New("key not found")
ErrNotFound is returned when a key is not found in the store.
var ErrSecretsNotConfigured = errors.New("secrets key not configured")
ErrSecretsNotConfigured is returned when trying to access secrets without a key configured.
Functions ¶
func IsSecret ¶ added in v0.15.0
IsSecret checks if a key should be treated as a secret based on its path. A key is a secret if it contains "secrets" as a path segment:
- secrets/db/password → true (starts with secrets/)
- app/secrets/db → true (contains /secrets/)
- app/secrets → true (ends with /secrets)
- secrets → true (exactly "secrets")
- my-secrets/foo → false (not a path segment)
- secretsabc/foo → false (not a path segment)
func NormalizeKey ¶ added in v0.9.1
NormalizeKey normalizes a key by trimming spaces, leading/trailing slashes, and replacing spaces with underscores.
Types ¶
type AuditEntry ¶ added in v0.18.0
type AuditEntry struct {
ID int64 `json:"id" db:"id"`
Timestamp time.Time `json:"timestamp" db:"timestamp"`
Action enum.AuditAction `json:"action" db:"action"`
Key string `json:"key" db:"key"`
Actor string `json:"actor" db:"actor"`
ActorType enum.ActorType `json:"actor_type" db:"actor_type"`
Result enum.AuditResult `json:"result" db:"result"`
IP string `json:"ip,omitempty" db:"ip"`
UserAgent string `json:"user_agent,omitempty" db:"user_agent"`
ValueSize *int `json:"value_size,omitempty" db:"value_size"`
RequestID string `json:"request_id,omitempty" db:"request_id"`
}
AuditEntry represents a single audit log entry.
type AuditQuery ¶ added in v0.18.0
type AuditQuery struct {
Key string // prefix match with * suffix, e.g., "app/*"
Actor string // exact match
ActorType enum.ActorType // exact match (zero value = any)
Action enum.AuditAction // exact match (zero value = any)
Result enum.AuditResult // exact match (zero value = any)
From time.Time // inclusive
To time.Time // inclusive
Limit int // max entries to return
Offset int // skip entries for pagination
}
AuditQuery defines filters for querying audit logs.
type Cached ¶ added in v0.8.0
type Cached struct {
// contains filtered or unexported fields
}
Cached wraps a store Interface with a loading cache and satisfies the Interface itself. Cache is populated on reads via loader function, invalidated on writes.
func NewCached ¶ added in v0.8.0
NewCached creates a new cached store wrapper. maxKeys sets the maximum number of entries in the cache.
func (*Cached) Get ¶ added in v0.8.0
Get retrieves the value for a key, using cache with load-through. Secrets are never cached to avoid storing decrypted values in memory.
func (*Cached) GetInfo ¶ added in v0.8.2
GetInfo retrieves metadata for a key from the underlying store (not cached).
func (*Cached) GetWithFormat ¶ added in v0.8.0
GetWithFormat retrieves the value and format for a key, using cache with load-through. Secrets are never cached to avoid storing decrypted values in memory.
func (*Cached) SecretsEnabled ¶ added in v0.15.0
SecretsEnabled returns whether secrets encryption is enabled in the underlying store.
func (*Cached) Set ¶ added in v0.8.0
func (c *Cached) Set(ctx context.Context, key string, value []byte, format string) (created bool, err error)
Set stores a value and invalidates the cache entry. Returns (true, nil) if a new key was created, (false, nil) if an existing key was updated.
type ConflictError ¶ added in v0.10.1
type ConflictError struct {
Info ConflictInfo
}
ConflictError wraps ErrConflict with conflict details for UI display.
func (*ConflictError) Error ¶ added in v0.10.1
func (e *ConflictError) Error() string
Error returns a string representation of the conflict.
func (*ConflictError) Unwrap ¶ added in v0.10.1
func (e *ConflictError) Unwrap() error
Unwrap returns the underlying ErrConflict sentinel.
type ConflictInfo ¶ added in v0.10.1
type ConflictInfo struct {
CurrentValue []byte
CurrentFormat string
CurrentVersion time.Time
AttemptedVersion time.Time
}
ConflictInfo holds details about a detected version conflict.
type Crypto ¶ added in v0.15.0
type Crypto struct {
// contains filtered or unexported fields
}
Crypto handles encryption and decryption of secret values using NaCl secretbox with Argon2id key derivation.
func NewCrypto ¶ added in v0.15.0
NewCrypto creates a new Crypto instance with the given master key. Key must be at least 16 bytes.
type Encryptor ¶ added in v0.15.0
type Encryptor interface {
Encrypt(value []byte) ([]byte, error)
Decrypt(encrypted []byte) ([]byte, error)
}
Encryptor defines the interface for encrypting and decrypting secret values.
type Interface ¶ added in v0.8.0
type Interface interface {
Get(ctx context.Context, key string) ([]byte, error)
GetWithFormat(ctx context.Context, key string) ([]byte, string, error)
GetInfo(ctx context.Context, key string) (KeyInfo, error)
Set(ctx context.Context, key string, value []byte, format string) (created bool, err error)
SetWithVersion(ctx context.Context, key string, value []byte, format string, expectedVersion time.Time) error
Delete(ctx context.Context, key string) error
List(ctx context.Context, filter enum.SecretsFilter) ([]KeyInfo, error)
SecretsEnabled() bool
Close() error
}
Interface defines the contract for key-value storage operations. Both Store (concrete DB) and Cached (wrapper) implement this interface.
type KeyInfo ¶
type KeyInfo struct {
Key string `json:"key" db:"key"`
Size int `json:"size" db:"size"`
Format string `json:"format" db:"format"`
Secret bool `json:"secret" db:"-"`
ZKEncrypted bool `json:"zk_encrypted" db:"-"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
KeyInfo holds metadata about a stored key.
type Option ¶ added in v0.15.0
type Option func(*Store)
Option configures Store behavior.
func WithEncryptor ¶ added in v0.15.0
WithEncryptor enables secrets encryption with the given encryptor.
type RWLocker ¶
type RWLocker interface {
RLock()
RUnlock()
Lock()
Unlock()
}
RWLocker is an interface for read-write locking.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store implements key-value storage using SQLite or PostgreSQL.
func New ¶
New creates a new Store with the given database URL. Automatically detects database type from URL: - postgres:// or postgresql:// -> PostgreSQL - everything else -> SQLite
func (*Store) CreateSession ¶ added in v0.11.0
func (s *Store) CreateSession(ctx context.Context, token, username string, expiresAt time.Time) error
CreateSession stores a new session in the database.
func (*Store) Delete ¶
Delete removes the key from the store. Returns ErrNotFound if the key does not exist.
func (*Store) DeleteAllSessions ¶ added in v0.11.0
DeleteAllSessions removes all sessions from the database.
func (*Store) DeleteAuditOlderThan ¶ added in v0.18.0
DeleteAuditOlderThan removes audit entries older than the given time. Returns the number of deleted entries.
func (*Store) DeleteExpiredSessions ¶ added in v0.11.0
DeleteExpiredSessions removes all expired sessions. Returns the number of sessions deleted.
func (*Store) DeleteSession ¶ added in v0.11.0
DeleteSession removes a session by token. Returns nil even if the session doesn't exist (idempotent).
func (*Store) DeleteSessionsByUsername ¶ added in v0.12.0
DeleteSessionsByUsername removes all sessions for a specific user. Returns nil even if the user has no sessions (idempotent).
func (*Store) Get ¶
Get retrieves the value for the given key. Returns ErrNotFound if the key does not exist. Returns ErrSecretsNotConfigured if key is a secret path but secrets are not enabled.
func (*Store) GetInfo ¶ added in v0.8.2
GetInfo retrieves metadata for the given key without loading the value. Returns ErrNotFound if the key does not exist. Returns ErrSecretsNotConfigured if key is a secret path but secrets are not enabled.
func (*Store) GetSession ¶ added in v0.11.0
func (s *Store) GetSession(ctx context.Context, token string) (username string, expiresAt time.Time, err error)
GetSession retrieves session data by token. Returns ErrNotFound if the session doesn't exist or is expired.
func (*Store) GetWithFormat ¶ added in v0.4.0
GetWithFormat retrieves the value and format for the given key. Returns ErrNotFound if the key does not exist. Returns ErrSecretsNotConfigured if key is a secret path but secrets are not enabled.
func (*Store) List ¶
List returns metadata for all keys, with optional filtering by secret flag. SecretsFilterAll returns all keys, SecretsFilterSecretsOnly returns only secrets, SecretsFilterKeysOnly returns only non-secrets.
func (*Store) LogAudit ¶ added in v0.18.0
func (s *Store) LogAudit(ctx context.Context, entry AuditEntry) error
LogAudit inserts an audit entry into the audit_log table.
func (*Store) QueryAudit ¶ added in v0.18.0
func (s *Store) QueryAudit(ctx context.Context, q AuditQuery) ([]AuditEntry, int, error)
QueryAudit retrieves audit entries matching the given filters. Returns entries ordered by timestamp descending (newest first).
func (*Store) SecretsEnabled ¶ added in v0.15.0
SecretsEnabled returns true if the store is configured for secrets encryption.
func (*Store) Set ¶
func (s *Store) Set(ctx context.Context, key string, value []byte, format string) (created bool, err error)
Set stores the value for the given key with the specified format. Creates a new key or updates an existing one. If format is empty, defaults to "text". Returns ErrSecretsNotConfigured if key is a secret path but secrets are not enabled. Returns (true, nil) if a new key was created, (false, nil) if an existing key was updated.
func (*Store) SetWithVersion ¶ added in v0.10.1
func (s *Store) SetWithVersion(ctx context.Context, key string, value []byte, format string, expectedVersion time.Time) error
SetWithVersion stores the value only if the key's updated_at matches expectedVersion. Returns *ConflictError with current state if the key was modified since expectedVersion. If expectedVersion is zero, behaves like regular Set (no version check). Returns ErrSecretsNotConfigured if key is a secret path but secrets are not enabled.