Skip to content

Commit

Permalink
Accept data from standard input (#35)
Browse files Browse the repository at this point in the history
If `-` is provided as the final argument to `chamber write`, read the
secret's value from standard input.  This is particularly useful when
the value consists of multiple lines (e.g., TLS certificate material).
  • Loading branch information
otterley committed Oct 9, 2017
1 parent 55413f6 commit d4d20a4
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 17 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*~
*.sw[a-z]
vendor/*/
dist/
67 changes: 51 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
# Chamber

Chamber is a tool for managing secrets. Currently it does so by storing secrets in SSM Parameter Store, an AWS service for storing secrets.
Chamber is a tool for managing secrets. Currently it does so by storing
secrets in SSM Parameter Store, an AWS service for storing secrets.

## Authenticating

Using `chamber` requires you to be running in an environment with an authenticated AWS user which has the appropriate permission to read/write values to SSM Parameter Store. The easiest way to do so is by using `aws-vault`, like:
Using `chamber` requires you to be running in an environment with an
authenticated AWS user which has the appropriate permission to read/write
values to SSM Parameter Store. The easiest way to do so is by using
`aws-vault`, like:

```bash
$ aws-vault exec prod -- chamber
```

For this reason, it is recommended that you create an alias in your shell of choice to save yourself some typing, for example (from my `.zshrc`):
For this reason, it is recommended that you create an alias in your shell of
choice to save yourself some typing, for example (from my `.zshrc`):

```
alias chamberprod='aws-vault exec production -- chamber'
```

## Setting up KMS

Chamber expects to find a KMS key with alias `parameter_store_key` in the account that you are writing/reading secrets. You can follow the [AWS KMS documentation](http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html) to create your key, and [follow this guide to set up your alias](http://docs.aws.amazon.com/kms/latest/developerguide/programming-aliases.html).
Chamber expects to find a KMS key with alias `parameter_store_key` in the
account that you are writing/reading secrets. You can follow the [AWS KMS
documentation](http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)
to create your key, and [follow this guide to set up your
alias](http://docs.aws.amazon.com/kms/latest/developerguide/programming-aliases.html).

If you are a [Terraform](https://www.terraform.io/) user, you can create your key with the following:
If you are a [Terraform](https://www.terraform.io/) user, you can create your
key with the following:

```HCL
resource "aws_kms_key" "parameter_store" {
Expand All @@ -35,17 +45,22 @@ resource "aws_kms_alias" "parameter_store_alias" {
}
```

If you'd like to use an alternate KMS key to encrypt your secrets, you can set the environment variable `CHAMBER_KMS_KEY_ALIAS`.
If you'd like to use an alternate KMS key to encrypt your secrets, you can set
the environment variable `CHAMBER_KMS_KEY_ALIAS`.

## Usage

### Writing Secrets

```bash
$ chamber write <service> <key> <value>
$ chamber write <service> <key> <value|->
```

This operation will write a secret into the secret store. If a secret with that key already exists, it will increment the version and store a new value.
This operation will write a secret into the secret store. If a secret with that
key already exists, it will increment the version and store a new value.

If `-` is provided as the value argument, the value will be read from standard
input.


### Listing Secrets
Expand All @@ -57,7 +72,9 @@ apikey 2 06-09 17:30:56 daniel-fuentes
other 1 06-09 17:30:34 daniel-fuentes
```

Listing secrets should show the key names for a given service, along with other useful metadata including when the secret was last modified, who modified it, and what the current version is.
Listing secrets should show the key names for a given service, along with other
useful metadata including when the secret was last modified, who modified it,
and what the current version is.


### Historic view
Expand All @@ -68,16 +85,23 @@ Event Version Date User
Created 1 06-09 17:30:19 daniel-fuentes
Updated 2 06-09 17:30:56 daniel-fuentes
```
The history command gives a historical view of a given secret. This view is useful for auditing changes, and can point you toward the user who made the change so it's easier to find out why changes were made.
The `history` command gives a historical view of a given secret. This view is
useful for auditing changes, and can point you toward the user who made the
change so it's easier to find out why changes were made.

### Exec
```bash
$ chamber exec <service...> -- <your executable>
```

`exec` populates the environment with the secrets from the specified services and executes the given command. Secret keys are converted to upper case (for example a secret with key `secret_key` will become `SECRET_KEY`).
`exec` populates the environment with the secrets from the specified services
and executes the given command. Secret keys are converted to upper case (for
example a secret with key `secret_key` will become `SECRET_KEY`).

Secrets from services are loaded in the order specified in the command. For example, if you do `chamber exec app apptwo -- ...` and both apps have a secret named `api_key`, the `api_key` from `apptwo` will be the one set in your environment.
Secrets from services are loaded in the order specified in the command. For
example, if you do `chamber exec app apptwo -- ...` and both apps have a secret
named `api_key`, the `api_key` from `apptwo` will be the one set in your
environment.

### Reading
```bash
Expand All @@ -86,11 +110,18 @@ Key Value Version LastModified
key secret 1 06-09 17:30:56 daniel-fuentes
```

`read` provides the ability to print out the value of a single secret, as well as the secret's additional metadata. It does not provide the ability to print out multiple secrets in order to discourage accessing extra secret material that is unneeded. Parameter store automatically versions secrets and passing the `--version/-v` flag to read can print older versions of the secret. Default version (-1) is the latest secret.
`read` provides the ability to print out the value of a single secret, as well
as the secret's additional metadata. It does not provide the ability to print
out multiple secrets in order to discourage accessing extra secret material
that is unneeded. Parameter store automatically versions secrets and passing
the `--version/-v` flag to read can print older versions of the secret. Default
version (-1) is the latest secret.

### AWS Region

Chamber uses [AWS SDK for Go](https://github.com/aws/aws-sdk-go). To use a region other than what is specified in `$HOME/.aws/config`, set the environment variable "AWS_REGION".
Chamber uses [AWS SDK for Go](https://github.com/aws/aws-sdk-go). To use a
region other than what is specified in `$HOME/.aws/config`, set the environment
variable "AWS_REGION".

```bash
$ AWS_REGION=us-west-2 chamber list service
Expand All @@ -99,8 +130,12 @@ apikey 3 07-10 09:30:41 daniel-fuentes
other 1 07-10 09:30:35 daniel-fuentes
```

Chamber does not currently read the value of "AWS_DEFAULT_REGION". See [https://github.com/aws/aws-sdk-go#configuring-aws-region](https://github.com/aws/aws-sdk-go#configuring-aws-region) for more details.
Chamber does not currently read the value of "AWS_DEFAULT_REGION". See
[https://github.com/aws/aws-sdk-go#configuring-aws-region](https://github.com/aws/aws-sdk-go#configuring-aws-region)
for more details.

## Releasing

To cut a new release, just push a tag named `v<semver>` where `<semver>` is a valid semver version. This tag will be used by Circle to automatically publish a github release.
To cut a new release, just push a tag named `v<semver>` where `<semver>` is a
valid semver version. This tag will be used by Circle to automatically publish
a github release.
12 changes: 11 additions & 1 deletion cmd/write.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"io/ioutil"
"os"
"strings"

"github.com/pkg/errors"
Expand All @@ -15,7 +17,7 @@ var (

// writeCmd represents the write command
var writeCmd = &cobra.Command{
Use: "write <service> <key> <value>",
Use: "write <service> <key> <value|->",
Short: "write a secret",
RunE: write,
}
Expand Down Expand Up @@ -43,6 +45,14 @@ func write(cmd *cobra.Command, args []string) error {
}

value := args[2]
if value == "-" {
// Read value from standard input
v, err := ioutil.ReadAll(os.Stdin)
if err != nil {
return err
}
value = string(v)
}

secretStore := store.NewSSMStore()
secretId := store.SecretId{
Expand Down

0 comments on commit d4d20a4

Please sign in to comment.