{"id":31904116,"url":"https://github.com/cloudfoundry-community/safe","last_synced_at":"2025-10-13T13:47:28.211Z","repository":{"id":167348414,"uuid":"642966024","full_name":"cloudfoundry-community/safe","owner":"cloudfoundry-community","description":"A Vault CLI","archived":false,"fork":false,"pushed_at":"2025-08-18T19:18:22.000Z","size":2754,"stargazers_count":5,"open_issues_count":2,"forks_count":1,"subscribers_count":40,"default_branch":"develop","last_synced_at":"2025-08-18T21:23:56.094Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/cloudfoundry-community.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2023-05-19T18:59:43.000Z","updated_at":"2025-08-18T19:18:26.000Z","dependencies_parsed_at":"2024-03-11T19:47:52.649Z","dependency_job_id":"3e542f55-2845-494e-b5c5-c59cb2ac8123","html_url":"https://github.com/cloudfoundry-community/safe","commit_stats":null,"previous_names":["cloudfoundry-community/safe"],"tags_count":94,"template":false,"template_full_name":null,"purl":"pkg:github/cloudfoundry-community/safe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fsafe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fsafe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fsafe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fsafe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudfoundry-community","download_url":"https://codeload.github.com/cloudfoundry-community/safe/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fsafe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015339,"owners_count":26085685,"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-10-13T02:00:06.723Z","response_time":61,"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":[],"created_at":"2025-10-13T13:47:26.959Z","updated_at":"2025-10-13T13:47:28.204Z","avatar_url":"https://github.com/cloudfoundry-community.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"safe - A Vault CLI\n==================\n\nQuestions? Pop in our [slack channel](https://cloudfoundry.slack.com/messages/vault/)!\n\n![SAFE](docs/safe.png)\n\n[Vault][vault] is an awesome project and it comes with superb\ndocumentation, a rock-solid server component and a flexible and\ncapable command-line interface.\n\n![get-set-passwords](docs/safely-generate-passwords.gif)\n\nSo, why `safe`?  To solve the following problems:\n\n  1. Securely generate new SSH public / private keys\n  2. Securely generate random RSA key pairs\n  3. Auto-generate secure, random passwords\n  4. Securely provide credentials, without files\n  5. Dumping multiple paths\n\nPrimarily, these are things encountered in trying to build secure\nBOSH deployments using Vault and [Spruce][spruce].\n\nATTENTION HOMEBREW USERS\n------------------------\n\nIf you run Homebrew on MacOS, be aware that the the Formula for\nsafe in homebrew core is outdated, incorrect, and unmaintained.\nWe maintain our own tap, which you are encouraged to use instead:\n\n```\nbrew tap cloudfoundry-community/cf\nbrew install cloudfoundry-community/cf/safe\n```\n\n\nAuthentication\n--------------\n\nTo make it easier to target multiple Vaults from one client (i.e.\nyour work laptop), `safe` lets you track and authenticate against\n_targets_, each representing a different vault.\n\nTo get started, you'll need to add a new target:\n\n```\nsafe target https://vault.example.com myvault\n```\n\nThe first argument is the URL to the Vault; the second is a\nshorthand alias for the target.  Later, you can retarget this\nVault with just:\n\n```\nsafe target myvault\n```\n\nYou can see what Vaults you have targeted by running\n\n```\nsafe targets\n```\n\nAll commands will be run against the currently targeted Vault.\n\nTo authenticate:\n\n```\nsafe auth [token]\nsafe auth ldap\nsafe auth github\nsafe auth okta\n```\n\n(Other authentication backends are not yet supported)\n\nFor each type (token, ldap, okta or github), you will be prompted for\nthe necessary credentials to authenticated against the Vault.\n\nUsage\n-----\n\n`safe` operates by way of sub-commands.  To generate a new\n2048-bit SSH keypair, and store it in `secret/ssh`:\n\n```\nsafe ssh 2048 secret/ssh\n```\n\nTo set non-sensitive keys, you can just specify them inline:\n\n```\nsafe set secret/ssh username=system\n```\n\nIf you use a password manager (good for you!) and don't want to\nhave to paste passwords twice, use the `paste` subcommand:\n\n```\nsafe paste secret/1pass/managed\n```\n\nCommands can be chained by separating them with the argument\nterminator, `--`, so to both create a new SSH keypair and set the\nusername:\n\n```\nsafe ssh 2048 secret/ssh -- set secret/ssh username=system\n```\n\nAuto-generated passwords are easy too:\n\n```\nsafe gen secret/account passphrase\n```\n\nSometimes, you just want to import passwords from another source\n(like your own password manager), without the hassle of writing\nfiles to disk or the risk of leaking credentials via the process\ntable or your shell history file.  For that, `safe` provides a\ndouble-confirmation interactive mode:\n\n```\nsafe set secret/ssl/ca passphrase\npassphrase [hidden]:\npassphrase [confirm]:\n```\n\nWhat you type will not be echoed back to the screen, and the\nconfirmation prompt is there to make sure your fingers didn't\nbetray you.\n\nAll operations (except for `delete`) are additive, so the\nfollowing:\n\n```\nsafe set secret/x a=b c=d\n```\n\nis equivalent to this:\n\n```\nsafe set secret/x a=b -- set secret/x c=d\n```\n\nNeed to take an existing password, and generate a crypt-sha512 hash,\nor base64 encode it? `safe fmt` will do this, and store the results\nin a new key for you, making it easy to generate a password, and then\nformat that password as needed.\n\n```\nsafe gen secret/account password\nsafe fmt base64 secret/account password base64_pass\nsafe fmt crypt-sha512 secret/account password crypt_pass\nsafe get secret/account\n```\n\nCommand Reference\n------------------\n\n### set path key\\[=value\\] \\[key ...\\]\n\nUpdates a single path with new keys.  Any existing keys that are\nnot specified on the command line are left intact.\n\nYou will be prompted to enter values for any keys that do not have\nvalues.  This can be used for more sensitive credentials like\npasswords, PINs, etc.\n\nExample:\n\n```\nsafe set secret/root username=root password\n\u003cprompts for 'password' here...\u003e\n```\n\nSimilarly, `safe paste` works the same way, but does not have a confirmation\nprompt for your value. It assumes you have pasted in the value from a known-good\nsource.\n\nSetting the value of a key to be the contents of a file\n\nExample:\n\n```\nsafe set secret/root ssl_key@/path/to/ssl_key_file\n```\n\n### get path \\[path ...\\]\n\nRetrieve and print the values of one or more paths, to standard\noutput.  This is most useful for piping credentials through\n`keybase` or `pgp` for encrypting and sending to others.\n\n```\nsafe get secret/root secret/whatever secret/key\n--- # secret/root\nusername: root\npassword: it's a secret\n\n--- # secret/whatever\nwhatever: is clever\n\n--- # secret/key\nprivate: |\n   -----BEGIN RSA PRIVATE KEY-----\n   ...\n   -----END RSA PRIVATE KEY-----\npublic: |\n  -----BEGIN RSA PUBLIC KEY-----\n  ...\n  -----END RSA PRIVATE KEY-----\n```\n\n### tree path \\[path ...\\]\n\nProvide a tree hierarchy listing of all reachable keys in the\nVault.\n\n```\nsafe tree secret/dc1\nsecret/dc1\n  concourse/\n    pipeline-the-first/\n      aws\n      dockerhub\n      github\n    pipeline-the-second/\n      aws\n      dockerhub\n      github\n```\n\n### paths path \\[path ... \\]\n\nProvide a flat listing of all reachable keys in the Vault.\n\n```\nsafe paths secret/dc1\nsecret/dc1concourse/pipeline-the-first/aws\nsecret/dc1concourse/pipeline-the-first/dockerhub\nsecret/dc1concourse/pipeline-the-first/github\nsecret/dc1concourse/pipeline-the-second/aws\nsecret/dc1concourse/pipeline-the-second/dockerhub\nsecret/dc1concourse/pipeline-the-second/github\n```\n\n### delete path \\[path ...\\]\n\nRemoves multiple paths from the Vault.\n\n```\nsafe delete secret/unused\n```\n\n### move oldpath newpath\n\nMove a secret from `oldpath` to `newpath`, a rename of sorts.\n\n```\nsafe move secret/staging/user secret/prod/user\n```\n\n(or, more succinctly, using brace expansion):\n\n```\nsafe move secret/{staging,prod}/user\n```\n\nAny credentials at `newpath` will be completely overwritten.  The\nsecret at `oldpath` will no longer exist.\n\n### copy oldpath newpath\n\nCopy a secret from `oldpath` to `newpath`.\n\n```\nsafe copy secret/staging/user secret/prod/user\n```\n\n(or, as with `move`, using brace expansion):\n\n```\nsave copy secret/{staging,prod}/user\n```\n\nAny credentials at `newpath` will be completely overwritten.  The\nsecret at `oldpath` will still exist after the copy.\n\n### gen \\[length\\] path key\n\nGenerate a new, random password.  By default, the generated\npassword will be 64 characters long.\n\n```\nsafe gen secret/account secretkey\n```\n\nTo get a shorter password, only 16 characters long:\n\n```\nsafe gen 16 secret/account password\n```\n\n### fmt format_type path oldKey newKey\n\nTake the key at `path:oldKey`, reformat it according to **format_type**,\nand save it in `path:newKey`. Useful for hashing, or encoding passwords\nin an alternate format (for htpass files, or /etc/shadow).\n\nCurrently supported formats:\n\n- base64\n- bcrypt\n- crypt-md5\n- crypt-sha256\n- crypt-sha512\n\n```\nsafe fmt base64 secret/account password base64_password\nsafe fmt crypt-sha512 secret/account password crypt_password\n```\n\n### ssh \\[nbits\\] path \\[path ...\\]\n\nGenerate a new SSH RSA keypair, adding the keys \"private\" and\n\"public\" to each path.  The public key will be encoded as an\nauthorized keys.  The private key is a PEM-encoded DER private\nkey.\n\nBy default, a 2048-bit key will be generated.  The `nbits`\nparameter allows you to change that.\n\nEach path gets a unique SSH keypair.\n\n### rsa \\[nbits\\] path \\[path ...\\]\n\nGenerate a new RSA keypair, adding the keys \"private\" and \"public\"\nto each path.  Both keys will be PEM-encoded DER.\n\nBy default, a 2048-bit key will be generated.  The `nbits`\nparameter allows you to change that.\n\nEach path gets a unique RSA keypair.\n\n### prompt ...\n\nEcho the arguments, space-separated, as a single line to the\nterminal.  This is a convenience helper for long pipelines of\nchained commands.\n\n### x509 issue \\[OPTIONS\\] --name cn.example.com path\n\nIssues a new X.509 TLS/SSL certificate, and stores the new RSA\nprivate key and the certificate in the Vault at _path_, in PEM\nformat.\n\n### x509 revoke \\[OPTIONS\\] --signed-by path/to/ca path/to/cert\n\nRevoke a certificate that was signed by a Certificate Authority.\nThe private key for the CA must be present in the Vault for this\nto work.  Revoked certificates will be appended to the CA's\ncertificate revocation list (CRL), stored at `path/to/ca:crl`\n\n### x509 validate \\[OPTIONS\\] path\n\nRun a variety of validation checks against a certificate in the\nVault.  In its simplest form, without arguments, this verifies\nthat the private key stored at `path:key` matches the certificate\nstored at `path:certificate`.  Options control more powerful\nvalidations, like checking for revocation, SAN validity, and\nexpiry.\n\n### x509 crl --renew path\n\nRenews (re-signs) the certificate authority at `path`, without\naffecting the list of revoked certificates.\n\n### export path \\[path ...\\]\n\nExport the given subtree(s) in a format suitable for migration\n(via a future `import` call), or long-term storage offline.\nSecrets will not be encrypted in this representation, so care\nshould be taken in handling it.  Output will be printed to\nstandard output.\n\n### import \u003cexport.file\n\nRead an export (as produced by the `export` subcommand) from\nstandard input, and write all of the secrets contained\ntherein to the same paths inside the targeted Vault.  Trees\nwill be imported in an additive nature, so existing credentials\nin the same subtree as imported credentials will be left intact.\n\nIf you've got an export saved in a file _on-disk_, you can feed\nit to `safe import` using your shell's redirection facilities:\n\n```\nsafe import \u003c ./path/to/export.file\n```\n\nYou can also use `cat`, in the standard UNIX idiom:\n\n```\ncat ./path/to/export.file | safe import\n```\n\n(_Note:_ storing exports on-disk is considered bad practice, as\n it leaks your secrets via a shared resource: the filesystem.)\n\nImport and export can be combined in a pipeline to facilitate\nmovement of credentials from one Vault to another, like so:\n\n```\nsafe -T old-vault export secret/sub/tree | \\\n  safe -T new-vault import\n```\n\n### env\n\nPrint the environment variables describing the current target:\n\n```\nsafe env\n  VAULT_ADDR  http://localhost:8200\n  VAULT_TOKEN  $SOME_UUID\n```\n\nYou can also use this command to export a target's configuration into the outer\nshell in order to use the Vault CLI directly:\n\n```\nsafe env --bash\n\\export VAULT_ADDR=http://localhost:8200;\n\\export VAULT_TOKEN=$SOME_UUID;\n\\unset VAULT_SKIP_VERIFY;\n\neval $(safe env --bash)\n```\n\n[vault]:  https://vaultproject.io\n[spruce]: https://github.com/geofffranks/spruce\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudfoundry-community%2Fsafe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudfoundry-community%2Fsafe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudfoundry-community%2Fsafe/lists"}