Help us shape the future of Go! Take the 2026 Go Developer Survey

vault

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Overview

Package vault is Atlas's engine-internal encrypted secret store: worker credentials sealed at rest with AES-256-GCM under a master key that never leaves the operator's control (ADR-0069), on by default with a generated key file when no operator key is supplied (ADR-0070).

It exists as its own package so the boundary is enforced rather than merely intended: nothing here returns a plaintext secret except Vault.Get, nothing writes the master key anywhere but the key file, and a caller cannot reach past the API into a record. The rest of the server holds a *Vault and resolves secret *references*, so a credential never sits in a compiled process, an event, or a log line.

Index

Constants

View Source
const (
	KeyEnv     = "ATLAS_VAULT_KEY"
	KeyFileEnv = "ATLAS_VAULT_KEY_FILE"
)

Environment variables that configure the vault master key. The key is 32 bytes (AES-256), given as hex (64 chars) or base64. An operator key from either of these is preferred and, per ADR-0069, is NEVER written to disk by Atlas. When neither is set the vault is on by default and generates its own key file (ADR-0070).

Variables

View Source
var ErrErased = errors.New("vault: the data subject's key has been erased; this value is permanently unreadable")

ErrErased is returned by Open when the subject's data key is gone: the value is permanently unreadable, which is the intended outcome of an erasure and not a fault. Callers distinguish it from a genuine failure because the two need opposite handling — one is reported to an operator as "erased", the other as broken.

Functions

func ConnectionCredentialName added in v0.20.0

func ConnectionCredentialName(connectionID string) string

ConnectionCredentialName is the vault name of one connection's credential.

func DataKeyName added in v0.7.0

func DataKeyName(subject string) string

DataKeyName is the vault name a subject's data key is stored under. Exported so the secrets API can refuse the region and an operator view can label it.

func IsDataKeyName added in v0.7.0

func IsDataKeyName(name string) bool

IsDataKeyName reports whether a vault name belongs to the data-key region.

func IsEnciphered added in v0.7.0

func IsEnciphered(text string) bool

IsEnciphered reports whether a stored value is an envelope. It needs no key, so any layer can ask — which is how the operator UI labels a value rather than showing it.

func IsLinkClientSecretName added in v0.21.0

func IsLinkClientSecretName(name string) bool

IsLinkClientSecretName reports whether a vault name holds a linking client secret.

func IsReservedName added in v0.20.0

func IsReservedName(name string) bool

IsReservedName reports whether a name belongs to a region the vault keeps for Atlas itself — a data subject's key, a connection's credential, or the client secret accounts are linked through. The operator surfaces — the secrets API, a Worker's credential reference, an API token sealed into the vault — refuse such a name, because reaching one through them would hand a person's credential, or the key to their data, to whatever that surface feeds.

func LinkClientSecretName added in v0.21.0

func LinkClientSecretName(provider string) string

LinkClientSecretName is the vault name of a provider's linking client secret.

func ResolveKey

func ResolveKey(keyFile string) (key []byte, source string, err error)

ResolveKey sources the master key with operator precedence (ADR-0070): an operator key from the environment (ATLAS_VAULT_KEY / ATLAS_VAULT_KEY_FILE) wins and is never written to disk; absent one, the key is loaded from keyFile, or generated into it (readable by this account only) so the vault is on by default without provisioning. source is "env", "file", or "generated" — the caller logs the generated case, which trades a weaker at-rest guarantee (key beside the ciphertext) for turnkey operation.

func SubjectOfDataKeyName added in v0.7.0

func SubjectOfDataKeyName(name string) (string, bool)

SubjectOfDataKeyName returns the subject a data-key name belongs to.

Types

type Envelope added in v0.7.0

type Envelope struct {
	// Subject names whose data key opens this value. It is in the clear on purpose:
	// ADR-0314's primary defence is that people are named by reference, so the id is
	// exactly the part that was never meant to be hidden — and carrying it here is
	// what makes the ciphertext self-contained in a backup nobody can interpret any
	// more.
	Subject string
	// Kind is the caller's own value kind, carried so an opened value returns as the
	// type it had rather than as a string. This package does not interpret it.
	Kind uint8
	// contains filtered or unexported fields
}

Envelope is an enciphered value as it is carried everywhere else in Atlas: in a command, in an event, in the state record, in a checkpoint, in an export.

Subject and Kind are readable because a reader that cannot open the value still has to render it — an operator inspecting an instance is shown whose data this is and what type it had, not a wall of base64. The nonce and the ciphertext are not exported: only this package can open one, which is the same boundary the package already draws around a secret's plaintext.

func ParseEnvelope added in v0.7.0

func ParseEnvelope(text string) (Envelope, bool)

ParseEnvelope reads a stored value back into an envelope, ok=false when the text is not one.

The parse is strict — the marker member, all four fields present, decodable base64, a non-empty subject — because an ordinary variable whose value happened to resemble an envelope would otherwise be treated as enciphered. Strictness makes an accidental collision vanishingly unlikely; a deliberate one is possible and harmless, since the forged envelope simply fails to open and only affects the instance its author submitted it to.

func (Envelope) Text added in v0.7.0

func (e Envelope) Text() string

Text renders the envelope as the canonical JSON that is stored and transported.

The marshal error is discarded rather than handled: every field is a string or a uint8, so encoding/json cannot fail here, and a branch nothing can reach is a branch nothing can test.

type Meta

type Meta struct {
	Name      string `json:"name"`
	KeyID     string `json:"keyId"`
	CreatedAt int64  `json:"createdAt"`
	UpdatedAt int64  `json:"updatedAt"`
}

Meta is the value-free view of a secret returned by the API and List: it proves a secret exists and under which key, but never reveals the value.

type Vault

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

Vault is the engine-internal encrypted secret store (ADR-0069, closing the A3 option deferred by ADR-0041). It owns a sidecar directory — one JSON file per secret, hex-named, atomic write + dir fsync, the connectorStore pattern — and an AES-256-GCM cipher built from the master key. Like the other sidecar stores it is owned by the run-loop goroutine, so it needs no locking; and it writes only ciphertext, so no secret value ever reaches the WAL, an event, or a variable (I6).

func New

func New(dir string, key []byte) (*Vault, error)

New opens (creating if needed) the vault directory and builds the AES-256-GCM cipher from a 32-byte master key.

func (*Vault) DataSubjects added in v0.7.0

func (v *Vault) DataSubjects() ([]Meta, error)

DataSubjects lists the subjects that hold a data key, oldest first. It is the operator's view of what an erasure could still act on; it reveals ids, which are references by ADR-0314's design and not the content the keys protect.

func (*Vault) Delete

func (v *Vault) Delete(name string) error

Delete removes a secret. A missing secret is not an error (idempotent).

func (*Vault) Erase added in v0.7.0

func (v *Vault) Erase(subject string) error

Erase destroys a subject's data key, which is the whole of an erasure: every copy of every value ever sealed under it, in every store and every backup, becomes permanently unreadable in one act. It is idempotent, so a repeated request is not an error.

func (*Vault) Get

func (v *Vault) Get(name string) (string, bool, error)

Get returns the decrypted value for a name, ok=false when no such secret exists. A record sealed under a different master key, or one that has been tampered with, is an error rather than a silent miss.

func (*Vault) HasDataKey added in v0.7.0

func (v *Vault) HasDataKey(subject string) (bool, error)

HasDataKey reports whether a subject still has a data key, i.e. whether their values are still readable.

func (*Vault) List

func (v *Vault) List() ([]Meta, error)

List returns value-free metadata for every stored secret, oldest first. Non-record files are ignored, and so are the per-subject data keys of ADR-0314: those are not credentials an operator manages, and showing them here would invite deleting one — which is an erasure of business data, not the removal of a secret. Vault.DataSubjects is their own view.

func (*Vault) Open added in v0.7.0

func (v *Vault) Open(name string, e Envelope) (string, error)

Open deciphers an envelope belonging to the named variable. A subject whose key has been erased is ErrErased, which is an answer and not a failure.

func (*Vault) Seal added in v0.7.0

func (v *Vault) Seal(subject, name string, kind uint8, plaintext string) (Envelope, error)

Seal enciphers one value of one variable under the subject's data key, creating that key on first use.

name binds the ciphertext to the variable it belongs to (with the subject, as the AEAD's additional data), so an envelope cannot be moved to another variable — or to another subject's — and still open. It survives the operations that legitimately copy a value under its own name: a fork, a migration, a checkpoint.

func (*Vault) Set

func (v *Vault) Set(name, value string) (Meta, error)

Set seals value under name and stores it durably, returning the value-free metadata. The plaintext is sealed at once and never persisted; an overwrite keeps the original createdAt.

Jump to

Keyboard shortcuts

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