Map file reference
What can envilder.json contain, and how does Envilder read it? It is one JSON object that maps environment variable names to secret identifiers, with an optional $config block for the provider, profile and vault URL. CLI flags override $config field by field, and an invalid name or provider stops the run before any secret is read.
Prerequisites
This page describes the map file as read by the envilder CLI (0.16) and the GitHub Action. The runtime SDKs read the same file. If you have not resolved a secret yet, start with the getting started guide.
Structure
A map file is one JSON object. Keys that start with $ are reserved; every other key declares an environment variable, and its value is the identifier of the secret that fills it.
{
"$schema": "https://envilder.com/schema/map-file.v1.json",
"$config": {
"provider": "aws",
"profile": "dev-account"
},
"DB_PASSWORD": "/my-app/dev/db-password",
"STRIPE_API_KEY": "/my-app/dev/stripe/api-key"
}| Key | Meaning |
|---|---|
$schema | Optional URL of the JSON Schema. Editors use it for autocompletion and validation; envilder ignores it. |
$config | Optional object that selects the provider and its settings. See the fields below. |
$… | Any other key starting with $ is skipped by envilder. The schema rejects it, so do not use it for metadata. |
DB_PASSWORD | Variable name (key) and secret identifier (string value). The value is opaque: its format depends on the provider. |
$config fields
Every field is optional. A file without $config uses AWS SSM with the default AWS credential chain.
| Field | Values | Default | Behaviour |
|---|---|---|---|
provider | aws | azure | aws | Secret backend. Matched case-insensitively. Any value other than aws or azure stops the run. |
profile | AWS CLI profile name | AWS default chain | Named profile from ~/.aws/config or ~/.aws/credentials. AWS only: with azure it is ignored and a warning is printed. |
vaultUrl | https://<vault>.vault.azure.net | - | Key Vault URL, for example https://my-vault.vault.azure.net. Required for azure. Ignored by aws. |
The runtime SDKs read the same fields but can reject combinations the CLI only warns about, such as profile with azure. Each SDK page lists its own errors.
Secret identifiers by provider
AWS SSM Parameter Store
The value is the parameter name exactly as stored in SSM, usually a hierarchical path. Envilder calls GetParameter with decryption, so String and SecureString parameters both work. The region comes from AWS_REGION, then AWS_DEFAULT_REGION, then the profile, with us-east-1 as the last fallback.
{
"$config": { "provider": "aws", "profile": "prod-account" },
"DB_PASSWORD": "/my-app/prod/db-password",
"LEGACY_TOKEN": "legacy-token"
}Azure Key Vault
The value is the secret name. Envilder turns slashes into hyphens before calling Key Vault, so the same path style can be shared with an AWS file:
{
"$config": {
"provider": "azure",
"vaultUrl": "https://my-vault.vault.azure.net"
},
"DB_PASSWORD": "my-app-prod-db-password",
"STRIPE_API_KEY": "/my-app/prod/stripe-api-key"
}- Leading slashes are removed and the other slashes become hyphens: "/my-app/prod/stripe-api-key" reads my-app-prod-stripe-api-key. The CLI, the GitHub Action and every SDK apply the same rule.
- Everything else is sent as written. A name Key Vault rejects (for example one with _ or .) fails with Key Vault's own error.
- In the CLI and the GitHub Action, two different values that resolve to the same name in one file are an error.
- Envilder always reads the latest version of the secret.
Precedence between $config and flags
Each setting is resolved on its own, from the first source that defines it:
A flag replaces only the field it names; the other $config fields still apply. The same rules hold for pull, push and exec. When --map is omitted, envilder uses envilder.json in the current directory; pull and push also default --envfile to .env.
envilder exec -- npm start
envilder exec --profile=staging-account -- npm start
envilder exec --provider=azure \
--vault-url=https://other-vault.vault.azure.net -- npm startThe GitHub Action accepts provider and vault-url inputs but has no profile input: in CI, credentials come from the workflow (for example OIDC), not from a named profile.
Validation rules
envilder checks the file before it contacts any provider, so an invalid file never resolves part of its secrets:
- The file must be valid JSON. Comments and trailing commas are not allowed.
- Variable names must match ^[A-Za-z0-9_./-]+$: letters, digits, underscore, dot, hyphen and slash. Spaces, =, #, accented letters and line breaks are rejected, because they would inject or lose a line in a .env file.
- A name with / (Database/Password) works everywhere: the SDKs and exec pass it as written, and the .NET SDK maps it to a configuration section. When writing a .env file the CLI keeps it and warns, because python-dotenv loads that line but dotenv for Node.js, Docker Compose and bash do not; use exec or a __ name (Database__Password) if your app reads the file with one of those.
- An empty name is rejected.
- __proto__ cannot be used as a variable name: the schema rejects it and envilder never resolves it, because .env parsers cannot read it back.
- The name rule applies to every key, even when the value is not a string. A key with a non-string value (number, object, null) is then skipped, not resolved.
- With exec on Windows, two names that differ only by case are rejected, because Windows treats them as one variable.
- The schema recommends POSIX names (^[a-zA-Z_][a-zA-Z0-9_]*$). Dotted and hyphenated names are accepted, but some shells and tools cannot read them as variables.
Secret contents (the resolved values)
Envilder never rewrites a secret value: what the provider returns is what your application gets. The limits come from where the value is stored:
| Stage | Limit |
|---|---|
| Provider | AWS SSM: 4 KB (standard) or 8 KB (advanced tier). Azure Key Vault: 25 KB. |
| .env file (CLI, GitHub Action) | Every value dotenv can represent. See the exception below. |
| Process environment | The operating system cannot store NUL (U+0000) in a variable, and Windows limits a variable to 32,767 characters. |
The SDKs' resolve-only APIs (resolve, ResolveFile, IConfiguration) keep values in memory and are subject to the provider limits only.
The CLI writes each value so that dotenv reads back exactly the original string. The quoting is chosen automatically and checked by parsing the result before the file is written. The check uses dotenv’s grammar extended to keys with /, so for those keys it proves the value round-trips, not that Node.js dotenv loads them (it skips such lines):
PLAIN=plain
QUOTES=she said "hi"
HASH='alpha#beta'
PADDED=' padded '
MULTILINE="first\nsecond"#, leading and trailing whitespace, quotes, backslashes, a literal \n, real LF/CRLF line breaks and Unicode all round-trip. When the file already exists, each assignment is replaced in place (a multiline one entirely), and comments, ordering and line endings are preserved.
Multi-environment example
Keep one file per environment with the same keys, so the application code never changes. Only the paths and the profile differ:
{
"$schema": "https://envilder.com/schema/map-file.v1.json",
"$config": { "provider": "aws", "profile": "dev-account" },
"DB_PASSWORD": "/my-app/dev/db-password",
"STRIPE_API_KEY": "/my-app/dev/stripe/api-key"
}{
"$schema": "https://envilder.com/schema/map-file.v1.json",
"$config": { "provider": "aws", "profile": "prod-account" },
"DB_PASSWORD": "/my-app/prod/db-password",
"STRIPE_API_KEY": "/my-app/prod/stripe/api-key"
}Choose the file with --map. Locally, run the app with the development file; for a production artifact, write a .env from the production file:
envilder exec --map=envilder.dev.json -- npm run dev
envilder --map=envilder.prod.json --envfile=.env.prodIn a workflow, point the action at the file for that environment:
- uses: macalbert/envilder/github-action@v0
with:
map-file: envilder.prod.json
env-file: .envNames that match envilder.json or envilder.*.json are recognized by SchemaStore, so most editors validate them even without the $schema line.
Common errors
| Message | Fix |
|---|---|
Invalid environment variable name "MY VAR": names may only contain letters, digits, underscore, dot, hyphen and slash, so that they can be read back from a .env file | Rename the key so it only uses letters, digits, underscore, dot, hyphen and slash. |
Invalid JSON in parameter map file: envilder.json | Fix the JSON syntax: a trailing comma, a comment or a missing quote is the usual cause. |
Unsupported provider: gcp. Supported providers: aws, azure | Use aws or azure in $config.provider or --provider. |
vaultUrl is required when using Azure provider. Set it in $config.vaultUrl in your map file or via --vault-url flag. | Set $config.vaultUrl, or pass --vault-url, when the provider is azure. |
--profile is only supported with the aws provider and will be ignored (current provider: azure). | A warning, not an error. Remove profile from $config, or drop --profile, when using azure. |
Map file declares variables that differ only by case (API_KEY, api_key); Windows treats them as the same variable. | Rename one of the keys; exec on Windows refuses names that differ only by case. |