encryption

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package encryption provides KeyProvider implementations for mfx:"encrypted" struct fields. The two bundled implementations are EnvKeyProvider (keys from environment variables) and VaultKeyProvider (HashiCorp Vault Transit engine).

Envelope format produced by EnvKeyProvider:

[ version:1 ][ keyIDLen:2 BE ][ keyID:N ][ nonce:12 ][ gcmCiphertext:M ]

Stored in the DB as the string "enc:<base64(envelope)>". The "enc:" prefix lets the framework distinguish already-encrypted values from legacy plaintext when a model is being migrated to encryption.

Index

Constants

View Source
const DefaultVaultTimeout = 10 * time.Second

DefaultVaultTimeout bounds a complete Vault HTTP operation when neither the provider nor an injected client supplies a timeout.

Variables

This section is empty.

Functions

This section is empty.

Types

type EnvKeyProvider

type EnvKeyProvider struct {
	// Prefix is prepended to the keyID when building the env var name.
	// Default: "MFX_KEY".
	Prefix string

	// IndexKeyID names a dedicated HMAC key for encrypted fields carrying a
	// UNIQUE constraint. It must not be rotated with field-encryption keys.
	IndexKeyID string
}

EnvKeyProvider loads AES-256-GCM keys from environment variables.

The env var name is built as: {Prefix}_{KEYID_UPPER} where hyphens in keyID are replaced with underscores and everything is uppercased. For example:

Prefix "MFX_KEY" + keyID "patient-pii"  →  MFX_KEY_PATIENT_PII
Prefix "MFX_KEY" + keyID "default"      →  MFX_KEY_DEFAULT

Each env var must contain a base64-encoded 32-byte (256-bit) key. Generate one with:

openssl rand -base64 32

Usage:

server := maniflex.New(maniflex.Config{
    KeyProvider: &encryption.EnvKeyProvider{Prefix: "MYAPP_KEY"},
})

func (*EnvKeyProvider) BlindIndexKeyID added in v0.4.0

func (p *EnvKeyProvider) BlindIndexKeyID() string

BlindIndexKeyID advertises the rotation-independent HMAC key to maniflex.

func (*EnvKeyProvider) Decrypt

func (p *EnvKeyProvider) Decrypt(_ context.Context, envelope []byte) ([]byte, error)

Decrypt decrypts an envelope produced by Encrypt. It reads the keyID from the envelope, loads the corresponding env var key, and decrypts with AES-256-GCM.

func (*EnvKeyProvider) Encrypt

func (p *EnvKeyProvider) Encrypt(_ context.Context, keyID string, plaintext []byte) ([]byte, error)

Encrypt encrypts plaintext with AES-256-GCM and returns a binary envelope. The envelope is self-describing: it embeds the keyID so that Decrypt never needs the caller to supply a key name.

func (*EnvKeyProvider) HMAC

func (p *EnvKeyProvider) HMAC(_ context.Context, keyID string, data []byte) ([]byte, error)

HMAC returns HMAC-SHA256 of data using the named key. Used to enforce UNIQUE constraints on encrypted fields without storing plaintext.

func (*EnvKeyProvider) KeyIDOf

func (p *EnvKeyProvider) KeyIDOf(envelope []byte) (string, error)

KeyIDOf extracts the keyID from an envelope without decrypting it.

type VaultKeyProvider

type VaultKeyProvider struct {
	// Address is the HTTPS Vault server URL. Required.
	Address string
	// Token is the static Vault authentication token. Required unless
	// TokenSource is set.
	Token string
	// TokenSource obtains a token before each request and takes precedence over
	// Token. Use it to integrate renewable AppRole or Kubernetes credentials.
	TokenSource VaultTokenSource
	// Mount is the Transit secrets engine path. Default: "transit".
	Mount string
	// Client is the HTTP client used for Vault calls. It is cloned before use.
	// The default is a private client with a bounded timeout.
	Client *http.Client
	// Timeout bounds the complete HTTP operation. Zero defaults to 10 seconds
	// unless an injected Client already has a timeout. A negative value
	// explicitly disables the client timeout; request context deadlines still
	// apply.
	Timeout time.Duration
	// AllowInsecureHTTP permits an http:// Address for explicitly isolated
	// development and test environments. It must not be enabled in production.
	AllowInsecureHTTP bool

	// IndexKeyID names a dedicated Transit key used only for HMAC blind indexes
	// on encrypted+unique fields. It must remain stable as encryption keys rotate.
	IndexKeyID string
}

VaultKeyProvider encrypts and decrypts via HashiCorp Vault's Transit secrets engine. The keyID maps to a Transit key name (e.g. "patient-pii").

Vault manages key material, versioning, and rotation internally. This provider stores a thin envelope in the DB:

[ version:1 ][ keyIDLen:2 BE ][ keyID:N ][ vaultCiphertext:M ]

The vaultCiphertext is the Vault-returned string (e.g. "vault:v1:..."), which embeds Vault's own key version, so decryption after a Vault key rotation is transparent — Vault handles both old and new key versions automatically.

Authentication uses a static token. For production, wrap this provider and refresh the token from AppRole/Kubernetes auth before each operation.

Usage:

server := maniflex.New(maniflex.Config{
    KeyProvider: &encryption.VaultKeyProvider{
        Address: "https://vault.example.com",
        Token:   os.Getenv("VAULT_TOKEN"),
    },
})

func (*VaultKeyProvider) BlindIndexKeyID added in v0.4.0

func (v *VaultKeyProvider) BlindIndexKeyID() string

BlindIndexKeyID advertises the rotation-independent HMAC key to maniflex.

func (*VaultKeyProvider) Decrypt

func (v *VaultKeyProvider) Decrypt(ctx context.Context, envelope []byte) ([]byte, error)

Decrypt decrypts a Vault envelope. It reads the keyID and Vault ciphertext from the envelope and sends them to the Vault Transit decrypt endpoint.

func (*VaultKeyProvider) Encrypt

func (v *VaultKeyProvider) Encrypt(ctx context.Context, keyID string, plaintext []byte) ([]byte, error)

Encrypt encrypts plaintext via Vault Transit and returns a binary envelope.

func (*VaultKeyProvider) HMAC

func (v *VaultKeyProvider) HMAC(ctx context.Context, keyID string, data []byte) ([]byte, error)

HMAC returns a Vault-keyed HMAC of data using the Transit HMAC endpoint. Vault's HMAC uses the named key so the digest is tied to key ownership.

func (*VaultKeyProvider) KeyIDOf

func (v *VaultKeyProvider) KeyIDOf(envelope []byte) (string, error)

KeyIDOf extracts the Vault Transit key name from an envelope without decrypting.

type VaultTokenSource added in v0.4.0

type VaultTokenSource interface {
	Token(context.Context) (string, error)
}

VaultTokenSource obtains a Vault token before each request. Implementations can cache and renew AppRole, Kubernetes, or other short-lived credentials.

type VaultTokenSourceFunc added in v0.4.0

type VaultTokenSourceFunc func(context.Context) (string, error)

VaultTokenSourceFunc adapts a function into a VaultTokenSource.

func (VaultTokenSourceFunc) Token added in v0.4.0

Token obtains a Vault token.

Jump to

Keyboard shortcuts

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