vault

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

README

Vault

GitHub release Go Reference

A Go package for secure secret storage with multiple encryption backends. Made for flow but can be used independently.

Quick Start

package main

import (
    "fmt"
    "github.com/flowexec/vault"
)

func main() {
    // Create a new AES vault
    v, err := vault.New("my-vault",
        vault.WithProvider(vault.ProviderTypeAES256),
        vault.WithLocalPath("/path/to/vault/storage"),
        vault.WithAESKeyFromEnv("VAULT_KEY"),
    )
    if err != nil {
        panic(err)
    }
    defer v.Close()

    // Store a secret
    secret := vault.NewSecretValue([]byte("my-secret-value"))
    err = v.SetSecret("api-key", secret)
    if err != nil {
        panic(err)
    }

    // Retrieve a secret
    retrieved, err := v.GetSecret("api-key")
    if err != nil {
        panic(err)
    }
    fmt.Println("Secret:", retrieved.PlainTextString())
}

Providers

AES256 Provider

Symmetric encryption using AES-256. Best for when you want a single encryption key shared across users / systems.

Key Generation:

key, err := vault.GenerateEncryptionKey()
if err != nil {
    panic(err)
}
// Store this key securely and configure vault to use it
Age Provider

Asymmetric encryption using the age encryption format. Best for when you may have multiple users or need the ability to add/remove recipients.

Key Generation:

# Generate age key pair - see https://github.com/FiloSottile/age for details
age-keygen -o key.txt
# Public key: age1ql3blv6a5y...
# Private key in key.txt

Encrypted Files

Both vault types create a single encrypted file at the specified path:

  • AES256: vault-{id}.enc
  • Age: vault-{id}.age

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrSecretNotFound   = errors.New("secret not found")
	ErrInvalidKey       = errors.New("invalid secret key")
	ErrNoAccess         = errors.New("access denied")
	ErrInvalidConfig    = errors.New("invalid configuration")
	ErrVaultNotFound    = errors.New("vault not found")
	ErrDecryptionFailed = errors.New("decryption failed")
	ErrInvalidRecipient = errors.New("invalid recipient")
	ErrPathNotSecure    = errors.New("path is not secure")
)
View Source
var (
	DefaultVaultKeyEnv = "VAULT_KEY"
)

Functions

func DeriveEncryptionKey

func DeriveEncryptionKey(passphrase, sal string) (string, string, error)

DeriveEncryptionKey derives an AES encryption key from a passphrase

func GenerateEncryptionKey

func GenerateEncryptionKey() (string, error)

GenerateEncryptionKey generates a new AES encryption key

func New

func New(id string, opts ...Option) (Provider, *Config, error)

New creates a new vault instance with the provided ID and options

func SaveConfigJSON

func SaveConfigJSON(config Config, path string) error

SaveConfigJSON saves the vault configuration to a file in JSON format

func ValidateEncryptionKey

func ValidateEncryptionKey(key string) error

ValidateEncryptionKey checks if a key is valid by attempting to encrypt/decrypt test data

func ValidateSecretKey

func ValidateSecretKey(reference string) error

Types

type AES256Vault

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

AES256Vault manages operations on an instance of a local vault backed by AES256 symmetric encryption.

func NewAES256Vault

func NewAES256Vault(cfg *Config) (*AES256Vault, error)

func (*AES256Vault) Close

func (v *AES256Vault) Close() error

func (*AES256Vault) DeleteSecret

func (v *AES256Vault) DeleteSecret(key string) error

func (*AES256Vault) GetSecret

func (v *AES256Vault) GetSecret(key string) (Secret, error)

func (*AES256Vault) HasSecret

func (v *AES256Vault) HasSecret(key string) (bool, error)

func (*AES256Vault) ID

func (v *AES256Vault) ID() string

func (*AES256Vault) ListSecrets

func (v *AES256Vault) ListSecrets() ([]string, error)

func (*AES256Vault) Metadata

func (v *AES256Vault) Metadata() Metadata

func (*AES256Vault) SetSecret

func (v *AES256Vault) SetSecret(key string, secret Secret) error

type AESState

type AESState struct {
	Metadata `yaml:"metadata"`

	Version int               `json:"version"`
	ID      string            `yaml:"id"`
	Secrets map[string]string `yaml:"secrets"`
}

AESState represents the state of the local AES256 vault.

type AesConfig

type AesConfig struct {
	// Storage location for the vault file
	StoragePath string `json:"storage_path"`
	// DEK sources for decryption (in order of preference)
	KeySource []KeySource `json:"key_sources,omitempty"`
}

AesConfig contains local (AES256-based) vault configuration

func (*AesConfig) Validate

func (c *AesConfig) Validate() error

type AgeConfig

type AgeConfig struct {
	// Storage location for the vault file
	StoragePath string `json:"storage_path"`

	// Identity sources for decryption (in order of preference)
	IdentitySources []IdentitySource `json:"identity_sources,omitempty"`

	// Recipients who can decrypt secrets
	Recipients []string `json:"recipients,omitempty"`
}

AgeConfig contains local (age-based) vault configuration

func (*AgeConfig) Validate

func (c *AgeConfig) Validate() error

type AgeState

type AgeState struct {
	Metadata `json:"metadata"`

	Version    int               `json:"version"`
	ID         string            `json:"id"`
	Recipients []string          `json:"recipients"`
	Secrets    map[string]string `json:"secrets"`
}

AgeState represents the state of the local age vault

type AgeVault

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

AgeVault manages operations on an instance of a local vault backed by age encryption.

func NewAgeVault

func NewAgeVault(cfg *Config) (*AgeVault, error)

func (*AgeVault) AddRecipient

func (v *AgeVault) AddRecipient(publicKey string) error

func (*AgeVault) Close

func (v *AgeVault) Close() error

func (*AgeVault) DeleteSecret

func (v *AgeVault) DeleteSecret(key string) error

func (*AgeVault) GetSecret

func (v *AgeVault) GetSecret(key string) (Secret, error)

func (*AgeVault) HasSecret

func (v *AgeVault) HasSecret(key string) (bool, error)

func (*AgeVault) ID

func (v *AgeVault) ID() string

func (*AgeVault) ListRecipients

func (v *AgeVault) ListRecipients() ([]string, error)

func (*AgeVault) ListSecrets

func (v *AgeVault) ListSecrets() ([]string, error)

func (*AgeVault) Metadata

func (v *AgeVault) Metadata() Metadata

func (*AgeVault) RemoveRecipient

func (v *AgeVault) RemoveRecipient(publicKey string) error

func (*AgeVault) SetSecret

func (v *AgeVault) SetSecret(key string, value Secret) error

type CommandSet

type CommandSet struct {
	Get    string `json:"get"`
	Set    string `json:"set"`
	Delete string `json:"delete"`
	List   string `json:"list"`
	Exists string `json:"exists,omitempty"`
}

CommandSet defines the command templates for external vault operations

type Config

type Config struct {
	ID       string          `json:"id"`
	Type     ProviderType    `json:"type"`
	Age      *AgeConfig      `json:"age,omitempty"`
	Aes      *AesConfig      `json:"aes,omitempty"`
	External *ExternalConfig `json:"external,omitempty"`
}

func LoadConfigJSON

func LoadConfigJSON(path string) (Config, error)

LoadConfigJSON loads the vault configuration from a file in JSON format

func (*Config) Validate

func (c *Config) Validate() error

type ExternalConfig

type ExternalConfig struct {
	// Command templates for operations
	Commands CommandSet `json:"commands"`

	// Environment variables for commands
	Environment map[string]string `json:"environment,omitempty"`

	// Timeout for command execution
	Timeout time.Duration `json:"timeout,omitempty"`

	// WorkingDir for command execution
	WorkingDir string `json:"working_dir,omitempty"`
}

ExternalConfig contains external (cli command-based) vault configuration

func (*ExternalConfig) Validate

func (c *ExternalConfig) Validate() error

type ExternalVaultProvider

type ExternalVaultProvider struct {
}

func (*ExternalVaultProvider) Close

func (v *ExternalVaultProvider) Close() error

func (*ExternalVaultProvider) DeleteSecret

func (v *ExternalVaultProvider) DeleteSecret(key string) error

func (*ExternalVaultProvider) GetSecret

func (v *ExternalVaultProvider) GetSecret(_ string) (Secret, error)

func (*ExternalVaultProvider) HasSecret

func (v *ExternalVaultProvider) HasSecret(key string) (bool, error)

func (*ExternalVaultProvider) ID

func (v *ExternalVaultProvider) ID() string

func (*ExternalVaultProvider) ListSecrets

func (v *ExternalVaultProvider) ListSecrets() ([]string, error)

func (*ExternalVaultProvider) SetSecret

func (v *ExternalVaultProvider) SetSecret(key string, value Secret) error

type IdentityResolver

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

func NewIdentityResolver

func NewIdentityResolver(sources []IdentitySource) *IdentityResolver

func (*IdentityResolver) ResolveIdentities

func (r *IdentityResolver) ResolveIdentities() ([]age.Identity, error)

type IdentitySource

type IdentitySource struct {
	// Type of identity source
	// Must be one of: "env", "file"
	Type string `json:"type"`
	// Path to the identity file (for "file" type)
	Path string `json:"fullPath,omitempty"`
	// Environment variable name (for "env" type)
	Name string `json:"name,omitempty"`
}

IdentitySource represents a source for the local vault identity keys

type KeyResolver

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

func NewKeyResolver

func NewKeyResolver(sources []KeySource) *KeyResolver

func (*KeyResolver) ResolveKeys

func (r *KeyResolver) ResolveKeys() ([]string, error)

func (*KeyResolver) TryDecrypt

func (r *KeyResolver) TryDecrypt(encryptedData string) (string, string, error)

type KeySource

type KeySource struct {
	// Type of data encryption key source
	// Must be one of: "env", "file"
	Type string `json:"type"`
	// Path to the identity file (for "file" type)
	Path string `json:"fullPath,omitempty"`
	// Environment variable name (for "env" type)
	Name string `json:"name,omitempty"`
}

KeySource represents a source for the local vault encryption keys

type Metadata

type Metadata struct {
	Created      time.Time `json:"created"`
	LastModified time.Time `json:"lastModified"`
}

type Option

type Option func(*Config)

func WithAESKeyFromEnv

func WithAESKeyFromEnv(envVar string) Option

WithAESKeyFromEnv specifies to retrieve the AES key from an environment variable

func WithAESKeyFromFile

func WithAESKeyFromFile(path string) Option

WithAESKeyFromFile specifies to retrieve the AES key from a file

func WithAESPath

func WithAESPath(path string) Option

WithAESPath sets the AES vault storage path

func WithAgeIdentityFromEnv

func WithAgeIdentityFromEnv(envVar string) Option

WithAgeIdentityFromEnv specifies to retrieve the age identity from an environment variable

func WithAgeIdentityFromFile

func WithAgeIdentityFromFile(path string) Option

WithAgeIdentityFromFile specifies to retrieve the age identity from a file

func WithAgePath

func WithAgePath(path string) Option

WithAgePath sets the age vault storage path

func WithAgeRecipients

func WithAgeRecipients(recipients ...string) Option

WithAgeRecipients sets the recipients for age vaults

func WithExternalConfig

func WithExternalConfig(cfg *ExternalConfig) Option

WithExternalConfig sets the external vault configuration. FOR TESTING PURPOSES ONLY. TODO: break this down when the external provider is fully implemented

func WithLocalPath

func WithLocalPath(path string) Option

WithLocalPath sets the local vault storage path (works for both Age and AES based on provider type)

func WithProvider

func WithProvider(provider ProviderType) Option

WithProvider sets the vault provider type

type Provider

type Provider interface {
	GetSecret(key string) (Secret, error)
	SetSecret(key string, value Secret) error
	DeleteSecret(key string) error
	ListSecrets() ([]string, error)
	HasSecret(key string) (bool, error)

	// ID returns a unique identifier for this vault instance
	ID() string

	// Metadata returns vault metadata such as creation time
	Metadata() Metadata

	Close() error
}

type ProviderType

type ProviderType string
const (
	ProviderTypeAES256   ProviderType = "aes256"
	ProviderTypeAge      ProviderType = "age"
	ProviderTypeExternal ProviderType = "external"
)

type RecipientManager

type RecipientManager interface {
	AddRecipient(identity string) error
	RemoveRecipient(identity string) error
	ListRecipients() ([]string, error)
}

func HasRecipientManagement

func HasRecipientManagement(v Provider) (RecipientManager, bool)

type Secret

type Secret interface {
	// PlainTextString returns the decrypted value as a string
	PlainTextString() string

	// String returns a masked representation for display
	String() string

	// Bytes returns the raw byte representation of the secret
	Bytes() []byte

	// Zero securely clears the secret from memory
	Zero()
}

type SecretValue

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

func NewSecretValue

func NewSecretValue(value []byte) *SecretValue

func (*SecretValue) Bytes

func (s *SecretValue) Bytes() []byte

func (*SecretValue) PlainTextString

func (s *SecretValue) PlainTextString() string

func (*SecretValue) String

func (s *SecretValue) String() string

func (*SecretValue) Zero

func (s *SecretValue) Zero()

type SecureBytes

type SecureBytes []byte

SecureBytes is a wrapper around []byte that provides secure memory handling

func (SecureBytes) Copy

func (s SecureBytes) Copy() SecureBytes

Copy creates a secure copy of the bytes

func (*SecureBytes) Zero

func (s *SecureBytes) Zero()

Zero securely clears the byte slice

type VaultPathError

type VaultPathError struct {
	Path string
	Err  error
}

func NewVaultPathError

func NewVaultPathError(path string) *VaultPathError

func (*VaultPathError) Error

func (e *VaultPathError) Error() string

func (*VaultPathError) Unwrap

func (e *VaultPathError) Unwrap() error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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