{"id":51009526,"url":"https://github.com/vdemeester/pass-run","last_synced_at":"2026-06-21T00:37:15.273Z","repository":{"id":343570784,"uuid":"1178260367","full_name":"vdemeester/pass-run","owner":"vdemeester","description":"Inject secrets from pass/passage into environment variables at runtime, then exec a command. Like op run for the unix password store ecosystem.","archived":false,"fork":false,"pushed_at":"2026-03-10T22:03:23.000Z","size":11,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-21T00:37:14.781Z","etag":null,"topics":["age","cli","dotenv","environment-variables","gpg","nix-flake","pass","passage","password-store","secrets"],"latest_commit_sha":null,"homepage":null,"language":"Shell","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/vdemeester.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-10T21:16:57.000Z","updated_at":"2026-03-11T03:50:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vdemeester/pass-run","commit_stats":null,"previous_names":["vdemeester/pass-run"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/vdemeester/pass-run","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdemeester%2Fpass-run","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdemeester%2Fpass-run/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdemeester%2Fpass-run/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdemeester%2Fpass-run/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vdemeester","download_url":"https://codeload.github.com/vdemeester/pass-run/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vdemeester%2Fpass-run/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34590214,"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-06-20T02:00:06.407Z","response_time":98,"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":["age","cli","dotenv","environment-variables","gpg","nix-flake","pass","passage","password-store","secrets"],"created_at":"2026-06-21T00:37:15.204Z","updated_at":"2026-06-21T00:37:15.264Z","avatar_url":"https://github.com/vdemeester.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pass-run\n\nInject secrets from [passage](https://github.com/FiloSottile/passage) or [pass](https://www.passwordstore.org/) into environment variables at runtime, then exec a command. No plaintext secrets on disk.\n\nInspired by [`op run`](https://developer.1password.com/docs/cli/reference/commands/run/) from 1Password and [`sops exec-env`](https://github.com/getsops/sops), but for the unix password store ecosystem.\n\n## Why\n\n`.env` files store secrets in plaintext on disk. `pass-run` replaces them with a reference file that maps variable names to password store paths — safe to commit, no secrets exposed.\n\n```\n# .env              (secrets on disk — bad)\nAPI_KEY=sk-1234567890abcdef\n\n# .env.pass      (references only — safe to commit)\nAPI_KEY=ai/openai/api_key\n```\n\n## Install\n\nCopy `pass-run` somewhere in your `$PATH`:\n\n```bash\ncp pass-run ~/.local/bin/\n```\n\nOr with Nix (flake):\n\n```bash\nnix run github:vdemeester/pass-run -- --help\n```\n\nRequires: `bash` and either `passage` or `pass`\n\n## Backends\n\n`pass-run` supports two backends:\n\n| Backend | Encryption | Tool |\n|---------|-----------|------|\n| [passage](https://github.com/FiloSottile/passage) | age | `passage show` |\n| [pass](https://www.passwordstore.org/) | GPG | `pass show` |\n\nBoth use the same `show` subcommand interface, so env files work with either.\n\n**Auto-detection** (default): prefers `passage` if available, falls back to `pass`.\n\n**Explicit**: use `-b passage` or `-b pass` to force a backend.\n\n## Usage\n\n### With an env file\n\nCreate a `.env.pass` file mapping variable names to store paths:\n\n```bash\n# .env.pass\nOPENAI_API_KEY=ai/openai/api_key\nSYNTHETIC_API_KEY=ai/synthetic.new/api_key\nDATABASE_URL=services/postgres/url\n```\n\nRun a command with those secrets injected:\n\n```bash\npass-run .env.pass -- my-app serve\npass-run .env.pass -- npm start\npass-run .env.pass -- pi --provider synthetic\n```\n\n### With inline mappings\n\n```bash\npass-run -e API_KEY=ai/openai/api_key -- curl -H \"Authorization: Bearer $API_KEY\" ...\n```\n\n### Combined\n\n```bash\npass-run .env.pass -e EXTRA_SECRET=path/to/secret -- my-app\n```\n\nInline `-e` flags override values from the file.\n\n### Force a backend\n\n```bash\n# Use pass (GPG) instead of passage (age)\npass-run -b pass .env.pass -- my-app\n\n# Explicitly use passage\npass-run -b passage .env.pass -- my-app\n```\n\n### Options\n\n```\n-b \u003cbackend\u003e   Backend: \"passage\", \"pass\", or \"auto\" (default: auto)\n-e VAR=path    Add a single mapping (can be repeated)\n-f \u003cfile\u003e      Env file to load (alternative to positional argument)\n-q             Quiet: don't print status messages to stderr\n-n             Dry run: show what would be exported without running the command\n-p             Parallel: fetch secrets concurrently (faster, noisier errors)\n-h, --help     Show help\n```\n\n### Dry run\n\nSee what would be injected without running anything:\n\n```bash\n$ pass-run .env.pass -n\n# pass-run: would export the following variables (via passage):\nexport OPENAI_API_KEY=\u003c51 chars\u003e\nexport SYNTHETIC_API_KEY=\u003c32 chars\u003e\n# then exec: my-app\n```\n\n## Env file format\n\n```bash\n# Comments (lines starting with #)\nVARIABLE_NAME=store/path/to/secret\n\n# Inline comments are stripped\nAPI_KEY=ai/openai/key  # this is ignored\n\n# Variable names must be valid shell identifiers\nMY_VAR_123=some/path\n```\n\n- One mapping per line: `VARIABLE_NAME=store/path`\n- Lines starting with `#` are comments\n- Blank lines are ignored\n- Only the first line of each store entry is used (the password line)\n\n## Examples\n\n### Pi coding agent with Synthetic\n\n```bash\n# .env.pass.pi\nSYNTHETIC_API_KEY=ai/synthetic.new/api_key\nGEMINI_API_KEY=redhat/google/osp/vdeemest-api-key\n\n# Run pi with secrets injected\npass-run .env.pass.pi -- pi --provider synthetic\n```\n\n### Docker Compose\n\n```bash\npass-run .env.pass -- docker compose up\n```\n\n### Shell scripts\n\n```bash\n# In a wrapper script\n#!/usr/bin/env bash\nexec pass-run \"$HOME/.env.pass.myapp\" -- myapp \"$@\"\n```\n\n### Migrating from pass to passage\n\nSame env file works with both — just switch the backend:\n\n```bash\n# With GPG-based pass\npass-run -b pass .env.pass -- my-app\n\n# With age-based passage\npass-run -b passage .env.pass -- my-app\n```\n\n## How it works\n\n1. Detects backend (`passage` preferred, `pass` fallback, or `-b` override)\n2. Reads variable-to-path mappings from file and/or `-e` flags\n3. Calls `\u003cbackend\u003e show \u003cpath\u003e` for each mapping\n4. Exports the resolved values as environment variables\n5. Uses `exec` to replace itself with your command\n\nSecrets exist only in the process environment — never written to disk.\n\n## See also\n\n- [passage](https://github.com/FiloSottile/passage) — age-backed password manager\n- [pass](https://www.passwordstore.org/) — the standard unix password manager (GPG)\n- [Stop Putting Secrets in .env Files](https://jonmagic.com/posts/stop-putting-secrets-in-dotenv-files/) — the blog post that inspired this pattern\n- [`op run`](https://developer.1password.com/docs/cli/reference/commands/run/) — 1Password's equivalent\n- [`sops exec-env`](https://github.com/getsops/sops) — SOPS's equivalent\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdemeester%2Fpass-run","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvdemeester%2Fpass-run","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvdemeester%2Fpass-run/lists"}