Chamber is a tool for managing secrets. Currently it does so by storing secrets in SSM Parameter Store, an AWS service for storing secrets.
For detailed info about using chamber, read The Right Way To Manage Secrets
Starting with version 2.0, chamber uses parameter store's path based API by default. Chamber pre-2.0 supported this API using the CHAMBER_USE_PATHS
environment variable. The paths based API has performance benefits and is the recommended best practice by AWS.
As a side effect of this change, if you didn't use path based secrets before 2.0, you will need to set CHAMBER_NO_PATHS
to enable the old behavior. This option is deprecated, and We recommend only using this setting for supporting existing applications.
To migrate to the new format, you can take advantage of the export
and import
commands. For example, if you wanted to convert secrets for service foo
to the new format using chamber 2.0, you can do:
CHAMBER_NO_PATHS=1 chamber export foo | chamber import foo -
If you have a functional go environment, you can install with:
go install github.com/segmentio/chamber/v2@latest
for Go >= 1.17;
or
go get github.com/segmentio/chamber
for older Go version.
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.
This is going to vary based on your organization but chamber needs AWS credentials to run.
One of the easiest ways to do so is by using aws-vault. To adjust these instructions for your needs, examine the env output of Aws-Vault: How It Works and use your organization's secrets tool accordingly with chamber.
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
):
alias chamberprod='aws-vault exec production -- chamber'
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
to create your key, and follow this guide to set up your
alias.
If you are a Terraform user, you can create your key with the following:
resource "aws_kms_key" "parameter_store" {
description = "Parameter store kms master key"
deletion_window_in_days = 10
enable_key_rotation = true
}
resource "aws_kms_alias" "parameter_store_alias" {
name = "alias/parameter_store_key"
target_key_id = "${aws_kms_key.parameter_store.id}"
}
If you'd like to use an alternate KMS key to encrypt your secrets, you can set
the environment variable CHAMBER_KMS_KEY_ALIAS
. As an example, the following will use your account's default SSM alias:
CHAMBER_KMS_KEY_ALIAS=aws/ssm
$ 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.
If -
is provided as the value argument, the value will be read from standard
input.
Secret keys are normalized automatically. The -
will be _
and the letters will be converted to upper case (for example a secret with key secret_key
and secret-key
will become SECRET_KEY
).
$ chamber list service
Key Version LastModified User
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.
$ chamber list -e service
Key Version LastModified User Value
apikey 2 06-09 17:30:56 daniel-fuentes apikeyvalue
other 1 06-09 17:30:34 daniel-fuentes othervalue
Listing secrets with expand parameter should show the key names and values 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.
$ chamber history service key
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.
$ 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
).
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.
$ chamber read service key
Key Value Version LastModified User
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.
$ chamber export [--format <format>] [--output-file <file>] <service...>
{"key":"secret"}
export
provides ability to export secrets in various file formats. The following
file formats are supported:
- json (default)
- yaml
- java-properties
- csv
- tsv
- dotenv
- tfvars
File is written to standard output by default but you may specify an output file.
To set env vars in your terminal you can use the chamber env
command. For example,
source <(chamber env service)`
printf "%s" "$SERVICE_VAR"
$ chamber import [--normalize-keys] <service> <filepath>
import
provides the ability to import secrets from a json or yaml file (like the kind
you get from chamber export
).
Note By default,
import
will not normalize key inputs, meaning that keys will be written to the secrets backend in the format they exist in the source file. In order to normalize keys on import, provide the--normalize-keys
flag
When normalizing keys, before write, the key will be be first converted to lowercase
to match how chamber write
handles keys.
Example: DB_HOST
will be converted to db_host
.
You can set filepath
to -
to instead read input from stdin.
$ chamber delete [--exact-key] service key
delete
provides the ability to remove a secret from chamber permanently,
including the secret's additional metadata. There is no way to recover a
secret once it has been deleted so care should be taken with this command.
Note By default,
delete
will normalize any provided keys. To change that behavior, provide the--exact-key
flag to attempt to delete the raw provided key.
Example: Given the following setup,
$ chamber list service
Key Version LastModified User
apikey 2 06-09 17:30:56 daniel-fuentes
APIKEY 1 06-09 17:30:34 daniel-fuentes
Calling
$ chamber delete --exact-key service APIKEY
will delete only APIKEY
from the service and leave only
$ chamber list service
Key Version LastModified User
apikey 2 06-09 17:30:56 daniel-fuentes
$ chamber find key
find
provides the ability to locate which services use the same key names.
$ chamber find value --by-value
Passing --by-value
or -v
will search the values of all secrets and return
the services and keys which match.
Chamber uses AWS SDK for Go. To use a
region other than what is specified in $HOME/.aws/config
, set the environment
variable "AWS_REGION".
$ AWS_REGION=us-west-2 chamber list service
Key Version LastModified User
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 for more details.
If you'd like to use a different region for chamber without changing AWS_REGION
, you can use CHAMBER_AWS_REGION
to override just for chamber.
If you'd like to use a custom SSM endpoint for chamber, you can use CHAMBER_AWS_SSM_ENDPOINT
to override AWS default URL.
By default, chamber store secrets in AWS Parameter Store. We now also provide an experimental S3 backend for storing secrets in S3 instead.
To configure chamber to use the S3 backend, use chamber -b s3 --backend-s3-bucket=mybucket
. Preferably, this bucket should reject uploads that do not set the server side encryption header (see this doc for details how)
This feature is experimental, and not currently meant for production work.
This backend is similar to the S3 Backend but uses KMS Key Encryption to encrypt your documents at rest, similar to the SSM Backend which encrypts your secrets at rest. You can read how S3 Encrypts documents with KMS here.
The highlights of SSE-KMS are:
- You can choose to create and manage encryption keys yourself, or you can choose to use your default service key uniquely generated on a customer by service by region level.
- The ETag in the response is not the MD5 of the object data.
- The data keys used to encrypt your data are also encrypted and stored alongside the data they protect.
- Auditable master keys can be created, rotated, and disabled from the AWS KMS console.
- The security controls in AWS KMS can help you meet encryption-related compliance requirements.
Source https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html
To configure chamber to use the S3 KMS backend, use chamber -b s3-kms --backend-s3-bucket=mybucket --kms-key-alias=alias/keyname
. You must also supply an environment variable of the KMS Key Alias to use CHAMBER_KMS_KEY_ALIAS, by default "alias/parameter_store_key" will be used.
Preferably, this bucket should reject uploads that do not set the server side encryption header (see this doc for details how)
When changing secrets between KMS Keys, you must first delete the Chamber secret with the existing KMS Key, then write it again with new KMS Key.
If services contain multiple KMS Keys, chamber list
and chamber exec
will only show Chamber secrets encrypted with KMS Keys you have access to.
This feature is experimental, and not currently meant for production work.
If it's preferred to not use any backend at all, use chamber -b null
. Doing so will forward existing ENV variables as if Chamber is not in between.
This feature is experimental, and not currently meant for production work.
chamber
includes some usage analytics code which Segment uses internally for tracking usage of internal tools. This analytics code is turned off by default, and can only be enabled via a linker flag at build time, which we do not set for public github releases.
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 Github Actions to automatically publish
a github release.