secrets

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package secrets reads and writes AWS Secrets Manager secrets, with the cache and the transforms of package parameters.

Create a Provider once and share it:

var vault = secrets.FromConfig(cfg) // or secrets.New(client)

key, err := vault.Get(ctx, "api-key")
creds, err := parameters.Get[Credentials](ctx, vault, "db-credentials",
	parameters.WithTransform(parameters.TransformJSON))
previous, err := vault.Get(ctx, "db-password", secrets.WithVersionStage("AWSPREVIOUS"))
values, failed, err := vault.GetByName(ctx, []string{"api-key", "db-password"})

or use the shortcuts, which build a provider from the default AWS configuration on first use: GetSecret, GetSecretsByName, SetSecret.

Get calls GetSecretValue and returns SecretString, or the bytes of SecretBinary. GetByName calls BatchGetSecretValue. Set adds a version to a secret with PutSecretValue and creates the secret with CreateSecret when it does not exist yet; a []byte value is a SecretBinary, a string a SecretString, any other value its JSON encoding.

Differences from Python

  • Fixed in GetByName: Python finds the secrets through a name filter, which matches by prefix ("db" also returns "db-password") and takes ten names at most. Here the secrets are asked for by their exact name or ARN (SecretIdList), twenty per call and as many calls as needed; with WithFilters the name filter is used, ten names per call, and only exact matches are kept.
  • Fixed in GetByName: the secrets Secrets Manager could not read (missing, access denied, decryption failure) are returned with their error instead of being dropped silently. The read still succeeds with the others, as in Python, and fails only when none could be read.
  • Version selectors (WithVersionID, WithVersionStage) are part of the cache key, so a previous version never answers for the current one.
  • Set accepts any JSON value, not only a dict, and returns the ARN, the name and the version id of either answer.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoNames reports a GetByName without names.
	ErrNoNames = errors.New("you must provide at least one secret name")
	// ErrNoSecretsFound reports a GetByName that could read none of the
	// secrets it was asked for.
	ErrNoSecretsFound = errors.New("no secrets found matching the provided names")
)

The sentinel errors of GetByName, inside a *parameters.GetSecretError.

Functions

func GetByName

func GetByName[T any](ctx context.Context, p *Provider, names []string, opts ...parameters.Option) (values map[string]T, failed map[string]error, err error)

GetByName reads several secrets with BatchGetSecretValue and returns them as Ts (see parameters.Get), keyed by the names asked for: Python's get_secrets_by_name. Names may be ARNs.

The secrets are asked for by their exact name or ARN (SecretIdList, up to twenty per call, as many calls as needed). With WithFilters they are found through a name filter instead, as Python does, and only exact matches are kept.

As in Python, the secrets that cannot be read do not fail the others: they are returned in failed, by name, each with its error (Secrets Manager reports ResourceNotFoundException, AccessDeniedException, DecryptionFailure as smithy.APIError). The read fails when none of the secrets can be read, or when a call fails as a whole. A secret whose transform fails is in failed too, unless WithRaiseOnTransformError makes it fail the read.

The result is cached under the set of names asked for, as in Python.

func GetSecret

func GetSecret[T any](ctx context.Context, name string, opts ...parameters.Option) (T, error)

GetSecret returns the secret name as a T (see parameters.Get), through a provider built on first use from the default AWS configuration: Python's get_secret.

func GetSecretsByName

func GetSecretsByName[T any](ctx context.Context, names []string, opts ...parameters.Option) (values map[string]T, failed map[string]error, err error)

GetSecretsByName reads several secrets through the default provider: Python's get_secrets_by_name. See GetByName.

func WithFilters

func WithFilters(filters ...types.Filter) parameters.Option

WithFilters narrows GetByName with Secrets Manager filters (by tag, by description), Python's Filters: the names asked for are then matched through a name filter, and only the secrets whose name is exactly one of them are returned.

func WithVersionID

func WithVersionID(id string) parameters.Option

WithVersionID reads the version of the secret with this id instead of the current one (VersionId). Versions are cached apart.

func WithVersionStage

func WithVersionStage(stage string) parameters.Option

WithVersionStage reads the version of the secret with this staging label, AWSPREVIOUS for one, instead of AWSCURRENT (VersionStage). Stages are cached apart.

Types

type Client

Client is the part of the Secrets Manager client the provider calls; *secretsmanager.Client satisfies it.

type Provider

type Provider struct {
	*parameters.Provider
	// contains filtered or unexported fields
}

Provider reads and writes Secrets Manager secrets. It is safe for concurrent use: create it once and share it across invocations.

func FromConfig

func FromConfig(cfg aws.Config) *Provider

FromConfig returns a provider with a Secrets Manager client built from cfg.

func New

func New(client Client) *Provider

New returns a provider that calls Secrets Manager through client.

func (*Provider) GetByName

func (p *Provider) GetByName(ctx context.Context, names []string, opts ...parameters.Option) (values map[string]string, failed map[string]error, err error)

GetByName returns the string value of several secrets: GetByName[string].

Example
// In a function: secrets.FromConfig(cfg), created once in main.
provider := secrets.New(newFake())

values, failed, err := provider.GetByName(context.Background(), []string{"api-key", "db-password", "missing"})
if err != nil {
	panic(err)
}
fmt.Println(values["api-key"], values["db-password"])
fmt.Println("failed:", slices.Sorted(maps.Keys(failed)))
Output:
k3y s3cret
failed: [missing]

func (*Provider) Set

func (p *Provider) Set(ctx context.Context, name string, value any, opts ...SetOption) (SetResult, error)

Set writes the secret name: Python's set_secret. A string is written as SecretString, a []byte as SecretBinary, anything else as its JSON encoding in SecretString (Python accepts a dict).

As in Python, Set first adds a version to the secret (PutSecretValue) and creates the secret (CreateSecret) only when it does not exist, the cheaper path for a secret that is written often. Failures are a *parameters.SetSecretError.

type SetOption

type SetOption func(*setOptions)

SetOption configures Provider.Set and SetSecret.

func WithClientRequestToken

func WithClientRequestToken(token string) SetOption

WithClientRequestToken makes the write idempotent: Secrets Manager creates one version per token, and the token becomes the version id.

func WithCreateSecretInput

func WithCreateSecretInput(edit func(*secretsmanager.CreateSecretInput)) SetOption

WithCreateSecretInput edits the CreateSecret request sent when the secret does not exist yet (description, KMS key, tags): Python's **sdk_options for the creation.

func WithPutSecretValueInput

func WithPutSecretValueInput(edit func(*secretsmanager.PutSecretValueInput)) SetOption

WithPutSecretValueInput edits the PutSecretValue request before it is sent (version stages, for one): Python's **sdk_options for the update.

type SetResult

type SetResult struct {
	ARN       string
	Name      string
	VersionID string
}

SetResult is what Secrets Manager answers to a write.

func SetSecret

func SetSecret(ctx context.Context, name string, value any, opts ...SetOption) (SetResult, error)

SetSecret writes a secret through the default provider: Python's set_secret. See Provider.Set.

Jump to

Keyboard shortcuts

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