Documentation
¶
Overview ¶
Package providers implements the secret backend providers for the Atmos secrets subsystem. It is a leaf package (it does not import pkg/secrets) exposing a backend-agnostic Provider interface plus a store-backed adapter (track 1) and a native SOPS provider (track 2).
Index ¶
Constants ¶
const ( // TrackStore is the store-backed track (a `secret: true` store). TrackStore = "store" // TrackSops is the SOPS file-backed track. TrackSops = "sops" )
Backend-track keys. Each concrete provider self-registers under its track via init(); pkg/secrets maps a declaration's BackendType onto these.
Variables ¶
var ( // ErrStoreNotFound indicates the referenced store is not configured. ErrStoreNotFound = errors.New("referenced store is not configured") // ErrStoreNotSecret indicates the referenced store is not marked `secret: true`. ErrStoreNotSecret = errors.New("referenced store is not a secret store (set `secret: true`)") // ErrProviderNotFound indicates the referenced SOPS provider is not configured. ErrProviderNotFound = errors.New("referenced secrets provider is not configured") // ErrDeleteNotSupported indicates the backend cannot delete values. ErrDeleteNotSupported = errors.New("backend does not support delete") // ErrKeygenNotSupported indicates a provider implements the keygen capability but cannot // generate for this particular vault/kind (e.g. a KMS/GPG-backed SOPS vault). Callers should // surface it as a friendly "not implemented" message, not a hard failure. ErrKeygenNotSupported = errors.New("key generation is not supported for this vault") // ErrScopeUnsupported indicates a declared secret's resolved scope is not supported by its // backend (e.g. an instance-scoped secret on a backend that only scopes by environment). ErrScopeUnsupported = errors.New("secret scope not supported by backend") )
Provider-construction errors.
var ( // ErrProviderAlreadyRegistered indicates two providers registered the same track. ErrProviderAlreadyRegistered = errors.New("secrets provider track already registered") // ErrTrackNotRegistered indicates no provider is registered for a backend track. ErrTrackNotRegistered = errors.New("no secrets provider registered for backend track") )
Registry-construction errors.
Functions ¶
func Register ¶
func Register(track string, c Constructor)
Register adds a backend-track constructor. Providers self-register from this package's files via init(), so dispatch never requires a central switch. It panics on duplicate registration, which is a programming error.
func Registered ¶
func Registered() []string
Registered returns the registered backend tracks, sorted, for diagnostics and tests.
Types ¶
type Constructor ¶
type Constructor func(atmosConfig *schema.AtmosConfiguration, name string, sectionProviders map[string]any) (Provider, error)
Constructor builds a Provider for a backend track. The name argument is the declaration's BackendName (a store name for track 1, a SOPS provider name for track 2). The sectionProviders argument carries a stack/component `secrets.providers` map (used by file-based tracks like SOPS; ignored by store-backed tracks).
type Coordinate ¶
type Coordinate struct {
Stack string
Component string
Key string
// Scope is the addressing level (instance, stack, or global). Providers interpret it in
// their own terms. Empty is treated as ScopeInstance. For ScopeStack, Component is empty;
// for ScopeGlobal, both Stack and Component are empty.
Scope Scope
}
Coordinate identifies a single secret value within a backend's namespace.
type FilePathProvider ¶
type FilePathProvider interface {
// FilePath returns the backing file path the coordinate resolves to.
FilePath(coord Coordinate) (string, error)
}
FilePathProvider is an optional capability for file-backed providers (e.g. SOPS) that can report the on-disk path a coordinate resolves to. `describe affected` uses it to treat the backing file as an automatic dependency of every component that consumes the secret, so a changed secret file marks its consumers affected. Store-backed providers do not implement it.
type FileResettable ¶
type FileResettable interface {
// Reset overwrites the provider's backing file with an empty document for the coordinate's scope.
Reset(coord Coordinate) error
}
FileResettable is an optional capability for file-based providers (e.g. SOPS) that can rewrite their whole backing file to a clean, empty state (creating it if missing). Store-backed providers do not implement it. Callers type-assert for this capability.
type KeyGenerator ¶
type KeyGenerator interface {
// HasKey reports whether the vault already has resolvable key material (so callers can decide
// whether to generate).
HasKey() bool
// GenerateKey produces new key material and records it in the vault's configured sinks. basePath
// roots any relative output. Implementations append/merge and never clobber other vaults'
// material. The KeygenResult describes what was produced for user-facing output.
GenerateKey(basePath string) (*KeygenResult, error)
}
KeyGenerator is the optional, backend-agnostic capability a provider implements to generate its own key material. It follows the registry pattern: any registered provider that implements it is dispatched by `atmos secret keygen` with no backend-specific code in the command. The SOPS (age) provider implements it to produce an age key pair; a future provider (e.g. an x509/SSL kind) could implement it to produce a certificate + key, reusing the same command and output rendering.
type KeygenOutput ¶
type KeygenOutput struct {
// Label names the artifact (e.g. "private identity", "public recipient", "certificate").
Label string
// Location is where it was written (a file path or a store reference).
Location string
// Sensitive marks private material that must be kept out of version control.
Sensitive bool
}
KeygenOutput is one artifact a provider wrote during key generation.
type KeygenResult ¶
type KeygenResult struct {
// Vault is the named secrets vault (`secrets.providers.<name>`) the material belongs to.
Vault string
// Kind is the provider kind that generated it (e.g. "sops/age", "ssl/x509").
Kind string
// Summary is a one-line human description (e.g. "Generated an age key pair.").
Summary string
// Outputs are the artifacts written, with where each landed.
Outputs []KeygenOutput
// Public is optional public material safe to print/share (an age recipient, a certificate, a
// public key). Empty when there is none.
Public string
}
KeygenResult describes what a provider's GenerateKey produced, in a backend-agnostic shape so the command can render any provider's output uniformly.
type LocalStatus ¶
type LocalStatus interface {
// LocalStatusCheck reports whether Status() is credential-free for this provider instance.
LocalStatusCheck() bool
}
LocalStatus is an optional capability marking providers whose Status() existence check is credential-free — it needs no network access, no authentication, and no decryption. SOPS reports local because "is the key present?" is answered from the cleartext key names in the encrypted file. Store-backed providers report local only when their underlying store is local (e.g. the OS keychain); remote stores (SSM, Secrets Manager, Key Vault, GCP, Vault, 1Password) are not local. `atmos secret list` always checks local providers, but reports non-local providers as Unknown unless verification is explicitly requested (`--verify`).
type Provider ¶
type Provider interface {
// Set stores a value at the coordinate.
Set(coord Coordinate, value any) error
// Get retrieves a value at the coordinate.
Get(coord Coordinate) (any, error)
// Delete removes a value at the coordinate.
Delete(coord Coordinate) error
// Status reports whether a value exists at the coordinate.
Status(coord Coordinate) (bool, error)
// Kind returns the provider kind (e.g. aws/ssm, sops/age) for display/observability.
Kind() string
// SupportsScope reports whether the provider can represent the given scope. A declared
// secret whose resolved scope is unsupported is rejected with ErrScopeUnsupported before any
// write. An empty scope (ScopeInstance) must always be supported.
SupportsScope(scope Scope) bool
}
Provider is the backend-agnostic CRUD interface the secrets service operates against. Track-1 (store-backed) and track-2 (SOPS) providers both implement it.
type Scope ¶
type Scope string
Scope identifies the addressing level at which a secret value is stored. Atmos exposes three scopes forming a ladder of sharing (instance → stack → global); each provider maps a scope to its native primitive (file path, key path, environment) and declares which scopes it supports via Provider.SupportsScope. An empty Scope is treated as ScopeInstance for back-compat.
const ( // ScopeInstance stores a value per component instance (stack + component). Default. ScopeInstance Scope = "instance" // ScopeStack stores a single value shared by every instance in a stack (no component segment). ScopeStack Scope = "stack" // ScopeGlobal stores a single value shared by every stack and component that resolves through // the same backend (no stack or component segment). Sharing is bounded by the backend the // store points at (account/project/prefix), which remains the isolation boundary. ScopeGlobal Scope = "global" )