# secretgarden
`secretgarden` is a self-contained CLI that generates and securely stores secrets like the following:
- Passwords
- SSH keys
- TLS/X.509 certificates
- Opaque values
It's made for sysadmins that manage a small set of systems by themselves. Secrets are kept safe
with a key derived from your SSH key (in concert with
[NaCl's secretbox](https://nacl.cr.yp.to/secretbox.html) and the [argon2 hash](https://github.com/P-H-C/phc-winner-argon2)).
The interaction model is strongly inspired by a credential server called [CredHub](https://docs.cloudfoundry.org/credhub/), where an automated deployment tool can ask for a secret that is:
- Securely stored
- Automatically generated if it does not exist
- Re-generated if the secret's options have changed
- Easy to generate based on other certificates (CAs with child certificates, for instance)
## Installation
Currently, secretgarden can only be installed from source. Install Rust via [rustup](rustup.rs) or
OS packages, then run `$ cargo install --path .` from inside this directory. (Make sure that `~/.cargo/bin` is in your `$PATH`.)
## Usage
### Prerequisites
Before getting started, make sure that you have ssh-agent running, and that you've added keys to it:
```
$ ssh-add -l
256 SHA256:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA me@home (ED25519)
...
```
If `$ ssh-add -l` returns nothing, then add your SSH key with `$ ssh-add`.
**Note**: only RSA and ED25519 keys are accepted. DSA and ECDSA keys generate random signatures,
making them unusable for key derivation.
If it returns an error, you likely aren't running `ssh-agent`. You can start it for your current
shell with `$ eval $(ssh-agent)`, but should probably add that command to your login script.
### Getting autogenerated secrets
Secrets are retrieved via subcommands of `secretgarden`. For instance, to retrieve a 32-character
random password named `mysql-root-password`, run:
```shell
$ secretgarden password mysql-root-password
nEIn5JwTCpaIrGGpCehuP6rVbCgKLWow
```
If this password doesn't exist, it will be generated and stored.
#### SSH keys
SSH keys can be generated similarly:
```shell
$ secretgarden ssh-key jumpbox-ssh-key
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
```
The public key can be retrieved with `--public`:
```shell
$ secretgarden ssh-key jumpbox-ssh-key --public
ssh-ed25519 ...
```
### X.509 certificates
X.509 certificates can be fetched in multiple formats and signed by other secretgarden-managed
certificates.
If a certficate is generated without a CA, it will be self signed. If a CA is configured as
follows:
```toml
[x509.example-ca]
is-ca = true
[x509.example-child]
ca = "example-ca"
```
then `example-child` will be signed by `example-ca`. Note that `example-ca` must be generated first
and must be unexpired.
These certificates and their public/private keys may be retrieved one at a time, or all at once. For
instance:
```shell
$ secretgarden x509 example-child --certficate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
$ secretgarden x509 example-child --certifcate --private-key
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
```
### Changing config
Each of the secret types has configuration that can be changed, ranging from password length to complex
X.509 options. This configuration is read from `secretgarden.toml` in the current directory. For
example:
```toml
[password.mysql-root-password]
length = 64
[ssh-key.jumpbox-ssh-key]
type = "rsa"
bits = 4096
[x509.ca]
is-ca = true
```
To see the options supported by a secret type, see `secretgarden SECRET-TYPE --help`:
```shell
$ secretgarden ssh-key --help
Get or generate an SSH key.
Will output the private key by default.
Available config options:
* `type`: the type of SSH key (`rsa`, `dsa`, `ecdsa`, or `ed-25519`; defaults to `ed-25519`).
* `bits`: the number of bits in the key (only supported for `rsa` and `ecdsa` keys).
...
```
### Storing opaque values
Some secrets might be dictated to you (API tokens, etc.), but it can still be useful to store them
alongside generated secrets.
Opaque (non-generated) values can be set with `secretgarden set-opaque` and retrieved with `secretgarden
opaque`:
```shell
$ secretgarden set-opaque api-token
<enter secret value>
$ secretgarden opaque api-token
<your secret value>
```