Documentation
¶
Overview ¶
Package encryptioncfg builds an encryption keyring over a caller-supplied encryption.Keyset, with one cipher provider — AES-256-GCM today — governing every key in the ring.
A mixed ring is expressible in principle, since a ciphertext names its key and the key determines its cipher, but nothing has wanted one and offering it would mean every deployment configuring an algorithm per key forever.
CurrentKeyID names the key new ciphertexts are written under and is required: rotation works by changing it, so inferring a default would make the choice invisible at the moment it matters most.
Index ¶
Constants ¶
const (
// ProviderAES is the AES-256-GCM encryption provider.
ProviderAES = "aes"
)
Variables ¶
This section is empty.
Functions ¶
func NewKeyring ¶
func NewKeyring( ctx context.Context, cfg *Config, keys encryption.Keyset, opts ...Option, ) (encryption.EncryptorDecryptor, error)
NewKeyring builds an encryption.Keyring over keys, using the configured provider for every one of them.
One provider governs the whole ring rather than one per key. A ciphertext names its key, and the key determines its cipher, so a mixed ring is expressible — but nothing has ever wanted one, and offering it would mean every deployment configuring an algorithm per key forever.
func RegisterEncryptorDecryptor ¶
RegisterEncryptorDecryptor registers an encryption.EncryptorDecryptor — a keyring — with the injector.
Consumers must provide an encryption.Keyset into the container (e.g. via do.ProvideValue(i, encryption.Keyset{"k1": material})). The keyset is resolved as its named type rather than a bare map so it cannot collide with an unrelated map registered in the same container.
Every key the deployment can still decrypt with belongs in that keyset, not just the current one. A keyset trimmed to the current key alone makes every ciphertext written before the last rotation unreadable, and it does so silently until something tries to read one.
Types ¶
type Config ¶
type Config struct {
// Provider names the cipher every key in the ring uses.
Provider string `env:"PROVIDER" json:"provider,omitempty" yaml:"provider,omitempty"`
// CurrentKeyID names the key new ciphertexts are written under. It has
// to be one of the keys supplied to NewKeyring, and it is required:
// rotation works by changing this value, so there is no sensible
// default and inferring one would make the choice invisible.
CurrentKeyID string `env:"CURRENT_KEY_ID" json:"currentKeyID,omitempty" yaml:"currentKeyID,omitempty"`
}
Config is the configuration for the encryption keyring.
func (*Config) ValidateWithContext ¶
ValidateWithContext validates a Config struct.
It checks the normalized provider, not the raw string: dispatch lowercases and trims, so validating the raw value rejected "AES" and " aes " while the factory accepted both.
type Option ¶
type Option func(*options)
Option configures how NewKeyring assembles its keyring.
The observability dependencies are options rather than parameters because every one of them is genuinely optional: an absent logger logs nowhere, an absent tracer provider traces nowhere, and an absent metrics provider records nothing. Requiring them positionally made a caller that wanted none of the three name all three anyway, usually as noops.
func WithLogger ¶
WithLogger attaches a logger. An absent logger logs nowhere.
func WithMetricsProvider ¶
WithMetricsProvider attaches a metrics provider, enabling the keyring's per-key encryption and decryption counters. An absent metrics provider records nothing — which also means a deployment that skips it has no way to see how far a rotation has gotten.
func WithPillars ¶
func WithPillars(p *observability.Pillars) Option
WithPillars attaches a logger, tracer provider, and metrics provider in one go, for the common case where a caller has already built them together. A nil Pillars attaches nothing.
It is applied in order with the individual options, so a caller can hand over its pillars and then override one of them.
func WithTracerProvider ¶
WithTracerProvider attaches a tracer provider, enabling spans on the instrumented operations. An absent tracer provider traces nowhere.