vaultstore

package module
v0.32.0 Latest Latest
Warning

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

Go to latest
Published: Feb 11, 2026 License: AGPL-3.0 Imports: 34 Imported by: 0

README ΒΆ

Vault Store

Tests Status Go Report Card PkgGoDev

Vault - a secure value storage (data-at-rest) implementation for Go.

Scope

VaultStore is specifically designed as a data store component for securely storing and retrieving secrets. It is not an API or a complete secrets management system. Features such as user management, access control, and API endpoints are intentionally beyond the scope of this project.

VaultStore is meant to be integrated into your application as a library, providing the data storage layer for your secrets management needs. The application using VaultStore is responsible for implementing any additional layers such as API endpoints, user management, or access control if needed.

Documentation

Features

  • Secure storage of sensitive data
  • Token-based access to secrets
  • Password protection for stored values
  • Password rotation
  • Flexible query interface for retrieving records
  • Soft delete functionality for data recovery
  • Support for multiple database backends

License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). You can find a copy of the license at https://www.gnu.org/licenses/agpl-3.0.en.html

For commercial use, please use my contact page to obtain a commercial license.

Installation

go get -u github.com/dracory/vaultstore

Technical Details

For database schema, record structure, and other technical information, please see the Technical Reference.

Setup

vault, err := NewStore(NewStoreOptions{
	VaultTableName:     "my_vault",
	DB:                 databaseInstance,
	AutomigrateEnabled: true,
})

Usage

Here are some basic examples of using VaultStore. For comprehensive documentation, see the Usage Guide.

// Create a token
token, err := vault.TokenCreate("my_value", "my_password", 20)

// Check if a token exists
exists, err := vault.TokenExists(token)

// Read a value using a token
value, err := vault.TokenRead(token, "my_password")

// Update a token's value
err := vault.TokenUpdate(token, "new_value", "my_password")

// Bulk rekey all records with old password to new password
ctx := context.Background()
count, err := vault.BulkRekey(ctx, "old_password", "new_password")

// Hard delete a token
err := vault.TokenDelete(token)

// Soft delete a token
err := vault.TokenSoftDelete(token)

🌏 Development in the Cloud

Click any of the buttons below to start a new development environment to contribute to the codebase without having to install anything on your machine:

Open in GitHub Codespaces Open in Gitpod

Changelog

For a detailed version history and changes, please see the Changelog.

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

View Source
const (
	MAX_DATETIME = "9999-12-31 23:59:59"
	ASC          = "ASC"
	DESC         = "DESC"
)

Database constants (replaces github.com/dracory/sb dependency)

View Source
const (
	COLUMN_OBJECT_TYPE = "object_type"
	COLUMN_OBJECT_ID   = "object_id"
	COLUMN_META_KEY    = "meta_key"
	COLUMN_META_VALUE  = "meta_value"
)

Meta table column constants

View Source
const (
	TOKEN_MIN_PAYLOAD_LENGTH = 12
	TOKEN_MAX_PAYLOAD_LENGTH = 37                                           // 37 chars + tk_ prefix = 40 total
	TOKEN_MIN_TOTAL_LENGTH   = len(TOKEN_PREFIX) + TOKEN_MIN_PAYLOAD_LENGTH // 15
	TOKEN_MAX_TOTAL_LENGTH   = len(TOKEN_PREFIX) + TOKEN_MAX_PAYLOAD_LENGTH // 40
)

Token size constraints

View Source
const (
	OBJECT_TYPE_PASSWORD_IDENTITY = "password_identity"
	OBJECT_TYPE_RECORD            = "record"
	OBJECT_TYPE_VAULT_SETTINGS    = "vault"
)

Object type constants for vault_meta table

View Source
const (
	META_KEY_HASH        = "hash"
	META_KEY_PASSWORD_ID = "password_id"
	META_KEY_VERSION     = "version"
)

Meta key constants

View Source
const (
	ARGON2ID_TIME     = 1         // Minimal passes for faster verification
	ARGON2ID_MEMORY   = 16 * 1024 // 16MB - lightweight for embedded/mobile
	ARGON2ID_THREADS  = 2         // Reduced parallelism
	ARGON2ID_KEY_LEN  = 32        // Hash output length
	ARGON2ID_SALT_LEN = 16        // Salt length
)

Argon2id password hashing parameters (lightweight defaults for broad compatibility) Users can increase these via CryptoConfig for higher security requirements

View Source
const (
	ENCRYPTION_VERSION_V1 = "v1"
	ENCRYPTION_VERSION_V2 = "v2"
	ENCRYPTION_PREFIX_V1  = ENCRYPTION_VERSION_V1 + ":"
	ENCRYPTION_PREFIX_V2  = ENCRYPTION_VERSION_V2 + ":"
)

Encryption version constants for versioned encryption

View Source
const (
	V2_SALT_SIZE       = 16
	V2_NONCE_SIZE      = 12
	V2_TAG_SIZE        = 16
	ARGON2_ITERATIONS  = 3
	ARGON2_MEMORY      = 64 * 1024 // 64MB
	ARGON2_PARALLELISM = 4
	ARGON2_KEY_LENGTH  = 32
)

v2 encryption parameters (AES-GCM + Argon2id)

View Source
const BCRYPT_COST = 12

bcrypt cost for password hashing (legacy - used for backward compatibility)

View Source
const COLUMN_CREATED_AT = "created_at"
View Source
const COLUMN_EXPIRES_AT = "expires_at"
View Source
const COLUMN_ID = "id"
View Source
const COLUMN_SOFT_DELETED_AT = "soft_deleted_at"
View Source
const COLUMN_UPDATED_AT = "updated_at"
View Source
const COLUMN_VAULT_TOKEN = "vault_token"
View Source
const COLUMN_VAULT_VALUE = "vault_value"
View Source
const PASSWORD_ID_PREFIX = "p_"

Password identity ID prefix

View Source
const RECORD_META_ID_PREFIX = "r_"

Record ID prefix (used in meta table)

View Source
const TOKEN_PREFIX = "tk_"
View Source
const (
	VAULT_SETTINGS_ID = "settings"
)

Vault settings constants

Variables ΒΆ

View Source
var ErrPasswordInvalid = errors.New("password does not meet requirements")

ErrPasswordInvalid is returned when password does not meet requirements

View Source
var ErrTokenExpired = errors.New("token has expired")

ErrTokenExpired is returned when a token has expired

Functions ΒΆ

func IsToken ΒΆ

func IsToken(s string) bool

func IsTokenValidLength ΒΆ added in v0.30.0

func IsTokenValidLength(s string) bool

IsTokenValidLength checks if a token has valid format and reasonable length Returns false if token format is invalid or length is outside reasonable bounds

func NewStore ΒΆ

func NewStore(opts NewStoreOptions) (*storeImplementation, error)

NewStore creates a new entity store

Types ΒΆ

type CryptoConfig ΒΆ added in v0.30.0

type CryptoConfig struct {
	// Argon2id parameters
	Iterations  int
	Memory      int // in bytes
	Parallelism int
	KeyLength   int // in bytes

	// AES-GCM parameters
	SaltSize  int // in bytes
	NonceSize int // in bytes
	TagSize   int // in bytes
}

CryptoConfig holds configurable cryptographic parameters

func DefaultCryptoConfig ΒΆ added in v0.30.0

func DefaultCryptoConfig() *CryptoConfig

DefaultCryptoConfig returns secure default cryptographic parameters

func HighSecurityCryptoConfig ΒΆ added in v0.30.0

func HighSecurityCryptoConfig() *CryptoConfig

HighSecurityCryptoConfig returns parameters for high-security scenarios

func LightweightCryptoConfig ΒΆ added in v0.30.0

func LightweightCryptoConfig() *CryptoConfig

LightweightCryptoConfig returns parameters for resource-constrained environments

type MetaInterface ΒΆ added in v0.30.0

type MetaInterface interface {
	Data() map[string]string
	DataChanged() map[string]string

	// Getters
	GetID() uint
	GetObjectType() string
	GetObjectID() string
	GetKey() string
	GetValue() string

	// Setters
	SetID(id uint) MetaInterface
	SetObjectType(objectType string) MetaInterface
	SetObjectID(objectID string) MetaInterface
	SetKey(key string) MetaInterface
	SetValue(value string) MetaInterface
}

MetaInterface defines the methods that a VaultMeta must implement

func NewMeta ΒΆ added in v0.30.0

func NewMeta() MetaInterface

NewMeta creates a new metadata entry

func NewMetaFromExistingData ΒΆ added in v0.30.0

func NewMetaFromExistingData(data map[string]string) MetaInterface

NewMetaFromExistingData creates a metadata entry from existing data

type NewStoreOptions ΒΆ

type NewStoreOptions struct {
	VaultTableName           string
	VaultMetaTableName       string
	DB                       *sql.DB
	DbDriverName             string
	AutomigrateEnabled       bool
	DebugEnabled             bool
	CryptoConfig             *CryptoConfig
	ParallelThreshold        int  // Threshold for parallel processing (0 = use default 10000)
	PasswordAllowEmpty       bool // Allow empty passwords (default: false)
	PasswordMinLength        int  // Minimum password length (default: 16)
	PasswordRequireLowercase bool // Require at least one lowercase letter (default: false)
	PasswordRequireUppercase bool // Require at least one uppercase letter (default: false)
	PasswordRequireNumbers   bool // Require at least one number (default: false)
	PasswordRequireSymbols   bool // Require at least one symbol (default: false)
}

NewStoreOptions define the options for creating a new session store

type RecordInterface ΒΆ

type RecordInterface interface {
	Data() map[string]string
	DataChanged() map[string]string

	// Getters
	GetCreatedAt() string
	GetExpiresAt() string
	GetSoftDeletedAt() string
	GetID() string
	GetToken() string
	GetUpdatedAt() string
	GetValue() string

	// Setters
	SetCreatedAt(createdAt string) RecordInterface
	SetExpiresAt(expiresAt string) RecordInterface
	SetSoftDeletedAt(softDeletedAt string) RecordInterface
	SetID(id string) RecordInterface
	SetToken(token string) RecordInterface
	SetUpdatedAt(updatedAt string) RecordInterface
	SetValue(value string) RecordInterface
}

RecordInterface defines the methods that a Record must implement

func NewRecord ΒΆ

func NewRecord() RecordInterface

func NewRecordFromExistingData ΒΆ

func NewRecordFromExistingData(data map[string]string) RecordInterface

type RecordQueryInterface ΒΆ

type RecordQueryInterface interface {
	Validate() error

	GetColumns() []string
	SetColumns(columns []string) RecordQueryInterface
	IsColumnsSet() bool

	IsIDSet() bool
	GetID() string
	SetID(id string) RecordQueryInterface

	IsIDInSet() bool
	GetIDIn() []string
	SetIDIn(idIn []string) RecordQueryInterface

	IsTokenSet() bool
	GetToken() string
	SetToken(token string) RecordQueryInterface

	IsTokenInSet() bool
	GetTokenIn() []string
	SetTokenIn(tokenIn []string) RecordQueryInterface

	IsOffsetSet() bool
	GetOffset() int
	SetOffset(offset int) RecordQueryInterface

	IsOrderBySet() bool
	GetOrderBy() string
	SetOrderBy(orderBy string) RecordQueryInterface

	IsLimitSet() bool
	GetLimit() int
	SetLimit(limit int) RecordQueryInterface

	IsCountOnlySet() bool
	GetCountOnly() bool
	SetCountOnly(countOnly bool) RecordQueryInterface

	IsSortOrderSet() bool
	GetSortOrder() string
	SetSortOrder(sortOrder string) RecordQueryInterface

	IsSoftDeletedIncludeSet() bool
	GetSoftDeletedInclude() bool
	SetSoftDeletedInclude(softDeletedInclude bool) RecordQueryInterface
}

func RecordQuery ΒΆ

func RecordQuery() RecordQueryInterface

RecordQuery creates a new record query

type StoreInterface ΒΆ

type StoreInterface interface {
	AutoMigrate() error
	EnableDebug(debug bool)

	GetDbDriverName() string
	GetVaultTableName() string
	GetMetaTableName() string

	RecordCount(ctx context.Context, query RecordQueryInterface) (int64, error)
	RecordCreate(ctx context.Context, record RecordInterface) error
	RecordDeleteByID(ctx context.Context, recordID string) error
	RecordDeleteByToken(ctx context.Context, token string) error
	RecordFindByID(ctx context.Context, recordID string) (RecordInterface, error)
	RecordFindByToken(ctx context.Context, token string) (RecordInterface, error)
	RecordList(ctx context.Context, query RecordQueryInterface) ([]RecordInterface, error)
	RecordSoftDelete(ctx context.Context, record RecordInterface) error
	RecordSoftDeleteByID(ctx context.Context, recordID string) error
	RecordSoftDeleteByToken(ctx context.Context, token string) error
	RecordUpdate(ctx context.Context, record RecordInterface) error

	TokenCreate(ctx context.Context, value string, password string, tokenLength int, options ...TokenCreateOptions) (token string, err error)
	TokenCreateCustom(ctx context.Context, token string, value string, password string, options ...TokenCreateOptions) (err error)
	TokenDelete(ctx context.Context, token string) error
	TokenExists(ctx context.Context, token string) (bool, error)
	TokenRead(ctx context.Context, token string, password string) (string, error)
	TokenRenew(ctx context.Context, token string, expiresAt time.Time) error
	TokensExpiredSoftDelete(ctx context.Context) (count int64, err error)
	TokensExpiredDelete(ctx context.Context) (count int64, err error)
	TokenSoftDelete(ctx context.Context, token string) error
	TokenUpdate(ctx context.Context, token string, value string, password string) error
	TokensRead(ctx context.Context, tokens []string, password string) (map[string]string, error)

	// Token-based password management
	TokensChangePassword(ctx context.Context, oldPassword, newPassword string) (int, error)

	// Vault settings
	GetVaultSetting(ctx context.Context, key string) (string, error)
	SetVaultSetting(ctx context.Context, key, value string) error
}

type TokenCreateOptions ΒΆ added in v0.28.0

type TokenCreateOptions struct {
	// ExpiresAt is the expiration time for the token
	// If zero value, token never expires
	ExpiresAt time.Time
}

TokenCreateOptions contains optional parameters for token creation

Jump to

Keyboard shortcuts

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