← Back to home

Documentation

Everything you need to get started with Envilder.

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

Installation

pnpm
pnpm add -g envilder
npm
npm install -g envilder
npx
npx envilder --help

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:

OperationPermission
Pullssm:GetParameter
Pushssm: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

OperationPermission
PullGet
PushSet

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.

📄
Structure: Each key becomes an env var name in your .env file. Each value is the path where the secret lives 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 /):

param-map.json json
{
  "API_KEY": "/myapp/prod/api-key",
  "DB_PASSWORD": "/myapp/prod/db-password",
  "SECRET_TOKEN": "/myapp/prod/secret-token"
}

This generates:

.env dotenv
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

KeyTypeDefaultDescription
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:

param-map.json json
{
  "$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:

param-map.json json
{
  "$config": {
    "provider": "azure",
    "vaultUrl": "https://my-vault.vault.azure.net"
  },
  "API_KEY": "myapp-prod-api-key",
  "DB_PASSWORD": "myapp-prod-db-password"
}
⚠️
Azure naming convention: Key Vault secret names only allow alphanumeric characters and hyphens. Envilder automatically normalizes names — slashes and underscores become hyphens (e.g., /myapp/db/password → myapp-db-password).

Key differences by provider

AWS SSMAzure Key Vault
Secret path format Parameter paths with slashes
/myapp/prod/api-key
Hyphenated names
myapp-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/dev/param-map.json json
{
  "$config": {
    "provider": "aws",
    "profile": "dev-account"
  },
  "API_KEY": "/myapp/dev/api-key",
  "DB_PASSWORD": "/myapp/dev/db-password"
}
config/prod/param-map.json json
{
  "$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

OptionDescription
--mapPath to JSON mapping file
--envfilePath to write .env
--provideraws (default) or azure
--vault-urlAzure Key Vault URL
--profileAWS 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

.env dotenv
# 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

OptionDescription
--pushEnable push mode (required)
--envfilePath to your local .env file
--mapPath to parameter mapping JSON
--provideraws (default) or azure
--vault-urlAzure Key Vault URL
--profileAWS 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

OptionDescription
--pushEnable push mode (required)
--keyEnvironment variable name
--valueValue to store
--secret-pathFull secret path in your cloud provider
--provideraws (default) or azure
--vault-urlAzure Key Vault URL
--profileAWS 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

.github/workflows/deploy.yml yaml
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

.github/workflows/deploy-env.yml yaml
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

.github/workflows/deploy-azure.yml yaml
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

InputRequiredDefaultDescription
map-fileYesPath to JSON mapping file
env-fileYesPath to the .env file to generate
providerNoawsaws or azure
vault-urlNoAzure Key Vault URL

Outputs

OutputDescription
env-file-pathPath to the generated .env file

Configuration priority

When multiple configuration sources are present, Envilder resolves them in this order (highest wins):

1. CLI flags / GHA inputs
2. $config in map file
3. Defaults (AWS)

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
  • truetrue → Azure RBAC (recommended)
  • false / nullfalse / 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.