{"id":15037475,"url":"https://github.com/shopify/ejson","last_synced_at":"2025-05-11T05:48:19.024Z","repository":{"id":16494232,"uuid":"19246943","full_name":"Shopify/ejson","owner":"Shopify","description":"EJSON is a small library to manage encrypted secrets using asymmetric encryption.","archived":false,"fork":false,"pushed_at":"2025-05-07T17:53:02.000Z","size":2993,"stargazers_count":1417,"open_issues_count":3,"forks_count":65,"subscribers_count":487,"default_branch":"main","last_synced_at":"2025-05-11T05:48:13.892Z","etag":null,"topics":[],"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/Shopify.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-04-28T17:12:08.000Z","updated_at":"2025-05-09T12:57:59.000Z","dependencies_parsed_at":"2023-11-20T04:23:01.110Z","dependency_job_id":"69c68283-2818-4c63-8c29-e37734324798","html_url":"https://github.com/Shopify/ejson","commit_stats":{"total_commits":162,"total_committers":43,"mean_commits":"3.7674418604651163","dds":0.7098765432098766,"last_synced_commit":"35899549d1d13827ae49ef18dc2bbcb55df52df1"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fejson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fejson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fejson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fejson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Shopify","download_url":"https://codeload.github.com/Shopify/ejson/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253523733,"owners_count":21921818,"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","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":[],"created_at":"2024-09-24T20:34:43.485Z","updated_at":"2025-05-11T05:48:19.007Z","avatar_url":"https://github.com/Shopify.png","language":"Go","readme":"# ejson\n\n`ejson` is a utility for managing a collection of secrets in source control. The\nsecrets are encrypted using [public\nkey](http://en.wikipedia.org/wiki/Public-key_cryptography), [elliptic\ncurve](http://en.wikipedia.org/wiki/Elliptic_curve_cryptography) cryptography\n([NaCl](http://nacl.cr.yp.to/) [Box](http://nacl.cr.yp.to/box.html):\n[Curve25519](http://en.wikipedia.org/wiki/Curve25519) +\n[Salsa20](http://en.wikipedia.org/wiki/Salsa20) +\n[Poly1305-AES](http://en.wikipedia.org/wiki/Poly1305-AES)). Secrets are\ncollected in a JSON file, in which all the string values are encrypted. Public\nkeys are embedded in the file, and the decrypter looks up the corresponding\nprivate key from its local filesystem.\n\n![demo](http://burkelibbey.s3.amazonaws.com/ejson-demo.gif)\n\nThe main benefits provided by `ejson` are:\n\n* Secrets can be safely stored in a git repo.\n* Changes to secrets are auditable on a line-by-line basis with `git blame`.\n* Anyone with git commit access has access to write new secrets.\n* Decryption access can easily be locked down to production servers only.\n* Secrets change synchronously with application source (as opposed to secrets\n  provisioned by Configuration Management).\n* Simple, well-tested, easily-auditable source.\n\nSee [the manpages](https://shopify.github.io/ejson) for more technical documentation.\n\nSee [ejson2env](https://github.com/Shopify/ejson2env) for a useful tool to help with exporting\na portion of secrets as environment variables for environments/tools that require this pattern.\n\n## Installation\n\nYou can download the `.deb` package from [Github Releases](https://github.com/Shopify/ejson/releases).\n\nOn development machines (64-bit linux or OS X), the recommended installation\nmethod is via Homebrew:\n\n```\nbrew tap shopify/shopify\nbrew install ejson\n```\n\n## Workflow\n\n### 1: Create the Keydir\n\nBy default, EJSON looks for keys in `/opt/ejson/keys`. You can change this by\nsetting `EJSON_KEYDIR` or passing the `-keydir` option.\n\n```\n$ mkdir -p /opt/ejson/keys\n```\n\n\u003e *For Mac OS users.* By default you won't have write permissions to `/opt/ejson` folder. Make sure to run the following command to grant these permissions:\n\n```bash\nsudo chown -R $(whoami) /opt/ejson\n```\n\n### 2: Generate a keypair\n\nWhen called with `-w`, `ejson keygen` will write the keypair into the `keydir`\nand print the public key. Without `-w`, it will print both keys to stdout. This\nis useful if you have to distribute the key to multiple servers via\nconfiguration management, etc.\n\n```\n$ ejson keygen\nPublic Key:\n63ccf05a9492e68e12eeb1c705888aebdcc0080af7e594fc402beb24cce9d14f\nPrivate Key:\n75b80b4a693156eb435f4ed2fe397e583f461f09fd99ec2bd1bdef0a56cf6e64\n```\n\n```\n$ ejson keygen -w\n53393332c6c7c474af603c078f5696c8fe16677a09a711bba299a6c1c1676a59\n$ cat /opt/ejson/keys/5339*\n888a4291bef9135729357b8c70e5a62b0bbe104a679d829cdbe56d46a4481aaf\n```\n\n### 3: Create an `ejson` file\n\nThe format is described in more detail [later on](#format). For now, create a\nfile that looks something like this. Fill in the `\u003ckey\u003e` with whatever you got\nback in step 2.\n\nCreate this file as `test.ejson`:\n\n```json\n{\n  \"_public_key\": \"\u003ckey\u003e\",\n  \"_database_username\": \"1234username\",\n  \"database_password\": \"1234password\"\n}\n```\n\n### 4: Encrypt the file\n\nRunning `ejson encrypt test.ejson` will encrypt any new plaintext keys in the\nfile and leave any existing encrypted keys or keys with property names prefixed with `_` untouched:\n\n```json\n{\n  \"_public_key\": \"63ccf05a9492e68e12eeb1c705888aebdcc0080af7e594fc402beb24cce9d14f\",\n  \"_database_username\": \"1234username\",\n  \"database_password\": \"EJ[1:WGj2t4znULHT1IRveMEdvvNXqZzNBNMsJ5iZVy6Dvxs=:kA6ekF8ViYR5ZLeSmMXWsdLfWr7wn9qS:fcHQtdt6nqcNOXa97/M278RX6w==]\"\n}\n```\n\nTry adding another plaintext secret to the file and run `ejson encrypt\ntest.ejson` again. The `database_password` field will not be changed, but the\nnew secret will be encrypted.\n\n### 5: Decrypt the file\n\nTo decrypt the file, you must have a file present in the `keydir` whose name is\nthe 64-byte hex-encoded public key exactly as embedded in the `ejson` document.\nThe contents of that file must be the similarly-encoded private key. If you used\n`ejson keygen -w`, you've already got this covered.\n\nUnlike `ejson encrypt`, which overwrites the specified files, `ejson decrypt`\nonly takes one file parameter, and prints the output to `stdout`:\n\n```\n$ ejson decrypt foo.ejson\n{\n  \"_public_key\": \"63ccf05a9492e68e12eeb1c705888aebdcc0080af7e594fc402beb24cce9d14f\",\n  \"_database_username\": \"1234username\",\n  \"database_password\": \"1234password\"\n}\n```\n\n## Format\n\nThe `ejson` document format is simple, but there are a few points to be aware\nof:\n\n1. It's just JSON.\n2. There *must* be a key at the top level named `_public_key`, whose value is a\n   32-byte hex-encoded (i.e. 64 ASCII byte) public key as generated by `ejson\n   keygen`.\n3. Any string literal that isn't an object key will be encrypted by default (ie.\n   in `{\"a\": \"b\"}`, `\"b\"` will be encrypted, but `\"a\"` will not.\n4. Numbers, booleans, and nulls aren't encrypted.\n5. If a key begins with an underscore, its corresponding value will not be\n   encrypted. This is used to prevent the `_public_key` field from being\n   encrypted, and is useful for implementing metadata schemes.\n6. Underscores do not propagate downward. For example, in `{\"_a\": {\"b\": \"c\"}}`,\n   `\"c\"` will be encrypted.\n\n## See also\n\n* If you use Capistrano for deployment you can use [capistrano-ejson](https://github.com/Shopify/capistrano-ejson) to automatically decrypt the secrets on deploy.\n* If you use [pre-commit](https://pre-commit.com/), you can use it to automatically encrypt secrets on commit.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshopify%2Fejson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshopify%2Fejson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshopify%2Fejson/lists"}