A Rust-based CLI tool for automatic secret rotation with support for HashiCorp Vault and AWS Secrets Manager. This tool enables automated management of secrets with configurable rotation periods, making it ideal for use in CI/CD pipelines and automation platforms like Jenkins, GitLab CI, and GitHub Actions.
- Multiple Backend Support: Works with HashiCorp Vault KV v2, AWS Secrets Manager, and local file storage
- HashiCorp Vault Integration: Seamlessly works with Vault KV v2 secrets engine
- AWS Secrets Manager Integration: Full support for AWS Secrets Manager with tag-based metadata and region configuration
- File Backend: Local file storage for testing and development (simple key:value format)
- Automatic Rotation: Flag secrets for automatic rotation with customizable periods
- Configurable Schedule: Default 6-month rotation period, customizable per secret
- CI/CD Ready: Designed for automation platforms (Jenkins, GitLab CI, GitHub Actions)
- Scanning: Scan vault paths to identify secrets needing rotation
- Metadata Tracking: Uses backend metadata to track rotation status and schedules
- Flexible Configuration: Configure via file or environment variables
- Password Generation: Generate secure random passwords and store them in backends
- Environment Variable Sync: Automatically update local shell config files with rotated secrets
- Auto-Update Workflow: Rotate secrets and update environment variables in one command
- Target System: Update passwords in target systems (databases, APIs) during rotation
- PostgreSQL Integration: Automatically update PostgreSQL database passwords when rotating secrets
- API Target Support: Update passwords via REST API calls with configurable endpoints and methods
- Comprehensive Testing: Full unit test suite with 38+ tests covering all major functionality
- GitHub Actions CI/CD: Automated testing and binary releases for multiple platforms
- Rust 1.70+ (will be auto-installed by the installer script)
- HashiCorp Vault server (or use Docker for local development)
Install with a single command:
curl -fsSL https://raw.githubusercontent.com/kelleyblackmore/Automatic-Secret-Rotation/main/install.sh | bashThis will:
- Download pre-built binary from GitHub releases (if available for your platform)
- Fall back to building from source if no pre-built binary is available:
- Install Rust (if not already installed)
- Clone the repository
- Build the binary
- Install the binary to
~/.local/bin/:- macOS:
secret-rotator(default, to avoid conflict with systemasr) - Other platforms:
asr(default)
- macOS:
- Verify the installation
Note: Pre-built binaries are available for:
- Linux (x86_64, ARM64)
- macOS (x86_64, ARM64/Apple Silicon)
After installation, you may need to add ~/.local/bin to your PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrcNote for macOS users: macOS includes a system tool called asr (Apple Software Restore) at /usr/sbin/asr. The installer automatically handles this by:
- Defaulting to
secret-rotatoras the binary name on macOS to avoid conflicts - Detecting macOS and informing you of the default
- Allowing you to override with
ASR_BINARY_NAME=asrif you prefer
Installation options:
# Use custom binary name
ASR_BINARY_NAME=my-custom-name ./install.sh
# Force build from source (skip binary download)
ASR_BUILD_FROM_SOURCE=1 ./install.sh
# Combine options
ASR_BINARY_NAME=rotator ASR_BUILD_FROM_SOURCE=1 ./install.shgit clone https://github.com/kelleyblackmore/Automatic-Secret-Rotation.git
cd Automatic-Secret-Rotation
make installmake build # Debug build
make release # Release build
# Binary will be in target/release/asrcargo install --git https://github.com/kelleyblackmore/Automatic-Secret-RotationUse the ASR tool in a container:
# Build from Dockerfile.example (or use the provided example)
docker build -f Dockerfile.example -t asr:latest .
# Run commands
docker run --rm asr:latest --help
docker run --rm -v $(pwd):/workspace asr:latest scan
# With environment variables
docker run --rm \
-e VAULT_ADDR=http://vault:8200 \
-e VAULT_TOKEN=your-token \
-e SECRET_BACKEND=vault \
asr:latest auto
# Build specific version
docker build -f Dockerfile.example --build-arg ASR_VERSION=v1.0.0 -t asr:v1.0.0 .The Dockerfile will:
- Try to download pre-built binaries from GitHub releases
- Fall back to building from source if binaries aren't available
- Support both x86_64 and ARM64 architectures
The project includes a Makefile with helpful commands:
make help # Show all available commands
make vault-docker # Start Vault in Docker for testing
make vault-full-setup # Start Vault with test secrets
make test # Run tests
make all # Format, lint, test, and buildCreate a sample configuration file:
asr init -o rotator-config.tomlEdit the configuration with your Vault details:
[vault]
address = "http://127.0.0.1:8200"
token = "your-vault-token-here"
mount = "secret"
[rotation]
period_months = 6
secret_length = 32Flag a secret to be rotated every 6 months:
asr flag my-app/database-password --period 6Check which secrets are due for rotation:
asr scanRotate all secrets that are due:
asr autoOr with automatic environment variable updates:
asr auto --update-envPerform a dry-run first:
asr auto --dry-runGenerate a secure password, store it in Vault, and optionally update your local environment:
# Generate and store in Vault only
asr gen-password myapp/database
# Generate, store, AND update local environment variable
asr gen-password --env-var DB_PASSWORD myapp/database
# Custom length
asr gen-password --env-var API_KEY --length 48 myapp/api
# Custom key name in Vault (default is "password")
asr gen-password --env-var TOKEN --key token myapp/githubUpdate your local shell config with an existing Vault secret:
# Sync secret to environment variable
asr update-env --env-var DB_PASSWORD myapp/database
# Sync with custom key
asr update-env --env-var API_TOKEN --key token myapp/githubAfter updating environment variables:
source ~/.bashrc # or ~/.zshrc
echo $DB_PASSWORD # Verify it's setThe tool can be configured in two ways:
Create a TOML configuration file:
For Vault:
backend = "vault"
[vault]
address = "http://127.0.0.1:8200"
token = "hvs.your-vault-token"
mount = "secret"
[rotation]
period_months = 6
secret_length = 32For AWS Secrets Manager:
backend = "aws"
[aws]
region = "us-east-1"
[rotation]
period_months = 6
secret_length = 32For File Backend (Local Storage):
backend = "file"
[file]
directory = "~/.asr/secrets" # Default: ~/.asr/secrets
[rotation]
period_months = 6
secret_length = 32Use it with:
asr -c rotator-config.toml <command>For Vault:
export SECRET_BACKEND="vault"
export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN="hvs.your-vault-token"
export VAULT_MOUNT="secret"
export ROTATION_PERIOD_MONTHS=6
export SECRET_LENGTH=32
asr <command>For AWS Secrets Manager:
export SECRET_BACKEND="aws"
export AWS_REGION="us-east-1"
export ROTATION_PERIOD_MONTHS=6
export SECRET_LENGTH=32
# AWS credentials are automatically detected from:
# - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
# - AWS credentials file (~/.aws/credentials)
# - IAM role (when running on EC2/ECS/Lambda)
asr <command>For File Backend:
export SECRET_BACKEND="file"
export ASR_FILE_DIR="~/.asr/secrets" # Optional, defaults to ~/.asr/secrets
export ROTATION_PERIOD_MONTHS=6
export SECRET_LENGTH=32
asr <command>File Format:
Secrets are stored in plain text files with key:value format, one per line:
password:mysecret123
username:admin
Metadata is stored in a separate .meta file alongside each secret file.
Configure target systems where passwords should be updated during rotation:
PostgreSQL Target:
[targets.postgres]
host = "localhost"
port = 5432
database = "postgres"
username = "admin"
password_path = "admin/password" # Path in backend for admin password
ssl_mode = "prefer" # Options: disable, allow, prefer, require, verify-ca, verify-fullAPI Target:
[targets.api]
base_url = "https://api.example.com"
endpoint = "/users/{username}/password" # {username} will be replaced
method = "POST" # GET, POST, PUT, PATCH, DELETE
password_field = "password"
username_field = "username" # Optional
timeout_seconds = 30
auth_header = "Bearer token123" # Optional
[targets.api.headers] # Optional additional headers
X-Custom-Header = "value"Legacy Database Config (deprecated, use [targets.postgres] instead):
[database]
host = "localhost"
port = 5432
database = "postgres"
username = "admin"
password_path = "admin/password"Create a sample configuration file:
asr init
asr init -o custom-config.tomlMark a secret for automatic rotation:
# Use default 6-month period
asr flag app/db-password
# Custom rotation period
asr flag app/api-key --period 3List all secrets that need rotation:
# Scan all secrets
asr scan
# Scan specific path
asr scan app/Manually rotate a specific secret:
# Basic rotation
asr rotate app/db-password
# Rotate and update target password (PostgreSQL, API, etc.)
asr rotate app/db-password --update-target --target-username myapp_userWhen using --update-target, the tool will:
- Rotate the secret in the backend (Vault/AWS/File)
- Update the password in the configured target system (PostgreSQL database or API)
- Verify the new password works
Rotate all secrets that are due for rotation:
# Perform rotation
asr auto
# Dry run (show what would be rotated)
asr auto --dry-run
# Scan specific path
asr auto app/
# Rotate and update environment variables
asr auto --update-env
# Rotate and update target passwords (databases, APIs)
asr auto --update-target
# Rotate, update env vars, and update targets
asr auto --update-env --update-targetWhen using --update-env, environment variables are automatically created based on the secret path:
myapp/database→MYAPP_DATABASEapi/github→API_GITHUB
Generate a secure random password and store it in Vault:
# Generate and store in Vault
asr gen-password myapp/database
# Generate and update local environment variable
asr gen-password --env-var DB_PASSWORD myapp/database
# Custom length (default: 32 characters)
asr gen-password --length 48 myapp/api-key
# Custom key name (default: "password")
asr gen-password --key token --env-var API_TOKEN myapp/githubUpdate local environment variables with secrets from Vault:
# Update environment variable from Vault
asr update-env --env-var DB_PASSWORD myapp/database
# Use custom key from secret
asr update-env --env-var API_TOKEN --key token myapp/githubThis command updates your shell configuration files (.bashrc, .bash_profile, .zshrc, .profile) with the secret value. You'll need to reload your shell for changes to take effect:
source ~/.bashrcRead and display a secret:
asr read app/db-passwordList all secrets at a path:
asr list
asr list app/Scenario: You want to test secret rotation locally without setting up Vault or AWS.
# Set backend to file
export SECRET_BACKEND="file"
export ASR_FILE_DIR="./test-secrets" # Use local directory for testing
# Generate a password
asr gen-password myapp/database --key password
# Flag for rotation
asr flag myapp/database --period 3
# Scan for secrets needing rotation
asr scan
# Rotate secrets
asr auto
# View the secret file
cat test-secrets/myapp/database
# Output:
# password:2ed1md...
# View metadata
cat test-secrets/myapp/database.meta
# Output:
# rotation_enabled:true
# last_rotated:2024-01-15T10:30:00ZFile Structure:
test-secrets/
├── myapp/
│ ├── database # Secret file (key:value format)
│ └── database.meta # Metadata file
└── api/
├── token
└── token.meta
Scenario: You're deploying a new application and need to create a database password.
# 1. Generate and store a new password
asr gen-password myapp/production/database --key password --length 40
# 2. Flag it for automatic rotation every 3 months
asr flag myapp/production/database --period 3
# 3. Verify it was created and flagged
asr read myapp/production/database
asr scan myapp/production/With Environment Variable Sync:
# Generate password and automatically update local environment
asr gen-password --env-var DB_PASSWORD myapp/production/database --key password
# Reload shell to use the new variable
source ~/.bashrc
echo $DB_PASSWORDScenario: You're deploying a new application in AWS and need to create an API key.
# Set backend to AWS
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# 1. Generate and store a new API key
asr gen-password myapp/production/api --key api_key --length 48
# 2. Flag it for automatic rotation every 6 months
asr flag myapp/production/api --period 6
# 3. Verify it was created and flagged
asr read myapp/production/api
asr scan myapp/production/Using Config File:
# config-aws.toml
backend = "aws"
[aws]
region = "us-east-1"
[rotation]
period_months = 6
secret_length = 32asr -c config-aws.toml gen-password myapp/production/api --key api_key
asr -c config-aws.toml flag myapp/production/api --period 6Scenario: Automatically rotate all secrets weekly in your CI/CD pipeline.
GitHub Actions with Vault:
name: Weekly Secret Rotation
on:
schedule:
- cron: '0 0 * * 0' # Every Sunday at midnight
workflow_dispatch:
jobs:
rotate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install asr
run: cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- name: Rotate Vault secrets
env:
SECRET_BACKEND: vault
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
VAULT_MOUNT: secret
run: |
asr auto --dry-run # Preview what will be rotated
asr auto # Perform rotationGitHub Actions with AWS Secrets Manager:
name: Weekly Secret Rotation
on:
schedule:
- cron: '0 0 * * 0' # Every Sunday at midnight
workflow_dispatch:
jobs:
rotate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Install asr
run: cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- name: Rotate AWS Secrets Manager secrets
env:
SECRET_BACKEND: aws
AWS_REGION: us-east-1
run: |
asr auto --dry-run # Preview what will be rotated
asr auto # Perform rotationScenario: Managing secrets across development, staging, and production environments.
Vault Example:
# Development environment
export VAULT_ADDR="http://vault-dev.example.com:8200"
export VAULT_TOKEN="$DEV_VAULT_TOKEN"
# Create secrets for each environment
asr gen-password dev/database --key password
asr gen-password staging/database --key password
asr gen-password production/database --key password
# Flag production secrets for rotation (more frequent)
asr flag production/database --period 3
asr flag staging/database --period 6
asr flag dev/database --period 12 # Less frequent for dev
# Scan specific environment
asr scan production/AWS Secrets Manager Example:
# Using different AWS profiles/regions for each environment
export SECRET_BACKEND=aws
# Development
export AWS_PROFILE=dev
export AWS_REGION=us-west-2
asr gen-password dev/database --key password
asr flag dev/database --period 12
# Staging
export AWS_PROFILE=staging
export AWS_REGION=us-east-1
asr gen-password staging/database --key password
asr flag staging/database --period 6
# Production
export AWS_PROFILE=production
export AWS_REGION=us-east-1
asr gen-password production/database --key password
asr flag production/database --period 3Scenario: A secret has been compromised and needs immediate rotation.
Vault:
# 1. Immediately rotate the compromised secret
asr rotate production/api-key
# 2. Update the application with the new secret
# (The secret value is displayed - copy it securely)
# 3. Verify rotation timestamp was updated
asr scan production/api-key
# 4. If needed, update rotation period for more frequent rotations
asr flag production/api-key --period 1 # Rotate monthly going forwardAWS Secrets Manager:
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# 1. Immediately rotate the compromised secret
asr rotate production/api-key
# 2. Update the application with the new secret
# (The secret value is displayed - copy it securely)
# 3. Verify rotation timestamp was updated
asr scan production/api-key
# 4. Update rotation period for more frequent rotations
asr flag production/api-key --period 1 # Rotate monthly going forwardScenario: Migrating multiple secrets or performing bulk operations.
Vault:
# List all secrets in a path
asr list production/
# Scan all secrets that need rotation
asr scan production/
# Rotate all secrets that are due (with dry-run first)
asr auto --dry-run production/
asr auto production/
# Rotate all secrets and update environment variables
asr auto --update-env production/AWS Secrets Manager:
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# List all secrets with a prefix
asr list production/
# Scan all secrets that need rotation
asr scan production/
# Rotate all secrets that are due (with dry-run first)
asr auto --dry-run production/
asr auto production/Scenario: Your application reads secrets from environment variables, and you want them automatically updated.
Vault:
# 1. Generate password and sync to environment variable
asr gen-password --env-var DB_PASSWORD myapp/database --key password
# 2. Flag for rotation
asr flag myapp/database --period 6
# 3. When rotation happens, automatically update env var
asr auto --update-env myapp/
# 4. Reload shell to pick up new values
source ~/.bashrc
# 5. Your application can now use the updated $DB_PASSWORDAWS Secrets Manager:
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# Same workflow works identically
asr gen-password --env-var DB_PASSWORD myapp/database --key password
asr flag myapp/database --period 6
asr auto --update-env myapp/
source ~/.bashrcScenario: Regular monitoring of secret rotation status.
Vault:
# Check what secrets need rotation
asr scan
# Check specific application
asr scan myapp/
# Dry run to see what would be rotated
asr auto --dry-run
# View secret metadata (rotation status)
asr read myapp/database # Shows last_rotated in metadataAWS Secrets Manager:
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# Check what secrets need rotation
asr scan
# Check specific application
asr scan myapp/
# Dry run to see what would be rotated
asr auto --dry-run
# View secret tags (rotation status)
aws secretsmanager describe-secret --secret-id myapp/database --query 'Tags'Scenario: Migrating secrets from Vault to AWS Secrets Manager (or vice versa).
# 1. Read secret from Vault
export SECRET_BACKEND=vault
export VAULT_ADDR="http://vault.example.com:8200"
export VAULT_TOKEN="$VAULT_TOKEN"
SECRET_VALUE=$(asr read myapp/database | grep "password:" | awk '{print $2}')
# 2. Write to AWS Secrets Manager
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# Create secret in AWS (as JSON)
echo "{\"password\": \"$SECRET_VALUE\"}" | \
aws secretsmanager create-secret --name myapp/database --secret-string file:///dev/stdin
# 3. Flag for rotation in AWS
asr flag myapp/database --period 6Scenario: Using rotated secrets in CI/CD pipelines without exposing them in logs.
GitLab CI with Vault:
rotate-and-deploy:
image: rust:latest
before_script:
- cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- asr auto # Rotate secrets if needed
script:
# Fetch latest secret (without displaying it)
- export DB_PASSWORD=$(asr read myapp/database | grep "password:" | awk '{print $2}')
- echo "Deploying with rotated secret..."
# Use $DB_PASSWORD in your deployment
variables:
SECRET_BACKEND: vault
VAULT_ADDR: $VAULT_ADDR
VAULT_TOKEN: $VAULT_TOKENGitLab CI with AWS Secrets Manager:
rotate-and-deploy:
image: rust:latest
before_script:
- cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- asr auto # Rotate secrets if needed
script:
# Fetch latest secret (without displaying it)
- export DB_PASSWORD=$(asr read myapp/database | grep "password:" | awk '{print $2}')
- echo "Deploying with rotated secret..."
# Use $DB_PASSWORD in your deployment
variables:
SECRET_BACKEND: aws
AWS_REGION: us-east-1name: Rotate Secrets (Vault)
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:
jobs:
rotate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install asr
run: cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- name: Rotate secrets
env:
SECRET_BACKEND: vault
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
VAULT_MOUNT: secret
run: |
asr auto --dry-run # Preview changes
asr auto # Perform rotationname: Rotate Secrets (AWS)
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:
jobs:
rotate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Install asr
run: cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- name: Rotate secrets
env:
SECRET_BACKEND: aws
AWS_REGION: us-east-1
run: |
asr auto --dry-run # Preview changes
asr auto # Perform rotationrotate-secrets-vault:
image: rust:latest
script:
- cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- asr auto --dry-run
- asr auto
variables:
SECRET_BACKEND: vault
VAULT_ADDR: $VAULT_ADDR
VAULT_TOKEN: $VAULT_TOKEN
VAULT_MOUNT: secret
only:
- schedulesrotate-secrets-aws:
image: rust:latest
before_script:
- apt-get update && apt-get install -y awscli
- aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
- aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
- aws configure set region us-east-1
script:
- cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation
- asr auto --dry-run
- asr auto
variables:
SECRET_BACKEND: aws
AWS_REGION: us-east-1
only:
- schedulespipeline {
agent any
triggers {
cron('0 0 * * 0') // Weekly on Sunday
}
environment {
SECRET_BACKEND = 'vault'
VAULT_ADDR = credentials('vault-addr')
VAULT_TOKEN = credentials('vault-token')
VAULT_MOUNT = 'secret'
}
stages {
stage('Install') {
steps {
sh 'cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation'
}
}
stage('Rotate Secrets') {
steps {
sh 'asr auto --dry-run'
sh 'asr auto'
}
}
}
}pipeline {
agent any
triggers {
cron('0 0 * * 0') // Weekly on Sunday
}
environment {
SECRET_BACKEND = 'aws'
AWS_REGION = 'us-east-1'
AWS_ACCESS_KEY_ID = credentials('aws-access-key-id')
AWS_SECRET_ACCESS_KEY = credentials('aws-secret-access-key')
}
stages {
stage('Install') {
steps {
sh 'cargo install --git https://github.com/kelleyblackmore/Automatic-Secret-Rotation'
}
}
stage('Rotate Secrets') {
steps {
sh 'asr auto --dry-run'
sh 'asr auto'
}
}
}
}The tool uses backend-specific metadata to track rotation status:
For HashiCorp Vault:
- Uses Vault's custom metadata feature
rotation_enabled: Set to "true" for secrets that should be rotatedlast_rotated: RFC3339 timestamp of last rotationrotation_period_months: Custom rotation period (optional)
For AWS Secrets Manager:
- Uses AWS Secrets Manager tags
rotation_enabled: Tag set to "true" for secrets that should be rotatedlast_rotated: Tag with RFC3339 timestamp of last rotationrotation_period_months: Tag with custom rotation period (optional)
For File Backend:
- Uses separate
.metafiles alongside secret files rotation_enabled: Set to "true" for secrets that should be rotatedlast_rotated: RFC3339 timestamp of last rotationrotation_period_months: Custom rotation period (optional)
- Flagging: When you flag a secret, metadata/tags are added to track rotation
- Scanning: The tool reads metadata/tags to identify secrets needing rotation
- Rotation: New random secrets are generated and written to the backend
- Tracking: Metadata/tags are updated with the new rotation timestamp
- Environment Sync (optional): Local shell configs are updated with new values
Backend Differences:
- Vault: Secrets stored as key-value pairs, metadata stored in Vault's metadata system
- AWS Secrets Manager: Secrets stored as JSON strings, metadata stored as tags
Secrets are generated using cryptographically secure random number generation with a character set including:
- Uppercase letters (A-Z)
- Lowercase letters (a-z)
- Numbers (0-9)
- Special characters (!@#$%^&*)
The tool can automatically update your shell configuration files with rotated secrets:
- Shell Config Files: Updates
.bashrc,.bash_profile,.zshrc, and.profile - Smart Updates: If a variable already exists, it's updated in-place; otherwise, it's appended
- Comments: Adds
# Auto-updated by secret rotatorfor tracking - Path Mapping: Converts secret paths to environment variable names (e.g.,
myapp/database→MYAPP_DATABASE)
This enables seamless integration of backend-managed secrets with applications that read from environment variables. Works identically for both Vault and AWS Secrets Manager.
- Credentials: Store backend credentials securely using secret management in your CI/CD platform
- TLS: Use HTTPS/TLS for all backend communication in production
- Permissions: Ensure credentials have minimal required permissions (principle of least privilege)
- Audit: Enable audit logging in your backend to track all secret operations
- Backup: Ensure secrets are backed up before rotation
- Terminal Output: The
rotateandreadcommands intentionally display secret values. Always:- Use these commands in secure environments only
- Clear your terminal history after viewing secrets
- Avoid logging command output that contains secrets
- Use the
autocommand for automated rotation (doesn't display secrets) - Never redirect output containing secrets to files unless properly secured
- Vault Token: Store Vault tokens securely using secret management in your CI/CD platform
- TLS: Use HTTPS for Vault communication in production
- Permissions: Ensure the Vault token has appropriate policies for reading, writing, and updating metadata
- Audit: Enable Vault audit logging to track all secret operations
- IAM Roles: Prefer IAM roles over access keys when running on EC2/ECS/Lambda
- Access Keys: If using access keys, rotate them regularly and store them securely
- IAM Policies: Use least-privilege IAM policies (see setup section for example)
- Encryption: AWS Secrets Manager automatically encrypts secrets at rest using KMS
- CloudTrail: Enable CloudTrail to audit all Secrets Manager API calls
- Resource Policies: Use resource-based policies to restrict access to specific secrets
vault secrets enable -version=2 -path=secret kvCreate a policy file rotator-policy.hcl:
path "secret/data/*" {
capabilities = ["create", "read", "update"]
}
path "secret/metadata/*" {
capabilities = ["create", "read", "update", "list"]
}Apply the policy:
vault policy write rotator rotator-policy.hcl
vault token create -policy=rotatorAWS Secrets Manager requires AWS credentials with appropriate permissions. The tool uses AWS SDK's default credential chain, which checks:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - AWS credentials file (
~/.aws/credentials) - IAM roles (when running on EC2/ECS/Lambda)
Create an IAM policy with the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:PutSecretValue",
"secretsmanager:CreateSecret",
"secretsmanager:UpdateSecret",
"secretsmanager:DescribeSecret",
"secretsmanager:ListSecrets",
"secretsmanager:TagResource"
],
"Resource": "*"
}
]
}- Secrets in AWS Secrets Manager are stored as JSON strings
- Metadata is stored as tags (e.g.,
rotation_enabled,last_rotated,rotation_period_months) - Secret names can include forward slashes (e.g.,
myapp/database/password)
cargo buildcargo testcargo run -- --help"Command not found" or "Wrong command executing"
On macOS, the installer defaults to installing the binary as secret-rotator to avoid conflict with the system asr tool.
-
Check which binary was installed:
ls ~/.local/bin/ | grep -E "(asr|secret-rotator)"
-
Use the correct command name:
# Default on macOS: secret-rotator --help # If you installed with ASR_BINARY_NAME=asr: asr --help
-
If you want to use 'asr' on macOS:
# Reinstall with custom name: ASR_BINARY_NAME=asr ./install.sh # Then ensure ~/.local/bin comes before /usr/sbin in PATH: export PATH="$HOME/.local/bin:$PATH"
-
Verify PATH configuration:
which secret-rotator # Should show: ~/.local/bin/secret-rotator echo $PATH | grep -o "[^:]*" | grep -n "local" # ~/.local/bin should appear before /usr/sbin
"Backend configuration not found"
- Verify
SECRET_BACKENDis set to either "vault" or "aws" - Check that the appropriate backend configuration section exists in your config file
- Ensure required environment variables are set
"Failed to authenticate"
- Verify credentials are correct and not expired
- Check that credentials have the necessary permissions
- For AWS, verify the credential chain is working (
aws sts get-caller-identity)
"Failed to connect to Vault"
- Verify
VAULT_ADDRis correct - Ensure Vault is running and accessible
- Check network connectivity
- Verify TLS certificates if using HTTPS
"Permission denied"
- Verify your Vault token has the necessary permissions
- Check the Vault policy allows read/write/metadata operations
- Ensure token hasn't expired
"Secret not found"
- Verify the mount path is correct (default:
secret) - Check the secret path exists in Vault
- Ensure you're using KV v2 (not v1)
"Failed to create AWS Secrets Manager client"
- Verify AWS credentials are configured correctly
- Check
AWS_REGIONis set or configured in AWS config - Test credentials:
aws sts get-caller-identity
"AccessDeniedException"
- Verify IAM user/role has required Secrets Manager permissions
- Check resource-based policies if using them
- Ensure you're using the correct AWS account/region
"ResourceNotFoundException"
- Verify the secret name is correct (case-sensitive)
- Check that you're querying the correct AWS region
- List secrets:
aws secretsmanager list-secrets
"InvalidParameterException"
- AWS Secrets Manager stores secrets as JSON strings
- Ensure secret data is valid JSON when writing
- Check secret name format (can include forward slashes)
"Secrets not appearing in list"
- AWS Secrets Manager paginates results - the tool handles this automatically
- Verify you're querying the correct region
- Check IAM permissions include
secretsmanager:ListSecrets
Apache License - see LICENSE file for details
Vault Examples:
# Generate password with env var update
asr gen-password --env-var DB_PASS myapp/db
# Sync Vault secret to environment
asr update-env --env-var API_KEY myapp/api
# Rotate all due secrets and update env vars
asr auto --update-env
# Flag secret for rotation
asr flag myapp/password --period 3
# Scan for secrets needing rotation
asr scan
# Dry run auto-rotation
asr auto --dry-runAWS Secrets Manager Examples:
# Set backend
export SECRET_BACKEND=aws
export AWS_REGION=us-east-1
# Generate password
asr gen-password --env-var DB_PASS myapp/db
# Sync AWS secret to environment
asr update-env --env-var API_KEY myapp/api
# Rotate all due secrets
asr auto --update-env
# Flag secret for rotation
asr flag myapp/password --period 3
# Scan for secrets needing rotation
asr scan
# Dry run auto-rotation
asr auto --dry-runmake install # Install the binary
make vault-docker # Start Vault in Docker
make vault-full-setup # Start Vault with test data
make demo # Quick demo with Vault
make test # Run tests
make all # Format, lint, test, buildContributions are welcome! Please feel free to submit a Pull Request.