@varlock/aws-secrets-plugin
v0.0.1
Published
Varlock plugin to load secrets from AWS (supports both Secrets Manager and Systems Manager Parameter Store)
Readme
@varlock/aws-secrets-plugin
This package is a Varlock plugin that enables loading data from AWS Secrets Manager and AWS Systems Manager Parameter Store into your configuration.
Features
- Zero-config authentication - Automatically uses AWS credentials from your environment
- IAM role support - No credentials needed for AWS-hosted apps (EC2, ECS, Lambda, etc.)
- AWS CLI authentication - Works seamlessly with
aws configurefor local development - Auto-infer secret/parameter names from environment variable names (uses name as-is)
- JSON key extraction from secrets/parameters using
#syntax or namedkeyparameter - Name prefixing with
namePrefixoption for organized secret management - Support for named AWS profiles
- Support for explicit credentials (access key/secret key)
- Support for temporary credentials (with session tokens)
- Lazy-initialized AWS SDK clients
- Comprehensive error handling with helpful tips
Installation
If you are in a JavaScript based project and have a package.json file, you can either install the plugin explicitly
npm install @varlock/aws-secrets-pluginAnd then register the plugin without any version number
# @plugin(@varlock/aws-secrets-plugin)
# ---Otherwise just set the explicit version number when you register it
# @plugin(@varlock/[email protected])
# ---See our Plugin Guide for more details.
Setup + Auth
After registering the plugin, you must initialize it with the @initAws root decorator.
Automatic auth
For most use cases, you only need to provide the AWS region:
# @plugin(@varlock/aws-secrets-plugin)
# @initAws(region=us-east-1)
# ---How this works:
- Local development: Run
aws configure→ automatically uses AWS CLI credentials - AWS-hosted apps (EC2, ECS, Lambda, Fargate): Attach an IAM role → automatically authenticates (no secrets needed!)
- Works everywhere with zero configuration beyond the region!
Explicit credentials (For non-AWS environments)
If you're deploying outside of AWS (e.g., Azure, GCP, on-premises), wire up IAM credentials:
# @plugin(@varlock/aws-secrets-plugin)
# @initAws(
# region=us-east-1,
# accessKeyId=$AWS_ACCESS_KEY_ID,
# secretAccessKey=$AWS_SECRET_ACCESS_KEY
# )
# ---
# @type=awsAccessKey
AWS_ACCESS_KEY_ID=
# @type=awsSecretKey @sensitive
AWS_SECRET_ACCESS_KEY=You would then need to inject these env vars using your CI/CD system.
Authentication Priority
The plugin tries authentication methods in this order:
- Explicit credentials - If
accessKeyIdandsecretAccessKeyare provided - Named profile - If
profileis specified, uses credentials from~/.aws/credentials - Default AWS credential chain - Environment variables →
~/.aws/credentials→ IAM roles
Using Named Profiles
Use a specific profile from your ~/.aws/credentials file:
# @initAws(region=us-east-1, profile=production)Multiple instances
If you need to connect to multiple instances with different settings, you can register multiple named instances:
# @initAws(id=us, region=us-east-1)
# @initAws(id=eu, region=eu-west-1, profile=eu-prod)Or use functions to populate in values:
# @initAws(region="${AWS_REGION}")Reading secrets and parameters
This plugin introduces two functions: awsSecret() for AWS Secrets Manager and awsParam() for Parameter Store.
# @plugin(@varlock/aws-secrets-plugin)
# @initAws(region=us-east-1)
# ---
# Auto-infer secret names (DATABASE_URL -> "DATABASE_URL")
DATABASE_URL=awsSecret()
API_KEY=awsSecret()
# Explicit secret names
STRIPE_KEY=awsSecret("payments/stripe-secret-key")
# Referring to a single key in items holding key/value pairs
# If "database-creds" contains: {"host": "db.example.com", "password": "secret"}
DB_HOST=awsSecret("database-creds#host")
DB_PASSWORD=awsSecret("database-creds#password")
# Or use named "key" parameter
DB_PORT=awsSecret("database-creds", key="port")
# Parameters from Parameter Store
APP_CONFIG=awsParam("/prod/app/config")
FEATURE_FLAGS=awsParam("/prod/features")
# Auto-infer parameter names too
DATABASE_HOST=awsParam()
# If using multiple instances
US_DATABASE_URL=awsSecret(us, "db-connection")
EU_DATABASE_URL=awsSecret(eu, "db-connection")Name Prefixing
Use namePrefix to automatically prefix all secret/parameter names:
# @initAws(region=us-east-1, namePrefix="prod/api/")
# ---
# Fetches "prod/api/DATABASE_URL"
DATABASE_URL=awsSecret()
# Fetches "prod/api/stripe-key"
STRIPE_KEY=awsSecret("stripe-key")You can even use dynamic prefixes:
# @initAws(region=us-east-1, namePrefix="${ENV}/")
# In prod: fetches "prod/DATABASE_URL"
# In dev: fetches "dev/DATABASE_URL"
DATABASE_URL=awsSecret()Reference
Root decorators
@initAws()
Initialize an AWS plugin instance.
Parameters:
region: string(required) - AWS region (e.g.,us-east-1,eu-west-1)namePrefix?: string- Prefix automatically prepended to all secret/parameter namesaccessKeyId?: string- AWS access key ID for explicit authenticationsecretAccessKey?: string- AWS secret access key for explicit authenticationsessionToken?: string- AWS session token for temporary credentialsprofile?: string- Named profile from~/.aws/credentialsid?: string- Instance identifier for multiple instances (defaults to_default)
Functions
awsSecret()
Fetch a secret from AWS Secrets Manager.
Signatures:
awsSecret()- Auto-infers secret name from variable name (uses name as-is)awsSecret(secretId)- Fetch by explicit secret name/IDawsSecret(secretId, key="jsonKey")- Fetch and extract JSON keyawsSecret(instanceId, secretId)- Fetch from a specific instance
Secret ID Formats:
- Name:
"my-secret" - Name with JSON key:
"my-secret#password"(shorthand for key extraction) - ARN:
"arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret-AbCdEf"
awsParam()
Fetch a parameter from AWS Systems Manager Parameter Store.
Signatures:
awsParam()- Auto-infers parameter name from variable name (uses name as-is)awsParam(parameterName)- Fetch by explicit parameter name/pathawsParam(parameterName, key="jsonKey")- Fetch and extract JSON keyawsParam(instanceId, parameterName)- Fetch from a specific instance
Parameter Formats:
- Simple:
"MyParameter" - Path:
"/prod/app/database-url" - Hierarchical:
"/team/service/env/config" - With JSON key:
"/prod/db/creds#password"
Data Types
awsAccessKey- AWS access key ID (20-character alphanumeric, sensitive)awsSecretKey- AWS secret access key (40 characters, sensitive)
AWS Setup
Required IAM Permissions
For AWS Secrets Manager
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": "arn:aws:secretsmanager:*:*:secret:*"
}
]
}For AWS Systems Manager Parameter Store
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ssm:GetParameter"],
"Resource": "arn:aws:ssm:*:*:parameter/*"
}
]
}Attach IAM Role (Recommended for AWS-hosted apps)
IAM roles are the AWS-native way to authenticate - no credentials needed!
For EC2 instances:
# Create role with trust policy for EC2
aws iam create-role \
--role-name varlock-secrets-reader \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Attach permissions
aws iam put-role-policy \
--role-name varlock-secrets-reader \
--policy-name secrets-access \
--policy-document file://policy.json
# Create and attach instance profile
aws iam create-instance-profile --instance-profile-name varlock-secrets-reader
aws iam add-role-to-instance-profile \
--instance-profile-name varlock-secrets-reader \
--role-name varlock-secrets-reader
# Attach to EC2 instance
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=varlock-secrets-readerFor ECS tasks:
# Create role with trust policy for ECS
aws iam create-role \
--role-name varlock-ecs-task-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ecs-tasks.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Attach permissions
aws iam put-role-policy \
--role-name varlock-ecs-task-role \
--policy-name secrets-access \
--policy-document file://policy.json
# Reference in task definition
# "taskRoleArn": "arn:aws:iam::123456789012:role/varlock-ecs-task-role"For Lambda functions:
# Create role with trust policy for Lambda
aws iam create-role \
--role-name varlock-lambda-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Attach permissions
aws iam put-role-policy \
--role-name varlock-lambda-role \
--policy-name secrets-access \
--policy-document file://policy.json
# Attach to Lambda function
aws lambda update-function-configuration \
--function-name my-function \
--role arn:aws:iam::123456789012:role/varlock-lambda-roleThat's it! Your app will now automatically authenticate using the IAM role.
Create IAM User (For non-AWS environments)
# Create IAM user
aws iam create-user --user-name varlock-secrets-reader
# Attach policy
aws iam put-user-policy \
--user-name varlock-secrets-reader \
--policy-name secrets-access \
--policy-document file://policy.json
# Create access key
aws iam create-access-key --user-name varlock-secrets-readerSave the AccessKeyId and SecretAccessKey from the output - you'll need them for non-AWS deployments.
Configure AWS CLI
For local development:
aws configure
# AWS Access Key ID: [your key]
# AWS Secret Access Key: [your secret]
# Default region name: us-east-1
# Default output format: jsonOr manually create ~/.aws/credentials:
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
[production]
aws_access_key_id = AKIAI44QH8DHBEXAMPLE
aws_secret_access_key = je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEYTroubleshooting
Secret not found
- Verify the secret exists:
aws secretsmanager list-secrets --query 'SecretList[?Name==\my-secret`]'` - Check you're using the correct region:
aws secretsmanager get-secret-value --secret-id my-secret --region us-east-1
Parameter not found
- Verify the parameter exists:
aws ssm describe-parameters --parameter-filters "Key=Name,Values=/my/param" - Check you're using the correct region
Permission denied
- Check your IAM permissions:
aws iam get-user-policy --user-name varlock-secrets-reader --policy-name secrets-access - For IAM roles on EC2:
aws sts get-caller-identity(run from the instance to see what role is attached) - Ensure the IAM policy includes the required actions (
secretsmanager:GetSecretValueand/orssm:GetParameter)
Authentication failed
- Local dev: Run
aws configureor ensureAWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYare set - AWS-hosted apps: Verify IAM role is attached and has the required permissions
- Other environments: Verify credentials are correct and properly injected
- Test credentials:
aws sts get-caller-identity
