{"id":29005309,"url":"https://github.com/vst/opsops","last_synced_at":"2025-08-30T14:16:59.394Z","repository":{"id":216233335,"uuid":"740762649","full_name":"vst/opsops","owner":"vst","description":"SOPS(-Nix) Goodies","archived":false,"fork":false,"pushed_at":"2025-05-20T03:28:18.000Z","size":79,"stargazers_count":14,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-25T11:06:46.269Z","etag":null,"topics":["1password","sops","sops-nix"],"latest_commit_sha":null,"homepage":"","language":"Haskell","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/vst.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2024-01-09T02:29:07.000Z","updated_at":"2025-06-25T01:40:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"4ac9d50b-b31e-40a9-9d0d-d3c43fd5f7ce","html_url":"https://github.com/vst/opsops","commit_stats":null,"previous_names":["vst/opsops"],"tags_count":6,"template":false,"template_full_name":"vst/haskell-template-hebele","purl":"pkg:github/vst/opsops","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vst%2Fopsops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vst%2Fopsops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vst%2Fopsops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vst%2Fopsops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vst","download_url":"https://codeload.github.com/vst/opsops/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vst%2Fopsops/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272858568,"owners_count":25005100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"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":["1password","sops","sops-nix"],"created_at":"2025-06-25T11:05:48.343Z","updated_at":"2025-08-30T14:16:59.389Z","avatar_url":"https://github.com/vst.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# opsops: SOPS(-Nix) Goodies\n\n![GitHub Release](https://img.shields.io/github/v/release/vst/opsops)\n![GitHub issues](https://img.shields.io/github/issues/vst/opsops)\n![GitHub last commit (branch)](https://img.shields.io/github/last-commit/vst/opsops/main)\n![GitHub License](https://img.shields.io/github/license/vst/opsops)\n\n`opsops` is a command-line application to generate clear [SOPS]\nsecrets from a given specification and generate [sops-nix] snippets\nfor it.\n\nThe specification is a YAML/JSON file representing a tree-like\nstructure where terminal nodes represent how the clear secrets will be\ngenerated, and internal nodes represent the \"path\" to the clear\nsecret.\n\nCurrently, system processes, scripts and 1password field reference\nURIs are supported:\n\n```yaml\nsecrets:\n  zamazingo:\n    secret:\n      type: \"process\"\n      value:\n        command: \"zamazingo\"\n        arguments: [\"--hip\", \"hop\"]\n  github:\n    token:\n      type: \"script\"\n      value:\n        content: \"printf \\\"%s\\\" \\\"$(gh auth token)\\\"\"\n  example.com:\n    password:\n      type: \"script\"\n      value:\n        interpreter: \"python3\"\n        content: |\n          import netrc\n          import sys\n\n          _login, _account, password = netrc.netrc().authenticators(\"example.com\")\n\n          sys.stdout.write(\"password\")\n  dockerhub:\n    password:\n      type: \"op\"\n      value:\n        account: \"PAIT5BAHSH7DAPEING3EEDIE2E\"\n        vault: \"Cloud Accounts\"\n        item: \"yies1Ahl4ahqu1afao4nahshoo\"\n        field: \"password\"\n  influxdb:\n    token:\n      type: \"op-read\"\n      value:\n        account: \"IPAEPH0JI3REE8FICHOOVU4CHA\"\n        uri: \"op://Devops/OokahCuZ4fo8ahphie1aiFa0ei/API Tokens/write-only\"\n```\n\n\u003c!--toc:start--\u003e\n- [opsops: SOPS(-Nix) Goodies](#opsops-sops-nix-goodies)\n  - [Installation](#installation)\n    - [Using `nix-env`](#using-nix-env)\n    - [Using `nix-profile`](#using-nix-profile)\n    - [Using `niv`](#using-niv)\n  - [Usage](#usage)\n    - [Specification](#specification)\n    - [See Canonical Specification](#see-canonical-specification)\n    - [Render Clear Secrets](#render-clear-secrets)\n    - [Create Snippet for `sops-nix`](#create-snippet-for-sops-nix)\n  - [Development](#development)\n  - [License](#license)\n\u003c!--toc:end--\u003e\n\n## Installation\n\n\u003e [!WARNING]\n\u003e\n\u003e If 1Password is used, 1Password CLI application (`op`) must be on\n\u003e `PATH` when running `opsops`.\n\n```sh\nnix profile install --file https://github.com/vst/opsops/archive/main.tar.gz\n```\n\n## Usage\n\n### Specification\n\nA specification is a YAML (or JSON) file. Here is an example:\n\n\u003cdetails\u003e\n  \u003csummary\u003eSee Example\u003c/summary\u003e\n\n```yaml\n## File: opsops.yaml\nsecrets:\n  zamazingo:\n    secret:\n      type: \"process\"\n      value:\n        command: \"zamazingo\"\n        arguments: [\"--hip\", \"hop\"]\n        strip: \"both\"\n        trailingNewline: \"crlf\"\n  github:\n    token:\n      type: \"script\"\n      value:\n        content: \"printf \\\"%s\\\" \\\"$(gh auth token)\\\"\"\n  example.com:\n    password:\n      type: \"script\"\n      value:\n        interpreter: \"python3\"\n        content: |\n          import netrc\n          import sys\n\n          _login, _account, password = netrc.netrc().authenticators(\"example.com\")\n\n          sys.stdout.write(\"password\")\n  dockerhub:\n    password:\n      type: \"op\"\n      value:\n        account: \"PAIT5BAHSH7DAPEING3EEDIE2E\"\n        vault: \"Cloud Accounts\"\n        item: \"yies1Ahl4ahqu1afao4nahshoo\"\n        field: \"password\"\n  influxdb:\n    token:\n      type: \"op-read\"\n      value:\n        account: \"IPAEPH0JI3REE8FICHOOVU4CHA\"\n        uri: \"op://Devops/OokahCuZ4fo8ahphie1aiFa0ei/API Tokens/write-only\"\n```\n\u003c/details\u003e\n\n### See Canonical Specification\n\nTo see canonical/normalized specification:\n\n```sh\nopsops normalize --input opsops.yaml\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eSee Output\u003c/summary\u003e\n\n```yaml\nsecrets:\n  dockerhub:\n    password:\n      type: op\n      value:\n        account: PAIT5BAHSH7DAPEING3EEDIE2E\n        field: password\n        item: yies1Ahl4ahqu1afao4nahshoo\n        newline: false\n        section: null\n        strip: null\n        trailingNewline: null\n        vault: Cloud Accounts\n  example.com:\n    password:\n      type: script\n      value:\n        arguments: []\n        content: |\n          import netrc\n          import sys\n\n          _login, _account, password = netrc.netrc().authenticators(\"example.com\")\n\n          sys.stdout.write(\"password\")\n        interpreter: python3\n        strip: null\n        trailingNewline: null\n  github:\n    token:\n      type: script\n      value:\n        arguments: []\n        content: printf \"%s\" \"$(gh auth token)\"\n        interpreter: bash\n        strip: null\n        trailingNewline: null\n  influxdb:\n    token:\n      type: op-read\n      value:\n        account: IPAEPH0JI3REE8FICHOOVU4CHA\n        newline: false\n        strip: null\n        trailingNewline: null\n        uri: op://Devops/OokahCuZ4fo8ahphie1aiFa0ei/API Tokens/write-only\n  zamazingo:\n    secret:\n      type: process\n      value:\n        arguments:\n        - --hip\n        - hop\n        command: zamazingo\n        environment: {}\n        strip: both\n        trailingNewline: crlf\n```\n\u003c/details\u003e\n\n### Render Clear Secrets\n\n\u003e [!WARNING]\n\u003e\n\u003e If 1Password is used, 1Password CLI application (`op`) should be\n\u003e authenticated first:\n\u003e\n\u003e ```sh\n\u003e eval $(op signin -f [--account \u003cACCOUNT\u003e])\n\u003e ```\n\nTo render clear secrets:\n\n```sh\nopsops render --input opsops.yaml\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eSee Output\u003c/summary\u003e\n\n```yaml\nexample.com:\n  password: password\ngithub:\n  token: gho_meecubier5dinohSh3tohphaekuo5Phahpei\nzamazingo:\n  secret: hebelehubele\ndockerhub:\n  password: ohbauy5eing8pheSh6iigooweeZee6ch\ninfluxdb:\n  token: mu9aephabeadi7zi8goo9peYo8yae7ge\n```\n\u003c/details\u003e\n\n### Create Snippet for `sops-nix`\n\nTo create snippet for `sops-nix` that can be copied/pasted inside the\n`sops-nix` module configuration:\n\n```sh\nopsops snippet sops-nix --input opsops.yaml\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eSee Output\u003c/summary\u003e\n\n```nix\n\"dockerhub/password\" = {};\n\"example.com/password\" = {};\n\"github/token\" = {};\n\"influxdb/token\" = {};\n\"zamazingo/secret\" = {};\n```\n\u003c/details\n\n... or with some prefix:\n\n```sh\nopsops snippet sops-nix --input opsops.yaml --prefix my_namespace\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eSee Output\u003c/summary\u003e\n\n```nix\n\"my_namespace/dockerhub/password\" = { key = \"dockerhub/password\"; };\n\"my_namespace/example.com/password\" = { key = \"example.com/password\"; };\n\"my_namespace/github/token\" = { key = \"github/token\"; };\n\"my_namespace/influxdb/token\" = { key = \"influxdb/token\"; };\n\"my_namespace/zamazingo/secret\" = { key = \"zamazingo/secret\"; };\n```\n\u003c/details\u003e\n\n## Development\n\nProvision `direnv`:\n\n```sh\ndirenv allow\n```\n\nBig, long build command for the impatient:\n\n```sh\nhpack \u0026\u0026\n    direnv reload \u0026\u0026\n    fourmolu -i app/ src/ test/ \u0026\u0026\n    prettier --write . \u0026\u0026\n    find . -iname \"*.nix\" -not -path \"*/nix/sources.nix\" -print0 | xargs --null nixpkgs-fmt \u0026\u0026\n    hlint app/ src/ test/ \u0026\u0026\n    cabal build -O0 \u0026\u0026\n    cabal run -O0 opsops -- --version \u0026\u0026\n    cabal v1-test \u0026\u0026\n    cabal haddock -O0\n```\n\nTo check and build:\n\n```sh\ncabal dev-test-build [-c]\n```\n\n## License\n\nSee [LICENSE].\n\n\u003c!-- REFERENCES --\u003e\n\n[LICENSE]: ./LICENSE.md\n[SOPS]: https://github.com/getsops/sops\n[sops-nix]: https://github.com/Mic92/sops-nix\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvst%2Fopsops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvst%2Fopsops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvst%2Fopsops/lists"}