{"id":18763788,"url":"https://github.com/roverdotcom/snagsby","last_synced_at":"2026-03-05T10:03:57.421Z","repository":{"id":48827853,"uuid":"63295386","full_name":"roverdotcom/snagsby","owner":"roverdotcom","description":"Snagsby reads a JSON object from an S3 bucket and outputs the keys and values in a format that can be evaluated by a shell to set environment variables.","archived":false,"fork":false,"pushed_at":"2026-02-26T15:31:15.000Z","size":1941,"stargazers_count":8,"open_issues_count":3,"forks_count":2,"subscribers_count":45,"default_branch":"master","last_synced_at":"2026-02-26T17:45:26.008Z","etag":null,"topics":["docker","ecs","ops"],"latest_commit_sha":null,"homepage":"","language":"Go","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/roverdotcom.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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2016-07-14T02:30:55.000Z","updated_at":"2026-02-23T13:48:54.000Z","dependencies_parsed_at":"2025-04-13T04:33:05.507Z","dependency_job_id":"4eb8c9dd-c288-4648-b208-2e9998a9556b","html_url":"https://github.com/roverdotcom/snagsby","commit_stats":{"total_commits":83,"total_committers":2,"mean_commits":41.5,"dds":"0.048192771084337394","last_synced_commit":"dd09d22008dec48ba51fc569c0f359e76c2b8c9e"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/roverdotcom/snagsby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roverdotcom%2Fsnagsby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roverdotcom%2Fsnagsby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roverdotcom%2Fsnagsby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roverdotcom%2Fsnagsby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roverdotcom","download_url":"https://codeload.github.com/roverdotcom/snagsby/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roverdotcom%2Fsnagsby/sbom","scorecard":{"id":785622,"data":{"date":"2025-08-11","repo":{"name":"github.com/roverdotcom/snagsby","commit":"dc20a03645d840e66d04df007757f5b31d24c979"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Code-Review","score":6,"reason":"Found 11/18 approved changesets -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.6.1 not signed: https://api.github.com/repos/roverdotcom/snagsby/releases/92080001","Warn: release artifact v0.6.0 not signed: https://api.github.com/repos/roverdotcom/snagsby/releases/91796932","Warn: release artifact v0.6.0-alpha not signed: https://api.github.com/repos/roverdotcom/snagsby/releases/90359720","Warn: release artifact v0.5.2 not signed: https://api.github.com/repos/roverdotcom/snagsby/releases/40436946","Warn: release artifact v0.5.1 not signed: https://api.github.com/repos/roverdotcom/snagsby/releases/36993651","Warn: release artifact v0.6.1 does not have provenance: https://api.github.com/repos/roverdotcom/snagsby/releases/92080001","Warn: release artifact v0.6.0 does not have provenance: https://api.github.com/repos/roverdotcom/snagsby/releases/91796932","Warn: release artifact v0.6.0-alpha does not have provenance: https://api.github.com/repos/roverdotcom/snagsby/releases/90359720","Warn: release artifact v0.5.2 does not have provenance: https://api.github.com/repos/roverdotcom/snagsby/releases/40436946","Warn: release artifact v0.5.1 does not have provenance: https://api.github.com/repos/roverdotcom/snagsby/releases/36993651"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/roverdotcom/snagsby/main.yaml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:2","Warn: containerImage not pinned by hash: Dockerfile:11","Warn: containerImage not pinned by hash: Dockerfile:20","Warn: containerImage not pinned by hash: scripts/DockerfileFpm:1","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 1 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T06:01:28.444Z","repository_id":48827853,"created_at":"2025-08-23T06:01:28.445Z","updated_at":"2025-08-23T06:01:28.445Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30118932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T09:35:22.236Z","status":"ssl_error","status_checked_at":"2026-03-05T09:35:20.028Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["docker","ecs","ops"],"created_at":"2024-11-07T18:27:27.615Z","updated_at":"2026-03-05T10:03:57.411Z","avatar_url":"https://github.com/roverdotcom.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Snagsby [![Build Status](https://travis-ci.org/roverdotcom/snagsby.svg?branch=master)](https://travis-ci.org/roverdotcom/snagsby)\n\nSnagsby reads configuration and secrets from multiple sources and outputs them\nas environment variables in a format that can be evaluated by a shell.\n\n**Supported sources:**\n- Local env files (`file://`) with dotenv format\n- AWS S3 JSON objects (`s3://`)\n- AWS Secrets Manager (`sm://`)\n\nIt's useful for reading configuration and secrets into environment variables in\nDocker containers and other deployment scenarios.\n\nIt can help with workflows like this one: https://blogs.aws.amazon.com/security/post/Tx2B3QUWAA7KOU/How-to-Manage-Secrets-for-Amazon-EC2-Container-Service-Based-Applications-by-Usi\n\n## Installation\n\nLinux and OSX 64 bit binaries are available on Github\n\n```bash\ncurl -L https://github.com/roverdotcom/snagsby/releases/download/v0.1.6/snagsby-0.1.6.linux-amd64.tar.gz \\\n    | tar zxf - -C /usr/local/bin\n```\n\n## JSON Format\n\nThe s3 object should contain a single JSON object:\n\n```javascript\n// s3://my-bucket/config.json\n{\n  \"processes\": 2,\n  \"multiline_config\": \"123\\n456\\n789\",\n  \"api_key\": \"abc123\",\n  \"yes\": true,\n  \"no\": false,\n  \"float_like\": 7.777\n}\n```\n\nUpload to `s3://my-bucket/config.json` with server side encryption and tight bucket access restrictions/policies.\n\nSnagsby can be configured with the `SNAGSBY_SOURCE` env var or you can pass the source url on the command line.\n\n```bash\nsnagsby s3://my-bucket/config.json?region=us-west-2\n```\n\nWould render:\n\n```bash\nexport API_KEY=\"abc123\"\nexport FLOAT_LIKE=\"7.777\"\nexport MULTILINE_CONFIG=\"123\\n456\\n789\"\nexport NO=\"0\"\nexport PROCESSES=\"2\"\nexport YES=\"1\"\n```\n\nYou can supply sources in a comma delimited `SNAGSBY_SOURCE` environment variable:\n\n```bash\nSNAGSBY_SOURCE=\"file://base.snagsby,  s3://my-bucket/secrets.json\" ./bin/snagsby\n\n# -e will fail on errors and exit 1\n./bin/snagsby -e \\\n  file://production.snagsby \\\n  s3://my-bucket/config.json \\\n  s3://my-bucket/config2.json\n```\n\nAn example docker entrypoint may look like:\n\n```bash\n#!/bin/sh\n\nset -e\n\n# Combine local config with remote secrets\neval $(./bin/snagsby \\\n  file://config/base.snagsby \\\n  file://config/production.snagsby \\\n  s3://my-bucket/config.json?region=us-west-2)\n\nexec \"$@\"\n```\n\n## Env File Format\n\nSnagsby supports reading environment variables from local files using the `file://` scheme with standard dotenv format.\n\n### Basic Usage\n\n```bash\nsnagsby file://local.snagsby\n```\n\n### File Format\n\nEnv files use the standard dotenv format (`KEY=VALUE`):\n\n```bash\n# Comments are supported\nDATABASE_URL=postgres://localhost:5432/mydb\nAPI_KEY=abc123\nDEBUG=true\n\n# Values can be quoted to preserve special characters\nMESSAGE=\"Hello # this is not a comment\"\nPATH_WITH_SPACES=\"  /path/with/spaces  \"\n\n# Empty values are allowed\nOPTIONAL_KEY=\n```\n\n### Secret References\n\nValues can reference AWS Secrets Manager using the `sm://` prefix:\n\n```bash\n# Direct values\nDATABASE_HOST=localhost\nDATABASE_PORT=5432\n\n# References to secrets in AWS Secrets Manager\nDATABASE_PASSWORD=sm://production/db/password\nAPI_SECRET=sm://production/api/secret\n```\n\nSnagsby will automatically fetch the secrets from AWS Secrets Manager and populate the environment variables with the actual values.\n\n### File Naming Conventions\n\nWhile Snagsby accepts any file extension, we recommend using extensions that clearly indicate the file contains **secret references**, not actual secrets:\n\n- `.snagsby` - Clear about the tool used to resolve the secrets\n- `.env.vault` - Suggests secrets/vault references\n- `.env.ref` - Short for \"references\"\n- `.envmap` - Conveys \"mapping to secrets\"\n\nIt is recommended to **avoid using `.env`** for files with secret references, as it may give developers a false sense that the file is safe to commit with actual secrets or that the file will not be committed to the repository.\n\n### Multiple Sources\n\nYou can combine multiple source types:\n\n```bash\nsnagsby \\\n  file://base.snagsby \\\n  file://production.snagsby \\\n  s3://my-bucket/config.json?region=us-west-2\n```\n\n### Validation and Key Handling\n\n**Env files require strict POSIX-compliant variable names:**\n\nEnvironment variable names in env files must follow shell naming conventions:\n- Start with a letter or underscore (`[a-zA-Z_]`)\n- Contain only letters, digits, and underscores (`[a-zA-Z0-9_]`)\n\nInvalid keys (e.g., `my-key` with dashes, `my.key` with dots, or `123key` starting with a digit) will be rejected with a clear error message.\n\n**Why strict validation?**\n\nUnlike other Snagsby resolvers (S3, Secrets Manager) that normalize arbitrary keys (e.g., converting `my-key` to `MY_KEY`), env files are meant to define actual shell environment variables. Since shells only accept POSIX-compliant names, we validate at parse time to catch errors early.\n\n**Key preservation:**\n\nKeys in env files are preserved exactly as written, including their case. For example:\n- `DATABASE_URL=...` stays as `DATABASE_URL` (not normalized to uppercase)\n- `lowercase_var=...` stays as `lowercase_var`\n\nThis matches standard `.env` file behavior and ensures variables are set exactly as intended.\n\n## AWS Configuration\n\nYou can configure AWS any way the golang sdk supports:\nhttps://github.com/aws/aws-sdk-go#configuring-credentials\n\nSnagsby enables support for the shared configuration file (~/.aws/config) in\nthe golang aws sdk.\n\nThe preferred method when in ec2 is to rely on instance profiles. When running\nin aws ecs snagsby will use the task iam role.\n\nYou can configure the default region by setting the `AWS_REGION` environment\nvariable. It's recommended you set the region on each source:\n`s3://my-bucket/snagsby-config.json?region=us-west-2`\n\n## Releasing\n\nFrom the `main` branch create a new SemVer tag:\n\n```bash\ngit tag -a v0.7.0 -m \"Release v0.7.0\"\n```\n\nIf you are looking to create a pre-release, ensure that you use a SemVer with a pre-release suffix i.e. SemVer with a dash and your pre-release suffix. For example `v0.7.0-alpha`.\n\nWhen you have your tag created, push to the remote with `git push --tags` and the release job will be created.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froverdotcom%2Fsnagsby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froverdotcom%2Fsnagsby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froverdotcom%2Fsnagsby/lists"}