AWS Secrets Manager
The awssm package provides a fig.SecretProvider backed by AWS Secrets Manager.
Installation
go get github.com/zoobzio/fig/awssm
Quick Start
import (
"context"
"log"
"github.com/zoobzio/fig"
"github.com/zoobzio/fig/awssm"
)
type Config struct {
DBPassword string `secret:"prod/database:password"`
APIKey string `secret:"prod/api-key"`
}
func main() {
ctx := context.Background()
provider, err := awssm.New(ctx)
if err != nil {
log.Fatal(err)
}
var cfg Config
if err := fig.LoadContext(ctx, &cfg, provider); err != nil {
log.Fatal(err)
}
}
Configuration
Credentials
The provider uses the standard AWS SDK credential chain:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - Shared credentials file (
~/.aws/credentials) - IAM role (EC2, ECS, Lambda)
Region
Set via environment or shared config:
export AWS_REGION=us-east-1
Or in ~/.aws/config:
[default]
region = us-east-1
Key Format
Keys follow the format secret-name or secret-name:json-field:
Plain Text Secrets
// AWS secret name: prod/api-key
// Value: sk_live_12345
APIKey string `secret:"prod/api-key"`
JSON Secrets
// AWS secret name: prod/database
// Value: {"username": "admin", "password": "secret"}
DBUser string `secret:"prod/database:username"`
DBPassword string `secret:"prod/database:password"`
Creating Secrets
# Plain text
aws secretsmanager create-secret \
--name prod/api-key \
--secret-string "sk_live_12345"
# JSON
aws secretsmanager create-secret \
--name prod/database \
--secret-string '{"username":"admin","password":"secret"}'
API Reference
New
func New(ctx context.Context, opts ...Option) (*Provider, error)
Creates a provider using the default AWS configuration.
Parameters:
ctx— context for loading AWS configopts— optional configuration
Returns: (*Provider, error) — error if AWS config loading fails.
NewWithClient
func NewWithClient(client *secretsmanager.Client, opts ...Option) *Provider
Creates a provider with a pre-configured Secrets Manager client.
Example:
import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
)
cfg, _ := config.LoadDefaultConfig(ctx,
config.WithRegion("eu-west-1"),
)
client := secretsmanager.NewFromConfig(cfg)
provider := awssm.NewWithClient(client)
IAM Permissions
Required IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:secretsmanager:*:*:secret:prod/*"
]
}
]
}
Restrict Resource to specific secret ARNs in production.
Cross-Account Access
For secrets in another AWS account:
import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
cfg, _ := config.LoadDefaultConfig(ctx)
stsClient := sts.NewFromConfig(cfg)
assumeRoleCfg, _ := config.LoadDefaultConfig(ctx,
config.WithCredentialsProvider(
stscreds.NewAssumeRoleProvider(stsClient, "arn:aws:iam::123456789012:role/SecretsReader"),
),
)
client := secretsmanager.NewFromConfig(assumeRoleCfg)
provider := awssm.NewWithClient(client)
Error Handling
The provider returns fig.ErrSecretNotFound when:
- The secret doesn't exist
- The secret value is nil
- The requested JSON field doesn't exist
- The JSON field is not a string
Other errors (network, permissions) are returned as-is.
Binary Secrets
AWS Secrets Manager supports binary secrets, but fig only handles string values. For binary secrets, store them as base64-encoded strings and decode after loading:
type Config struct {
CertBase64 string `secret:"tls/certificate"`
}
cfg := Config{}
fig.Load(&cfg, provider)
cert, _ := base64.StdEncoding.DecodeString(cfg.CertBase64)
Next Steps
- Secret Providers Guide — implementing custom providers
- HashiCorp Vault — Vault integration
- GCP Secret Manager — GCP integration