What is Envilder?
Envilder is a CLI tool and GitHub Action that pulls environment variables from a cloud vault (AWS SSM Parameter Store or Azure Key Vault) and writes them to a local .env file — or pushes them back. You define a simple JSON mapping between variable names and secret paths, and Envilder does the rest.
Without Envilder, teams copy secrets by hand, store them in plaintext .env files committed to repos, or maintain fragile shell scripts per environment. This leads to leaked credentials, inconsistent configurations, and slow onboarding.
With Envilder, one param-map.json file is the single source of truth. Secrets never leave the vault until runtime, every environment uses the same mapping, and a new developer is up and running in one command.
Requirements
- Node.js v20+ — Download
- AWS CLI (for AWS SSM) — Install guide
- Azure CLI (for Azure Key Vault) — Install guide
Installation
Cloud credentials
AWS (default)
Envilder uses your AWS CLI credentials. Set up the default profile:
aws configure Or use a named profile:
aws configure --profile dev-account
# Then pass it to envilder
envilder --map=param-map.json --envfile=.env --profile=dev-account Azure Key Vault
Envilder uses Azure Default Credentials. Log in with:
az login Provide the vault URL via $config in your map file or the --vault-url flag.
IAM permissions
AWS
Your IAM user or role needs:
| Operation | Permission |
|---|---|
| Pull | ssm:GetParameter |
| Push | ssm:PutParameter |
Example IAM policy:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["ssm:GetParameter", "ssm:PutParameter"],
"Resource": "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/*"
}]
} Azure
| Operation | Permission |
|---|---|
| Pull | Get |
| Push | Set |
Recommended — assign Key Vault Secrets Officer via RBAC:
az role assignment create \
--role "Key Vault Secrets Officer" \
--assignee <YOUR_OBJECT_ID> \
--scope /subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.KeyVault/vaults/<VAULT> For pull-only access, Key Vault Secrets User is sufficient.
Mapping file
The mapping file (param-map.json) is the core of Envilder. It's a JSON file that maps environment variable names (keys) to secret paths (values) in your cloud provider.
Basic format (AWS SSM — default)
When no $config section is present, Envilder defaults to AWS SSM Parameter Store. Values must be valid SSM parameter paths (typically starting with /):
{
"API_KEY": "/myapp/prod/api-key",
"DB_PASSWORD": "/myapp/prod/db-password",
"SECRET_TOKEN": "/myapp/prod/secret-token"
} This generates:
API_KEY=<value from /myapp/prod/api-key>
DB_PASSWORD=<value from /myapp/prod/db-password>
SECRET_TOKEN=<value from /myapp/prod/secret-token> The $config section
Add a $config key to your mapping file to declare which cloud provider to use and its settings. Envilder reads $config for configuration, and treats all other keys as secret mappings.
$config options
| Key | Type | Default | Description |
|---|---|---|---|
provider | "aws" | "azure" | "aws" | Cloud provider to use |
vaultUrl | string | — | Azure Key Vault URL (required when provider is "azure") |
profile | string | — | AWS CLI profile for multi-account setups (AWS only) |
AWS SSM with profile
To use a specific AWS CLI profile (useful for multi-account setups), add profile to $config:
{
"$config": {
"provider": "aws",
"profile": "prod-account"
},
"API_KEY": "/myapp/prod/api-key",
"DB_PASSWORD": "/myapp/prod/db-password"
} This tells Envilder to use the prod-account profile from your ~/.aws/credentials file instead of the default profile.
Azure Key Vault
For Azure Key Vault, set provider to "azure" and provide the vaultUrl:
{
"$config": {
"provider": "azure",
"vaultUrl": "https://my-vault.vault.azure.net"
},
"API_KEY": "myapp-prod-api-key",
"DB_PASSWORD": "myapp-prod-db-password"
} Key differences by provider
| AWS SSM | Azure Key Vault | |
|---|---|---|
| Secret path format | Parameter paths with slashes/myapp/prod/api-key | Hyphenated namesmyapp-prod-api-key |
| Required $config | None (AWS is the default) | provider + vaultUrl |
| Optional $config | profile | — |
| Authentication | AWS CLI credentials | Azure Default Credentials |
Multiple environments
A common pattern is having one mapping file per environment. The structure is the same, only the secret paths change:
{
"$config": {
"provider": "aws",
"profile": "dev-account"
},
"API_KEY": "/myapp/dev/api-key",
"DB_PASSWORD": "/myapp/dev/db-password"
} {
"$config": {
"provider": "aws",
"profile": "prod-account"
},
"API_KEY": "/myapp/prod/api-key",
"DB_PASSWORD": "/myapp/prod/db-password"
} Then pull the right one:
# Development
envilder --map=config/dev/param-map.json --envfile=.env.dev
# Production
envilder --map=config/prod/param-map.json --envfile=.env.prod Overriding $config with CLI flags
CLI flags always take priority over $config values. This lets you set defaults in the file and override per invocation:
# Uses $config from the map file as-is
envilder --map=param-map.json --envfile=.env
# Overrides provider and vault URL, ignoring $config
envilder --provider=azure \
--vault-url=https://other-vault.vault.azure.net \
--map=param-map.json --envfile=.env
# Overrides just the AWS profile
envilder --map=param-map.json --envfile=.env --profile=staging-account Priority order: CLI flags / GHA inputs → $config in map file → defaults (AWS).
Pull command
Download secrets from your cloud provider and generate a local .env file.
envilder --map=param-map.json --envfile=.env Options
| Option | Description |
|---|---|
--map | Path to JSON mapping file |
--envfile | Path to write .env |
--provider | aws (default) or azure |
--vault-url | Azure Key Vault URL |
--profile | AWS CLI profile to use |
Examples
# Default (AWS SSM)
envilder --map=param-map.json --envfile=.env
# With AWS profile
envilder --map=param-map.json --envfile=.env --profile=prod-account
# Azure via $config in map file
envilder --map=azure-param-map.json --envfile=.env
# Azure via CLI flags
envilder --provider=azure \
--vault-url=https://my-vault.vault.azure.net \
--map=param-map.json --envfile=.env Output
# Generated by Envilder
API_KEY=abc123
DB_PASSWORD=secret456 Push command
Upload environment variables from a local .env file to your cloud provider using a mapping file.
envilder --push --envfile=.env --map=param-map.json Options
| Option | Description |
|---|---|
--push | Enable push mode (required) |
--envfile | Path to your local .env file |
--map | Path to parameter mapping JSON |
--provider | aws (default) or azure |
--vault-url | Azure Key Vault URL |
--profile | AWS CLI profile (AWS only) |
Examples
# Push to AWS SSM
envilder --push --envfile=.env --map=param-map.json
# With AWS profile
envilder --push --envfile=.env.prod --map=param-map.json --profile=prod-account
# Azure via $config in map file
envilder --push --envfile=.env --map=azure-param-map.json
# Azure via CLI flags
envilder --push --provider=azure \
--vault-url=https://my-vault.vault.azure.net \
--envfile=.env --map=param-map.json Push single variable
Push a single environment variable directly without any files.
envilder --push --key=API_KEY --value=<SECRET> --secret-path=/myapp/api/key Options
| Option | Description |
|---|---|
--push | Enable push mode (required) |
--key | Environment variable name |
--value | Value to store |
--secret-path | Full secret path in your cloud provider |
--provider | aws (default) or azure |
--vault-url | Azure Key Vault URL |
--profile | AWS CLI profile (AWS only) |
GitHub Action setup
The Envilder GitHub Action pulls secrets from AWS SSM or Azure Key Vault into .env files during your CI/CD workflow. No build step needed — the action is pre-built and ready to use from GitHub Marketplace.
Prerequisites
- AWS: Configure credentials with aws-actions/configure-aws-credentials
- Azure: Configure credentials with azure/login
- A param-map.json committed to your repository
The GitHub Action only supports pull mode (no push).
Basic workflow example
name: Deploy Application
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: us-east-1
- name: Pull Secrets from AWS SSM
uses: macalbert/envilder/github-action@v0
with:
map-file: config/param-map.json
env-file: .env
- uses: actions/setup-node@v6
with:
node-version: "20.x"
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm deploy Multi-environment workflow
name: Deploy to Environment
on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
type: choice
options: [dev, staging, production]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-24.04
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v5
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: us-east-1
- name: Pull ${{ inputs.environment }} secrets
uses: macalbert/envilder/github-action@v0
with:
map-file: config/${{ inputs.environment }}/param-map.json
env-file: .env
- uses: actions/setup-node@v6
with:
node-version: "20.x"
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm deploy Azure Key Vault workflow
name: Deploy with Azure Key Vault
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Pull Secrets from Azure Key Vault
uses: macalbert/envilder/github-action@v0
with:
map-file: config/param-map.json
env-file: .env
provider: azure
vault-url: https://my-vault.vault.azure.net
- uses: actions/setup-node@v6
with:
node-version: "20.x"
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm deploy Action inputs & outputs
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
map-file | Yes | — | Path to JSON mapping file |
env-file | Yes | — | Path to the .env file to generate |
provider | No | aws | aws or azure |
vault-url | No | — | Azure Key Vault URL |
Outputs
| Output | Description |
|---|---|
env-file-path | Path to the generated .env file |
Configuration priority
When multiple configuration sources are present, Envilder resolves them in this order (highest wins):
This means --provider=azure on the CLI will override "provider": "aws" in $config.
Azure Key Vault setup
Check which access model your vault uses:
az keyvault show --name <VAULT_NAME> \
--query properties.enableRbacAuthorization true→ true → Azure RBAC (recommended)false/null→ false / null → Vault Access Policy (classic)
Option A — Azure RBAC (recommended)
az role assignment create \
--role "Key Vault Secrets Officer" \
--assignee <YOUR_OBJECT_ID> \
--scope /subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.KeyVault/vaults/<VAULT> Option B — Vault Access Policy
az keyvault set-policy \
--name <VAULT_NAME> \
--object-id <YOUR_OBJECT_ID> \
--secret-permissions get set list For pull-only access, get list is enough. Add set for push.