providers

package
v1.233.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

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

View Source
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

View Source
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")
	// ErrRawNotSupported indicates the backend cannot return an original textual payload.
	ErrRawNotSupported = errors.New("backend does not support raw secret retrieval")
	// 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.

View Source
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 IsSelector

func IsSelector(value string) bool

IsSelector reports whether a string value is a YAML-function selector (such as `!aws.cloudformation.output ...`) that must be evaluated before it is concrete.

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 RegisterLocations

func RegisterLocations(track string, fn LocationsFunc)

RegisterLocations adds the file-location reporter of a file-backed backend track. It lets `describe affected` stay conservative for a secret whose backend selector cannot be resolved without credentials: the component is treated as affected by any change under these locations. Like Register, it is called from a provider's init and panics on a duplicate registration.

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 FileLocations

type FileLocations struct {
	Files   []string
	Folders []string
}

FileLocations describes where the files of a file-backed provider definition may live when the exact file of a particular secret cannot be computed. Files are exact paths; Folders are directories under which any file may be one of the provider's files. Paths are relative to the working directory, like the paths the provider itself resolves.

func PossibleLocations

func PossibleLocations(track string, spec map[string]any) (FileLocations, bool)

PossibleLocations returns the locations a provider definition of the given track may use, and false when the track is not file-backed (store-backed secrets have no files).

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 LocationsFunc

type LocationsFunc func(spec map[string]any) FileLocations

LocationsFunc reports every location a file-backed provider definition (its `spec` map) could place its files in, independent of any coordinate. A spec value that is itself a YAML-function selector (see IsSelector) is unknown, so the func must widen the result to cover anything that value could produce.

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.

func New

func New(atmosConfig *schema.AtmosConfiguration, track, name string, sectionProviders map[string]any) (Provider, error)

New constructs the provider registered for track, returning ErrTrackNotRegistered if none is registered.

type RawGetter added in v1.229.0

type RawGetter interface {
	GetRaw(coord Coordinate) (string, error)
}

RawGetter is an optional capability for providers that can retrieve the original textual secret without structured decoding. `!secret ... | raw` explicitly requests this capability.

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"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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