{"id":36545311,"url":"https://github.com/macalbert/envilder","last_synced_at":"2026-05-31T11:01:11.132Z","repository":{"id":257805617,"uuid":"859829892","full_name":"macalbert/envilder","owner":"macalbert","description":"🚀 Envilder is an open-source developer toolkit for loading cloud secrets into your app runtime. Built as a monorepo with CLI, GitHub Action, and native SDKs. Supports AWS SSM and Azure Key Vault today, with Google Cloud and HashiCorp Vault next. No SaaS middleman, no vendor lock-in.","archived":false,"fork":false,"pushed_at":"2026-05-29T22:53:51.000Z","size":17988,"stargazers_count":136,"open_issues_count":17,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-05-30T00:19:35.476Z","etag":null,"topics":["automation","aws-ssm-parameters","azure","azure-key-vault","ci-cd","dev-experience","dev-tools","devops","devsecops","dotenv","dotenv-flow","env","envfile","environment-variables","parameter-store","secrets","secrets-in-keyvault","secrets-management","secrets-manager","secure"],"latest_commit_sha":null,"homepage":"https://envilder.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/macalbert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"docs/SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":".github/AGENTS.md","dco":null,"cla":null},"funding":{"github":"macalbert"}},"created_at":"2024-09-19T10:58:20.000Z","updated_at":"2026-05-29T22:53:19.000Z","dependencies_parsed_at":"2026-01-12T06:02:32.365Z","dependency_job_id":null,"html_url":"https://github.com/macalbert/envilder","commit_stats":null,"previous_names":["macalbert/envilder"],"tags_count":52,"template":false,"template_full_name":null,"purl":"pkg:github/macalbert/envilder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macalbert%2Fenvilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macalbert%2Fenvilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macalbert%2Fenvilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macalbert%2Fenvilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/macalbert","download_url":"https://codeload.github.com/macalbert/envilder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macalbert%2Fenvilder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33728391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","aws-ssm-parameters","azure","azure-key-vault","ci-cd","dev-experience","dev-tools","devops","devsecops","dotenv","dotenv-flow","env","envfile","environment-variables","parameter-store","secrets","secrets-in-keyvault","secrets-management","secrets-manager","secure"],"created_at":"2026-01-12T06:00:08.023Z","updated_at":"2026-05-31T11:01:11.122Z","avatar_url":"https://github.com/macalbert.png","language":"TypeScript","funding_links":["https://github.com/sponsors/macalbert"],"categories":[],"sub_categories":[],"readme":"# 🗝️ Envilder ☁️\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/8a7188ef-9d8d-45fb-8c37-3af718fb5103\" alt=\"Envilder\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eOne model. Your secrets. Every runtime.\u003c/b\u003e\u003cbr\u003e\n  \u003cspan\u003eDefine secret mappings once. Resolve them consistently from AWS SSM or Azure Key Vault.\u003c/span\u003e\n\u003c/p\u003e\n\n[![npm version](https://img.shields.io/npm/v/envilder.svg)](https://www.npmjs.com/package/envilder)\n[![npm downloads](https://img.shields.io/npm/dm/envilder.svg)](https://npmcharts.com/compare/envilder)\n[![CI Tests](https://github.com/macalbert/envilder/actions/workflows/tests.yml/badge.svg)](https://github.com/macalbert/envilder/actions/workflows/tests.yml)\n[![Overall Coverage](https://macalbert.github.io/envilder/badge_combined.svg)](https://macalbert.github.io/envilder/)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n\n## Why Envilder?\n\nYour new developer joins the team. They need environment variables to run the app locally.\nWhat happens next? Someone sends API keys over Slack. Someone else digs up a wiki page\nwith outdated credentials. Forty-five minutes later, their `.env` file is \"probably correct\".\n\n**Envilder fixes this in one command.**\n\nYou create a JSON mapping between variable names and cloud secret paths. Envilder resolves\nthem from AWS SSM or Azure Key Vault. The same mapping file works in local dev (CLI),\nCI/CD (GitHub Action), and application startup (runtime SDKs).\n\n```bash\nenvilder --map=envilder.json --envfile=.env\n```\n\nNo SaaS middleman. No vendor lock-in. Secrets stay in your cloud.\n\n---\n\n## The problem\n\n- **Onboarding takes hours, not seconds.** Every new developer needs someone to explain which\n  secrets go where. Keys get shared over Slack, pasted from wikis, or copied from a colleague's\n  machine. It's slow, error-prone, and insecure.\n- **Every environment has its own workflow.** Local dev reads `.env` files. CI/CD uses vault\n  integrations. Production has its own method. Same app, three different secret workflows.\n- **No single source of truth.** Without a versioned contract, dev/staging/production configs\n  drift apart. Deployments break. Nobody knows which config is correct.\n\n## How Envilder solves it\n\n- 📋 **One mapping file for everything.** A single `envilder.json` defines what secrets your app\n  needs. Git-versioned, PR-reviewable, the same across every environment.\n- ⚡ **Works everywhere your code runs.** CLI for local dev, GitHub Action for CI/CD, runtime SDKs\n  for application startup. Same file, same result.\n- 🛡️ **Your cloud, zero infrastructure.** Secrets stay in AWS SSM or Azure Key Vault. No SaaS\n  proxy, no extra servers, no data to migrate.\n\n---\n\n## ⚙️ Features\n\n| Feature | Description |\n|---------|-------------|\n| 📋 **Declarative Mapping** | One JSON file defines all secrets. Git-versioned, PR-reviewable, diff-able |\n| ☁️ **Multi-Provider** | AWS SSM + Azure Key Vault. No vendor lock-in |\n| 🔌 **Runtime SDKs** | Load secrets into memory at app startup: [.NET](./src/sdks/dotnet/README.md), [Python](./src/sdks/python/README.md), [Node.js](./src/sdks/nodejs/README.md). No `.env` on disk |\n| ⚙️ **GitHub Action** | Pull secrets in CI/CD. Same mapping, zero manual config |\n| 🔄 **Bidirectional Sync** | Pull secrets to `.env` or push values back to the cloud |\n| 🧱 **Zero Infrastructure** | No servers, no proxies, no SaaS. Uses cloud services you already have |\n\n---\n\n## 🚀 Quick Start\n\n### 🎥 See it in action\n\nWatch how easy it is to automate your .env management in less than 1 minute:  \n\n![Watch the video](https://github.com/user-attachments/assets/9f194143-117d-49f3-a6fb-f400040ea514)\n\n### 🏁 Get Started (2 steps)\n\n**1. Create a mapping file** (`envilder.json`):\n\n```json\n{\n  \"$schema\": \"https://envilder.com/schema/map-file.v1.json\",\n  \"DB_PASSWORD\": \"/my-app/db/password\",\n  \"API_KEY\": \"/my-app/api-key\"\n}\n```\n\n**2. Generate your `.env` file:**\n\n```bash\nnpx envilder --map=envilder.json --envfile=.env\n```\n\nThat's it. Your secrets are pulled from AWS SSM and written to `.env`.\nAdd `.env` to `.gitignore`. The mapping file is versioned and reviewable in PRs.\n\n\u003e 💡 Using Azure Key Vault? Add a `$config` section to your mapping file.\n\u003e See [Mapping File Format](#️-mapping-file-format) below.\n\n### 💾 Installation\n\n```bash\nnpm install -g envilder\n```\n\n\u003e 💡 **No install needed?** `npx envilder` works out of the box.\n\u003e\n\u003e **Requirements:** Node.js v22.12+. AWS CLI or Azure CLI configured.\n\u003e See [full requirements](docs/requirements-installation.md).\n\n### 🤖 GitHub Action\n\n**AWS SSM (default):**\n\n```yaml\n- name: Configure AWS Credentials\n  uses: aws-actions/configure-aws-credentials@v5\n  with:\n    role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}\n    aws-region: us-east-1\n\n- name: Pull secrets from AWS SSM\n  uses: macalbert/envilder/github-action@v0.8.0\n  with:\n    map-file: envilder.json\n    env-file: .env\n```\n\n**Azure Key Vault:**\n\n```yaml\n- name: Azure Login\n  uses: azure/login@v2\n  with:\n    client-id: ${{ secrets.AZURE_CLIENT_ID }}\n    tenant-id: ${{ secrets.AZURE_TENANT_ID }}\n    subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}\n\n- name: Pull secrets from Azure Key Vault\n  uses: macalbert/envilder/github-action@v0.8.0\n  with:\n    map-file: envilder.json\n    env-file: .env\n    provider: azure\n    vault-url: ${{ secrets.AZURE_KEY_VAULT_URL }}\n```\n\n📖 **[Full GitHub Action docs](./github-action/README.md)**\n\n### 📚 More resources\n\n- [📖 Full Documentation](https://envilder.com): the complete guide at envilder.com\n- [Push Command Guide](docs/push-command.md)\n- [Pull Command Guide](docs/pull-command.md)\n\n---\n\n## 🗺️ Mapping File Format\n\nThe mapping file (`envilder.json`) is the core of Envilder. It's the single model that defines\nwhat secrets your app needs and where they live in your cloud provider. The same file is used by\nthe CLI, the GitHub Action, and the runtime SDKs. You can optionally include a `$config` section\nto declare which provider and settings to use.\n\nAdd `\"$schema\"` to enable IDE autocomplete, inline documentation, and validation for your map\nfiles. The schema is published at\n[envilder.com/schema/map-file.v1.json](https://envilder.com/schema/map-file.v1.json).\n\n### Basic Format (AWS SSM, default)\n\nWhen no `$config` is present, Envilder defaults to AWS SSM Parameter Store:\n\n```json\n{\n  \"$schema\": \"https://envilder.com/schema/map-file.v1.json\",\n  \"API_KEY\": \"/myapp/prod/api-key\",\n  \"DB_PASSWORD\": \"/myapp/prod/db-password\",\n  \"SECRET_TOKEN\": \"/myapp/prod/secret-token\"\n}\n```\n\nValues are SSM parameter paths (e.g., `/myapp/prod/api-key`).\n\n### With `$config` (explicit provider)\n\nAdd a `$config` key to declare the provider and its settings. Envilder reads `$config` for configuration\nand uses all other keys as secret mappings:\n\n**AWS SSM with profile:**\n\n```json\n{\n  \"$schema\": \"https://envilder.com/schema/map-file.v1.json\",\n  \"$config\": {\n    \"provider\": \"aws\",\n    \"profile\": \"prod-account\"\n  },\n  \"API_KEY\": \"/myapp/prod/api-key\",\n  \"DB_PASSWORD\": \"/myapp/prod/db-password\"\n}\n```\n\n**Azure Key Vault:**\n\n```json\n{\n  \"$schema\": \"https://envilder.com/schema/map-file.v1.json\",\n  \"$config\": {\n    \"provider\": \"azure\",\n    \"vaultUrl\": \"https://my-vault.vault.azure.net\"\n  },\n  \"API_KEY\": \"myapp-prod-api-key\",\n  \"DB_PASSWORD\": \"myapp-prod-db-password\"\n}\n```\n\n\u003e **Azure naming:** Key Vault secret names only allow alphanumeric characters and hyphens.\n\u003e Envilder automatically normalizes names: slashes and underscores become hyphens\n\u003e (e.g., `/myapp/db/password` → `myapp-db-password`).\n\n### `$config` Options\n\n| Key | Type | Default | Description |\n| --- | --- | --- | --- |\n| `provider` | `\"aws\"` \\| `\"azure\"` | `\"aws\"` | Cloud provider to use |\n| `vaultUrl` | `string` | - | Azure Key Vault URL (required when `provider` is `\"azure\"`) |\n| `profile` | `string` | - | AWS CLI profile for multi-account setups (AWS only) |\n\n### Configuration Priority\n\nCLI flags and GitHub Action inputs always override `$config` values:\n\n```txt\nCLI flags / GHA inputs  \u003e  $config in map file  \u003e  defaults (AWS)\n```\n\nThis means you can set a default provider in `$config` and override it per invocation:\n\n```bash\n# Uses $config from the map file\nenvilder --map=envilder.json --envfile=.env\n\n# Overrides provider and vault URL from the map file\nenvilder --provider=azure --vault-url=https://other-vault.vault.azure.net --map=envilder.json --envfile=.env\n```\n\n---\n\n## 🧩 Runtime SDKs\n\nBeyond the CLI and GitHub Action, Envilder provides **runtime SDKs** that resolve secrets\ndirectly into your application's memory at startup. No `.env` file written to disk, no secrets\nleft behind. SDKs use the same map-file format as the CLI.\n\n### .NET SDK\n\nInstall via NuGet:\n\n```bash\ndotnet add package Envilder\n```\n\nLoad secrets into `IConfiguration` or inject them into the process environment:\n\n```csharp\n// Option A: integrate with IConfiguration\nvar config = new ConfigurationBuilder()\n    .AddEnvilder(\"envilder.json\")\n    .Build();\n\nvar dbPassword = config[\"DB_PASSWORD\"];\n\n// Option B: resolve + inject into environment\nEnv.Load(\"envilder.json\");\nvar dbPassword = Environment.GetEnvironmentVariable(\"DB_PASSWORD\");\n```\n\n📖 **[Full .NET SDK docs](./src/sdks/dotnet/README.md)** · 💡 **[Examples](./examples/sdk/dotnet/)**\n\n### Python SDK\n\nInstall via uv (recommended) or pip:\n\n```bash\nuv add envilder\n# or\npip install envilder\n```\n\nLoad secrets into your application with a single line:\n\n```python\nfrom envilder import Envilder\n\n# Resolve + inject into os.environ\nEnvilder.load('envilder.json')\n```\n\nOr route by environment, where each environment points to its own map file:\n\n```python\nfrom envilder import Envilder\n\nEnvilder.load('production', {\n    'production': 'prod-secrets.json',\n    'development': 'dev-secrets.json',\n    'test': None,  # no secrets loaded\n})\n```\n\n📖 **[Full Python SDK docs](./src/sdks/python/README.md)** · 💡 **[Examples](./examples/sdk/python/)**\n\n### Node.js SDK\n\nInstall via npm:\n\n```bash\nnpm install @envilder/sdk\n```\n\nLoad secrets into your application with a single line:\n\n```typescript\nimport { Envilder } from '@envilder/sdk';\n\n// Resolve + inject into process.env\nconst secrets = await Envilder.load('envilder.json');\n```\n\nOr use the fluent builder for full control:\n\n```typescript\nimport { Envilder, SecretProviderType } from '@envilder/sdk';\n\nconst secrets = await Envilder.fromMapFile('envilder.json')\n  .withProvider(SecretProviderType.Aws)\n  .withProfile('prod-account')\n  .resolve();\n```\n\n📖 **[Full Node.js SDK docs](./src/sdks/nodejs/README.md)** · 💡 **[Examples](./examples/sdk/nodejs/)**\n\n---\n\n## 🛠️ How it works\n\n```mermaid\ngraph LR\n    A[\"Mapping Model (envilder.json)\"] --\u003e B[Envilder]:::core\n    B --\u003e C[\"CLI → .env file\"]\n    B --\u003e D[\"GitHub Action → CI/CD\"]\n    B --\u003e E[\"SDK → app memory\"]\n    F[\"AWS SSM / Azure Key Vault\"]:::cloud --\u003e B\n\n    classDef cloud fill:#ffcc66,color:#000000,stroke:#333,stroke-width:1.5px;\n    classDef core fill:#1f3b57,color:#fff,stroke:#ccc,stroke-width:2px;\n```\n\n1. **Define**: create an `envilder.json` mapping env var names to cloud secret paths\n2. **Resolve**: Envilder fetches each secret from your cloud vault\n3. **Deliver**: secrets arrive as a `.env` file (CLI/GHA) or in-memory (SDKs)\n4. **Push**: rotate or add secrets from your local environment back to the cloud\n\n---\n\n## 🔍 Envilder vs. Alternatives\n\nEnvilder is not a secrets manager. It is a **configuration resolution layer** that reads from your\nexisting cloud vault and delivers secrets where they're needed (`.env` file, CI/CD, app memory).\nNo SaaS backend. No extra servers.\n\n| | Envilder | dotenvx | Infisical |\n|-|----------|---------|-----------|\n| **Source of truth** | Your cloud (SSM / Key Vault) | Encrypted `.env` in git | Infisical backend |\n| **Declarative mapping** | ✅ JSON file | ❌ | ❌ |\n| **Multi-cloud** | ✅ AWS + Azure | ❌ | ✅ |\n| **Runtime SDKs** | ✅ .NET, Python, Node.js | ✅ Node.js | ✅ 6+ languages |\n| **Requires SaaS** | ❌ | ❌ | Optional |\n| **Infrastructure** | None | None | Server required |\n\n\u003e **When Envilder shines:** you already have secrets in AWS SSM or Azure Key Vault and want\n\u003e a versioned mapping file that resolves them everywhere: local dev, CI/CD, and app runtime.\n\u003e No data to migrate. No servers to deploy. No vendor to depend on.\n\nFor detailed tool-by-tool comparison including\n[chamber](https://github.com/segmentio/chamber) and\n[aws-vault](https://github.com/99designs/aws-vault),\nsee [envilder.com](https://envilder.com).\n\n---\n\n## 🏁 What's Next\n\nEnvilder already covers the full dev-to-production lifecycle with CLI, GitHub Action,\nand runtime SDKs for .NET, Python, and Node.js. Here's what's coming:\n\n| Status | Feature |\n|--------|---------|\n| ✅ | Pull \u0026 Push: bidirectional sync between `.env` and cloud vault |\n| ✅ | Multi-provider: AWS SSM + Azure Key Vault |\n| ✅ | GitHub Action for CI/CD |\n| ✅ | .NET, Python, and Node.js SDKs |\n| 🚧 | Go and Java SDKs |\n| 🚧 | GCP Secret Manager |\n| 🚧 | Exec mode (inject secrets without writing to disk) |\n\n👉 **[Full roadmap with priorities](./ROADMAP.md)**\n\n---\n\n## 🤝 Contributing\n\nAll help is welcome! PRs, issues, ideas.\n\n- 🔧 Use our [Pull Request Template](.github/pull_request_template.md)\n- 🧪 Add tests where possible\n- 💬 Feedback and discussion welcome\n- 🏗️ Check our [Architecture Documentation](./docs/architecture/README.md)\n- 🔒 Review our [Security Policy](./docs/SECURITY.md)\n\n---\n\n## 💜 Sponsors\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://localstack.cloud\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./src/website/public/localstack-logo-horizontal-Light.svg\"\u003e\n      \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./src/website/public/localstack-logo-horizontal-Dark.svg\"\u003e\n      \u003cimg src=\"./src/website/public/localstack-logo-horizontal-Dark.svg\" alt=\"LocalStack\" height=\"40\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Supported by \u003ca href=\"https://localstack.cloud\"\u003eLocalStack\u003c/a\u003e.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Envilder is also supported through the\n  \u003ca href=\"https://aws.amazon.com/blogs/opensource/aws-cloud-credits-for-open-source-projects-affirming-our-commitment/\"\u003e\n    AWS Open Source Credits Program\n  \u003c/a\u003e.\n\u003c/p\u003e\n\n---\n\n## 📜 License\n\nMIT © [Marçal Albert](https://github.com/macalbert)  \nSee [LICENSE](./LICENSE) | [CHANGELOG](./docs/CHANGELOG.md) | [Security Policy](./docs/SECURITY.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacalbert%2Fenvilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmacalbert%2Fenvilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacalbert%2Fenvilder/lists"}