AWS

Secrets Manager and SSM Parameter Store, built on aws-sdk-go-v2.

Schemesaws-sm:// aws-ps://
Modulegithub.com/xavidop/mamori/providers/aws
SensitiveSecrets Manager: yes · Parameter Store: SecureString only
Watchpoll
Authdefault AWS credential chain (AWS_REGION, env, shared config, IAM role)

Install

go get github.com/xavidop/mamori/providers/aws
import _ "github.com/xavidop/mamori/providers/aws" // registers aws-sm:// and aws-ps://

Using the ref

An aws-sm:// ref points at one secret in AWS Secrets Manager; an aws-ps:// ref points at one parameter in SSM Parameter Store.

aws-sm://<secret-id>[#json-key]
aws-ps://<parameter-name>[#json-key]
PartRequiredWhat it means
<secret-id>yesThe Secrets Manager secret name or ARN.
<parameter-name>yesThe Parameter Store name, including its leading slash, e.g. /myapp/log-level.
#json-keynoSelect one field from a JSON secret/parameter payload (via mamori.SelectKey).

Examples

  • aws-sm://prod/api-key returns the whole secret string - use it for an opaque token.
  • aws-sm://prod/db#password returns just the password field of a JSON secret.
  • aws-ps:///myapp/log-level reads the /myapp/log-level parameter (note the extra slash: the aws-ps:// scheme plus the /myapp/... name).
  • aws-ps:///myapp/db#password selects password from a JSON parameter.
type Config struct {
	APIKey     secret.String `source:"aws-sm://prod/api-key"`      // whole secret string
	DBPassword secret.String `source:"aws-sm://prod/db#password"`  // one key of a JSON secret
	LogLevel   string        `source:"aws-ps:///myapp/log-level"`  // SecureString is marked sensitive
}

Secrets Manager values are always Sensitive; Parameter Store reads with WithDecryption=true and marks only SecureString parameters Sensitive. Value.Version is the secret’s VersionId or the parameter’s numeric Version. Secrets Manager implements BatchProvider, so multiple aws-sm:// refs resolve in one BatchGetSecretValue call.

Explicit configuration

import awsprov "github.com/xavidop/mamori/providers/aws"

mamori.WithProvider(awsprov.NewSecretsManager(awsprov.WithRegion("eu-west-1")))
mamori.WithProvider(awsprov.NewParameterStore(awsprov.WithRegion("eu-west-1")))

Watch

Neither backend has native change notification, so mamori polls (WithPollInterval + jitter, Value.Version comparison). For push-based rotation you can pair this with an EventBridge -> SQS trigger in your app and call Load on demand.

Error classification

Failures are classified so mamori.ErrorKind can distinguish them:

AWS error codemamori kind
ResourceNotFoundException, ParameterNotFound, ParameterVersionNotFoundnot_found
AccessDeniedExceptionpermission_denied
UnrecognizedClientException, ExpiredTokenException, InvalidSignatureException, MissingAuthenticationToken, IncompleteSignatureunauthenticated
ThrottlingException, Throttling, TooManyRequestsException, RequestLimitExceededrate_limited
InternalServiceError, InternalServerError, InternalFailure, InternalServerException, ServiceUnavailable, ServiceUnavailableExceptionunavailable
InvalidParameterException, InvalidRequestException, ValidationException, InvalidParameterValue, InvalidKeyId, BadRequestExceptioninvalid
anything elseunknown

This table is the whole of classifyAWS, one function shared by all three schemes in this module - aws-sm://, aws-ps://, and aws-appconfig:// - so it lists every code any of the three can produce, not only the ones Secrets Manager and Parameter Store return. InternalServerException and BadRequestException are AppConfig Data’s codes; they are included here because a shared classifier means “anything else maps to unknown” has to hold for the whole module, not just for this page’s two schemes.

Codes not listed above report unknown rather than being guessed at. Notably, Secrets Manager’s DecryptionFailure is deliberately left unmapped: it can mean a KMS key policy problem, a disabled key, or a KMS outage, and doesn’t map cleanly to one kind. The original SDK error stays reachable with errors.As.

Verified by unit tests and the providertest conformance kit against in-memory fakes; live AWS behavior is covered by //go:build integration tests.