mongo

package
v1.8.2 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package mongo provides a Grove ORM MongoDB implementation of all Vault store interfaces.

Index

Constants

This section is empty.

Variables

View Source
var Migrations = migrate.NewGroup("vault")

Migrations is the grove migration group for the Vault mongo store.

Functions

This section is empty.

Types

type AuditModel

type AuditModel struct {
	grove.BaseModel `grove:"table:vault_audit"`
	ID              string         `grove:"id,pk"              bson:"_id"`
	Action          string         `grove:"action,notnull"     bson:"action"`
	Resource        string         `grove:"resource,notnull"   bson:"resource"`
	Key             string         `grove:"key"                bson:"key"`
	AppID           string         `grove:"app_id"             bson:"app_id"`
	TenantID        string         `grove:"tenant_id"          bson:"tenant_id"`
	UserID          string         `grove:"user_id"            bson:"user_id"`
	IP              string         `grove:"ip"                 bson:"ip"`
	Outcome         string         `grove:"outcome"            bson:"outcome"`
	Metadata        map[string]any `grove:"metadata"           bson:"metadata,omitempty"`
	CreatedAt       time.Time      `grove:"created_at,notnull" bson:"created_at"`
}

AuditModel is the Grove model for vault_audit (MongoDB).

type ConfigModel

type ConfigModel struct {
	grove.BaseModel `grove:"table:vault_config"`
	ID              string            `grove:"id,pk"              bson:"_id"`
	Key             string            `grove:"key,notnull"        bson:"key"`
	Value           any               `grove:"value"              bson:"value"`
	ValueType       string            `grove:"value_type"         bson:"value_type"`
	Version         int64             `grove:"version,notnull"    bson:"version"`
	Description     string            `grove:"description"        bson:"description"`
	AppID           string            `grove:"app_id,notnull"     bson:"app_id"`
	Metadata        map[string]string `grove:"metadata"           bson:"metadata,omitempty"`
	CreatedAt       time.Time         `grove:"created_at,notnull" bson:"created_at"`
	UpdatedAt       time.Time         `grove:"updated_at,notnull" bson:"updated_at"`
}

ConfigModel is the Grove model for vault_config (MongoDB).

type ConfigVersionModel

type ConfigVersionModel struct {
	grove.BaseModel `grove:"table:vault_config_versions"`
	ID              string    `grove:"id,pk"              bson:"_id"`
	ConfigKey       string    `grove:"config_key,notnull" bson:"config_key"`
	AppID           string    `grove:"app_id,notnull"     bson:"app_id"`
	Version         int64     `grove:"version,notnull"    bson:"version"`
	Value           any       `grove:"value"              bson:"value"`
	CreatedBy       string    `grove:"created_by"         bson:"created_by"`
	CreatedAt       time.Time `grove:"created_at,notnull" bson:"created_at"`
}

ConfigVersionModel is the Grove model for vault_config_versions (MongoDB).

type FlagModel

type FlagModel struct {
	grove.BaseModel `grove:"table:vault_flags"`
	ID              string            `grove:"id,pk"              bson:"_id"`
	Key             string            `grove:"key,notnull"        bson:"key"`
	Type            string            `grove:"type,notnull"       bson:"type"`
	DefaultValue    any               `grove:"default_value"      bson:"default_value"`
	Description     string            `grove:"description"        bson:"description"`
	Tags            []string          `grove:"tags"               bson:"tags,omitempty"`
	Variants        []flag.Variant    `grove:"variants"           bson:"variants,omitempty"`
	Enabled         bool              `grove:"enabled,notnull"    bson:"enabled"`
	AppID           string            `grove:"app_id,notnull"     bson:"app_id"`
	Metadata        map[string]string `grove:"metadata"           bson:"metadata,omitempty"`
	CreatedAt       time.Time         `grove:"created_at,notnull" bson:"created_at"`
	UpdatedAt       time.Time         `grove:"updated_at,notnull" bson:"updated_at"`
}

FlagModel is the Grove model for vault_flags (MongoDB).

type FlagOverrideModel

type FlagOverrideModel struct {
	grove.BaseModel `grove:"table:vault_flag_overrides"`
	ID              string    `grove:"id,pk"              bson:"_id"`
	FlagKey         string    `grove:"flag_key,notnull"   bson:"flag_key"`
	AppID           string    `grove:"app_id,notnull"     bson:"app_id"`
	TenantID        string    `grove:"tenant_id,notnull"  bson:"tenant_id"`
	Value           any       `grove:"value"              bson:"value"`
	CreatedAt       time.Time `grove:"created_at,notnull" bson:"created_at"`
	UpdatedAt       time.Time `grove:"updated_at,notnull" bson:"updated_at"`
}

FlagOverrideModel is the Grove model for vault_flag_overrides (MongoDB).

type FlagRuleModel

type FlagRuleModel struct {
	grove.BaseModel `grove:"table:vault_flag_rules"`
	ID              string          `grove:"id,pk"              bson:"_id"`
	FlagKey         string          `grove:"flag_key,notnull"   bson:"flag_key"`
	AppID           string          `grove:"app_id,notnull"     bson:"app_id"`
	Priority        int             `grove:"priority,notnull"   bson:"priority"`
	Type            string          `grove:"type,notnull"       bson:"type"`
	Config          flag.RuleConfig `grove:"config"             bson:"config,omitempty"`
	ReturnValue     any             `grove:"return_value"       bson:"return_value"`
	CreatedAt       time.Time       `grove:"created_at,notnull" bson:"created_at"`
	UpdatedAt       time.Time       `grove:"updated_at,notnull" bson:"updated_at"`
}

FlagRuleModel is the Grove model for vault_flag_rules (MongoDB).

type OverrideModel

type OverrideModel struct {
	grove.BaseModel `grove:"table:vault_overrides"`
	ID              string            `grove:"id,pk"              bson:"_id"`
	Key             string            `grove:"key,notnull"        bson:"key"`
	Value           any               `grove:"value"              bson:"value"`
	AppID           string            `grove:"app_id,notnull"     bson:"app_id"`
	TenantID        string            `grove:"tenant_id,notnull"  bson:"tenant_id"`
	Metadata        map[string]string `grove:"metadata"           bson:"metadata,omitempty"`
	CreatedAt       time.Time         `grove:"created_at,notnull" bson:"created_at"`
	UpdatedAt       time.Time         `grove:"updated_at,notnull" bson:"updated_at"`
}

OverrideModel is the Grove model for vault_overrides (MongoDB).

type RotationPolicyModel

type RotationPolicyModel struct {
	grove.BaseModel `grove:"table:vault_rotation_policies"`
	ID              string     `grove:"id,pk"                bson:"_id"`
	SecretKey       string     `grove:"secret_key,notnull"   bson:"secret_key"`
	AppID           string     `grove:"app_id,notnull"       bson:"app_id"`
	IntervalNS      int64      `grove:"interval_ns,notnull"  bson:"interval_ns"`
	Enabled         bool       `grove:"enabled,notnull"      bson:"enabled"`
	LastRotatedAt   *time.Time `grove:"last_rotated_at"      bson:"last_rotated_at,omitempty"`
	NextRotationAt  *time.Time `grove:"next_rotation_at"     bson:"next_rotation_at,omitempty"`
	CreatedAt       time.Time  `grove:"created_at,notnull"   bson:"created_at"`
	UpdatedAt       time.Time  `grove:"updated_at,notnull"   bson:"updated_at"`
}

RotationPolicyModel is the Grove model for vault_rotation_policies (MongoDB).

type RotationRecordModel

type RotationRecordModel struct {
	grove.BaseModel `grove:"table:vault_rotation_records"`
	ID              string    `grove:"id,pk"              bson:"_id"`
	SecretKey       string    `grove:"secret_key,notnull" bson:"secret_key"`
	AppID           string    `grove:"app_id,notnull"     bson:"app_id"`
	OldVersion      int64     `grove:"old_version,notnull" bson:"old_version"`
	NewVersion      int64     `grove:"new_version,notnull" bson:"new_version"`
	RotatedBy       string    `grove:"rotated_by"         bson:"rotated_by"`
	RotatedAt       time.Time `grove:"rotated_at,notnull" bson:"rotated_at"`
}

RotationRecordModel is the Grove model for vault_rotation_records (MongoDB).

type SecretModel

type SecretModel struct {
	grove.BaseModel `grove:"table:vault_secrets"`
	ID              string            `grove:"id,pk"              bson:"_id"`
	Key             string            `grove:"key,notnull"        bson:"key"`
	AppID           string            `grove:"app_id,notnull"     bson:"app_id"`
	TenantID        string            `grove:"tenant_id"          bson:"tenant_id"`
	EncryptedValue  []byte            `grove:"encrypted_value"    bson:"encrypted_value"`
	EncryptionAlg   string            `grove:"encryption_alg"     bson:"encryption_alg"`
	EncryptionKeyID string            `grove:"encryption_key_id"  bson:"encryption_key_id"`
	Version         int64             `grove:"version,notnull"    bson:"version"`
	Metadata        map[string]string `grove:"metadata"           bson:"metadata,omitempty"`
	ExpiresAt       *time.Time        `grove:"expires_at"         bson:"expires_at,omitempty"`
	CreatedAt       time.Time         `grove:"created_at,notnull" bson:"created_at"`
	UpdatedAt       time.Time         `grove:"updated_at,notnull" bson:"updated_at"`
}

SecretModel is the Grove model for vault_secrets (MongoDB).

TenantID is not notnull on purpose. A validator generated from this model would then require the field, and a replica of a release from before tenants, which never writes it, would have its inserts refused while a rollout is under way. Reads treat a missing tenant_id as "" (see tenantMatch), and the migration writes "" into every old document.

type SecretVersionModel

type SecretVersionModel struct {
	grove.BaseModel `grove:"table:vault_secret_versions"`
	ID              string    `grove:"id,pk"              bson:"_id"`
	SecretKey       string    `grove:"secret_key,notnull" bson:"secret_key"`
	AppID           string    `grove:"app_id,notnull"     bson:"app_id"`
	TenantID        string    `grove:"tenant_id"          bson:"tenant_id"`
	Version         int64     `grove:"version,notnull"    bson:"version"`
	EncryptedValue  []byte    `grove:"encrypted_value"    bson:"encrypted_value"`
	EncryptionAlg   *string   `grove:"encryption_alg"     bson:"encryption_alg,omitempty"`
	CreatedBy       string    `grove:"created_by"         bson:"created_by"`
	CreatedAt       time.Time `grove:"created_at,notnull" bson:"created_at"`
}

SecretVersionModel is the Grove model for vault_secret_versions (MongoDB).

EncryptionAlg's omitempty has no effect: grove writes a nil pointer as an explicit null. Rows from before the field existed have no field at all. Both mean "never recorded", so filters for it use {encryption_alg: null}, which matches both, and never {$exists: false}.

type Store

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

Store is a Grove ORM MongoDB implementation of all Vault store interfaces.

func New

func New(db *grove.DB, opts ...StoreOption) *Store

New creates a new MongoDB store backed by Grove ORM.

func (*Store) ClaimDueRotation

func (s *Store) ClaimDueRotation(ctx context.Context, key, appID string, now, until time.Time) (bool, error)

ClaimDueRotation claims a due policy for one rotation run. It is a single UpdateOne whose filter carries the whole due test, and MongoDB applies a single-document update atomically, so only one of several concurrent callers can match a given due time. $lt never matches a missing or null next_rotation_at. A missing policy returns false and a nil error.

func (*Store) Close

func (s *Store) Close() error

Close closes the database connection.

func (*Store) CountAudit

func (s *Store) CountAudit(ctx context.Context, appID string) (int64, error)

CountAudit returns the number of audit entries belonging to appID.

func (*Store) CountAuditMatching

func (s *Store) CountAuditMatching(ctx context.Context, appID string, opts audit.ListOpts) (int64, error)

CountAuditMatching returns the number of audit entries belonging to appID that match opts. Limit and Offset are ignored.

func (*Store) CountConfig

func (s *Store) CountConfig(ctx context.Context, appID string) (int64, error)

CountConfig returns the number of config entries belonging to appID.

func (*Store) CountConfigMatching

func (s *Store) CountConfigMatching(ctx context.Context, appID string, opts cfgpkg.ListOpts) (int64, error)

CountConfigMatching returns the number of config entries belonging to appID whose key starts with opts.KeyPrefix. Limit and Offset are ignored.

func (*Store) CountFlagDefinitions

func (s *Store) CountFlagDefinitions(ctx context.Context, appID string) (int64, error)

CountFlagDefinitions returns the number of flag definitions belonging to appID.

func (*Store) CountFlagDefinitionsMatching

func (s *Store) CountFlagDefinitionsMatching(ctx context.Context, appID string, opts flag.ListOpts) (int64, error)

CountFlagDefinitionsMatching returns the number of flag definitions belonging to appID that match opts. Limit and Offset are ignored.

func (*Store) CountOverrides

func (s *Store) CountOverrides(ctx context.Context, appID string) (int64, error)

CountOverrides returns the number of tenant overrides belonging to appID.

func (*Store) CountRotationPolicies

func (s *Store) CountRotationPolicies(ctx context.Context, appID string) (int64, error)

CountRotationPolicies returns the number of rotation policies belonging to appID.

func (*Store) CountSecrets

func (s *Store) CountSecrets(ctx context.Context, appID string) (int64, error)

CountSecrets returns the number of secrets belonging to appID, across every tenant.

func (*Store) CountSecretsMatching

func (s *Store) CountSecretsMatching(ctx context.Context, appID string, opts secret.ListOpts) (int64, error)

CountSecretsMatching returns the number of secrets belonging to appID, across every tenant, that pass the expiry bounds in opts. TenantID, Limit and Offset are ignored.

func (*Store) CountSecretsUnencrypted

func (s *Store) CountSecretsUnencrypted(ctx context.Context, appID string) (int64, error)

CountSecretsUnencrypted returns the number of secrets belonging to appID, across every tenant, that were stored without an encryption algorithm. A document with no encryption_alg field at all is unencrypted too, so the filter matches both an empty string and a missing field.

func (*Store) CountVersionEncryption

func (s *Store) CountVersionEncryption(ctx context.Context, appID string) (secret.VersionEncryptionCounts, error)

CountVersionEncryption tallies appID's version rows, across every tenant, by recorded algorithm, leaving out each secret's current version. Only plaintext and unrecorded rows reach the $lookup; it drops a row whose secret's current version is that row's version. {encryption_alg: null} inside $in also matches a row with no field at all.

The $lookup matches a row to its secret by key, app and tenant: matching on key and app alone would let one tenant's current version hide another tenant's earlier row with the same number. Both sides read a missing tenant_id as "", the app-level tenant, as tenantMatch does.

func (*Store) DB

func (s *Store) DB() *grove.DB

DB returns the underlying grove database for direct access.

func (*Store) DefineFlag

func (s *Store) DefineFlag(ctx context.Context, f *flag.Definition) error

DefineFlag creates or updates a flag definition.

func (*Store) DeleteConfig

func (s *Store) DeleteConfig(ctx context.Context, key, appID string) error

DeleteConfig removes a config entry's versions, then the entry.

Mongo has no transaction here, so the order is the guarantee: the entry goes last. If the version delete fails, the entry is still there and a retry finds it and cleans up again. Deleting the entry first would make that retry return ErrConfigNotFound before it reached the versions, and the orphaned versions would collide with the unique (config_key, app_id, version) index when the key is recreated at version 1.

ErrConfigNotFound is returned only when nothing at all was deleted, so a retry after a partial failure succeeds.

func (*Store) DeleteFlagDefinition

func (s *Store) DeleteFlagDefinition(ctx context.Context, key, appID string) error

DeleteFlagDefinition removes a flag's rules and overrides, then the flag.

Mongo has no transaction here, so the order is the guarantee: the definition goes last. If a cleanup delete fails, the definition is still there and a retry finds it and cleans up again. Deleting the definition first would make that retry return ErrFlagNotFound before it reached the cleanup, and the orphaned rules and overrides would attach to any flag later created with the same key.

ErrFlagNotFound is returned only when the definition was already gone and this call removed nothing, so a retry after a partial failure succeeds.

func (*Store) DeleteFlagTenantOverride

func (s *Store) DeleteFlagTenantOverride(ctx context.Context, key, appID, tenantID string) error

DeleteFlagTenantOverride removes a tenant override.

func (*Store) DeleteOverride

func (s *Store) DeleteOverride(ctx context.Context, key, appID, tenantID string) error

DeleteOverride removes a tenant override.

func (*Store) DeleteRotationPolicy

func (s *Store) DeleteRotationPolicy(ctx context.Context, key, appID string) error

DeleteRotationPolicy removes a rotation policy.

func (*Store) DeleteSecret

func (s *Store) DeleteSecret(ctx context.Context, key, appID, tenantID string) error

DeleteSecret removes a secret and all its versions, in one app and tenant.

func (*Store) GetConfig

func (s *Store) GetConfig(ctx context.Context, key, appID string) (*cfgpkg.Entry, error)

GetConfig retrieves a config entry by key and app ID.

func (*Store) GetConfigVersion

func (s *Store) GetConfigVersion(ctx context.Context, key, appID string, version int64) (*cfgpkg.Entry, error)

GetConfigVersion retrieves a specific version of a config entry.

func (*Store) GetFlagDefinition

func (s *Store) GetFlagDefinition(ctx context.Context, key, appID string) (*flag.Definition, error)

GetFlagDefinition retrieves a flag definition.

func (*Store) GetFlagRules

func (s *Store) GetFlagRules(ctx context.Context, key, appID string) ([]*flag.Rule, error)

GetFlagRules returns targeting rules for a flag, ordered by priority.

func (*Store) GetFlagTenantOverride

func (s *Store) GetFlagTenantOverride(ctx context.Context, key, appID, tenantID string) (any, error)

GetFlagTenantOverride retrieves a tenant override for a flag.

func (*Store) GetOverride

func (s *Store) GetOverride(ctx context.Context, key, appID, tenantID string) (*override.Override, error)

GetOverride retrieves a tenant override by key, app ID, and tenant ID.

func (*Store) GetRotationPolicy

func (s *Store) GetRotationPolicy(ctx context.Context, key, appID string) (*rotation.Policy, error)

GetRotationPolicy retrieves a rotation policy by secret key and app ID.

func (*Store) GetSecret

func (s *Store) GetSecret(ctx context.Context, key, appID, tenantID string) (*secret.Secret, error)

GetSecret retrieves the latest version of a secret in one app and tenant.

func (*Store) GetSecretVersion

func (s *Store) GetSecretVersion(ctx context.Context, key, appID, tenantID string, version int64) (*secret.Secret, error)

GetSecretVersion retrieves a specific version of a secret in one app and tenant. The secret and the version row are both looked up by the tenant.

func (*Store) ListAudit

func (s *Store) ListAudit(ctx context.Context, appID string, opts audit.ListOpts) ([]*audit.Entry, error)

ListAudit returns audit entries for an app.

func (*Store) ListAuditByKey

func (s *Store) ListAuditByKey(ctx context.Context, key, appID string, opts audit.ListOpts) ([]*audit.Entry, error)

ListAuditByKey returns audit entries for a specific key within an app.

func (*Store) ListConfig

func (s *Store) ListConfig(ctx context.Context, appID string, opts cfgpkg.ListOpts) ([]*cfgpkg.Entry, error)

ListConfig returns config entries for an app.

func (*Store) ListConfigVersions

func (s *Store) ListConfigVersions(ctx context.Context, key, appID string) ([]*cfgpkg.EntryVersion, error)

ListConfigVersions returns all versions of a config entry.

func (*Store) ListFlagDefinitions

func (s *Store) ListFlagDefinitions(ctx context.Context, appID string, opts flag.ListOpts) ([]*flag.Definition, error)

ListFlagDefinitions returns all flag definitions for an app.

func (*Store) ListFlagTenantOverrides

func (s *Store) ListFlagTenantOverrides(ctx context.Context, key, appID string) ([]*flag.TenantOverride, error)

ListFlagTenantOverrides returns all tenant overrides for a flag.

func (*Store) ListOverridesByKey

func (s *Store) ListOverridesByKey(ctx context.Context, key, appID string) ([]*override.Override, error)

ListOverridesByKey returns all tenant overrides for a specific config key.

func (*Store) ListOverridesByTenant

func (s *Store) ListOverridesByTenant(ctx context.Context, appID, tenantID string) ([]*override.Override, error)

ListOverridesByTenant returns all overrides for a specific tenant.

func (*Store) ListRotationPolicies

func (s *Store) ListRotationPolicies(ctx context.Context, appID string) ([]*rotation.Policy, error)

ListRotationPolicies returns all rotation policies for an app.

func (*Store) ListRotationRecords

func (s *Store) ListRotationRecords(ctx context.Context, key, appID string, opts rotation.ListOpts) ([]*rotation.Record, error)

ListRotationRecords returns rotation history for a secret.

func (*Store) ListSecretVersions

func (s *Store) ListSecretVersions(ctx context.Context, key, appID, tenantID string) ([]*secret.Version, error)

ListSecretVersions returns all versions of a secret in one app and tenant.

func (*Store) ListSecrets

func (s *Store) ListSecrets(ctx context.Context, appID string, opts secret.ListOpts) ([]*secret.Meta, error)

ListSecrets returns secret metadata for an app and the tenant in opts.TenantID, matched exactly.

func (*Store) ListUnrecordedVersions

func (s *Store) ListUnrecordedVersions(ctx context.Context, appID, after string, limit int) ([]*secret.Version, error)

ListUnrecordedVersions returns up to limit version rows of appID, across every tenant, whose encryption algorithm was never recorded, in ascending id order, after the id after. A missing field and a null both count as never recorded: the filter {encryption_alg: null} matches both.

func (*Store) Migrate

func (s *Store) Migrate(ctx context.Context) error

Migrate creates indexes for all vault collections, and scopes the secret collections by tenant the way "scope_secrets_by_tenant" does.

func (*Store) Ping

func (s *Store) Ping(ctx context.Context) error

Ping checks database connectivity.

func (*Store) RecordAudit

func (s *Store) RecordAudit(ctx context.Context, e *audit.Entry) error

RecordAudit persists an audit log entry.

func (*Store) RecordRotation

func (s *Store) RecordRotation(ctx context.Context, r *rotation.Record) error

RecordRotation records a completed rotation event.

func (*Store) SaveRotationPolicy

func (s *Store) SaveRotationPolicy(ctx context.Context, p *rotation.Policy) error

SaveRotationPolicy creates or updates a rotation policy.

func (*Store) SetConfig

func (s *Store) SetConfig(ctx context.Context, e *cfgpkg.Entry) error

SetConfig creates or updates a config entry with auto-versioning.

func (*Store) SetFlagRules

func (s *Store) SetFlagRules(ctx context.Context, key, appID string, rules []*flag.Rule) error

SetFlagRules replaces all targeting rules for a flag.

func (*Store) SetFlagTenantOverride

func (s *Store) SetFlagTenantOverride(ctx context.Context, key, appID, tenantID string, value any) error

SetFlagTenantOverride sets a direct per-tenant override value.

func (*Store) SetOverride

func (s *Store) SetOverride(ctx context.Context, o *override.Override) error

SetOverride creates or updates a tenant override.

func (*Store) SetSecret

func (s *Store) SetSecret(ctx context.Context, sec *secret.Secret) error

SetSecret creates or updates a secret with auto-versioning.

func (*Store) SetVersionEncryption

func (s *Store) SetVersionEncryption(ctx context.Context, versionID id.ID, alg string) error

SetVersionEncryption records the algorithm of the version row with the given id. An unknown id updates nothing and is not an error.

type StoreOption

type StoreOption func(*Store)

StoreOption configures the Store.

func WithLogger

func WithLogger(l log.Logger) StoreOption

WithLogger sets the logger for the store.

Jump to

Keyboard shortcuts

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