Chamber keeps secrets in SSM Parameter Store, and the documented install path builds a binary that calls itself chamber dev
CLI for managing secrets
At a glance
- What is it?
- segmentio/chamber is a Go CLI over AWS SSM Parameter Store, with a KMS alias convention, key normalisation that collapses two spellings into one, a Makefile whose default goal is the test suite, and an analytics key that only release builds receive.
- Who is it for?
- Chamber is a sound choice when your secrets already belong in SSM Parameter Store and your organisation runs on IAM identities, because it adds a scripting interface over a service you are probably using anyway. Three checks decide whether it fits.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 123 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- segmentio/chamber2,614 ★ · +0
| Repository | 2026-10-04 | 2026-11-14 |
|---|---|---|
| segmentio/chamber | 2.6k | 2.6k |
0 Stars in the last 41 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
go install produces a binary that reports itself as chamber dev
The documented install is one line, and the module path carries a major version suffix:
go install github.com/segmentio/chamber/v3@latestThat path has a documented consequence. Version information is injected at compile time by the Makefile, so a binary built by `go install` has none, and the version command reports a placeholder instead:
$ chamber version
chamber devThe Makefile fills that string from `git describe --tags --always --dirty="-dev"`, meaning a checkout with uncommitted changes appends its own marker, and it passes the result into the binary through linker flags. So the same source tree produces a versioned binary when built with make and an unversioned one when installed with go, and the unversioned one is what the instructions lead with. The documentation also points to a wiki page for Docker images, Linux packages and precompiled binaries, which is where the versioned artifacts live.
The Makefile's default goal is the test suite, not a build
The Makefile states its intent in a comment: it is meant for humans, and a fork should be able to run the same checks as CI. It then sets `.DEFAULT_GOAL := test` with a note explaining that target ordering should not define the default. So a bare `make` in a fresh checkout runs `go test -v ./...` and never produces a binary. That default target depends on a generated mock file, and its rule is conditional on whether a tool called moq is on the path. When moq is absent, the recipe prints `Unable to generate mocks`, prints an install hint, and stops, without failing. The test suite then runs against whatever mock file is already checked in. Compare the neighbouring lint target, which fails on purpose when golangci-lint is missing. Two optional tools, two different behaviours, and the one that matters most for test reliability is the one that carries on.
An analytics write key is compiled into release binaries
The linker flags at the top of the Makefile carry two values into the binary: the version string, and an analytics write key. That key is an empty variable by default, written so a caller can pass it in, and it is set by whoever runs a release build. The dependency list confirms the client library is present, with segmentio analytics-go as a direct requirement. The practical shape of this is asymmetric. An official release build can carry a key; a `go install` binary, a local make build without the variable, or a container built without it carries an empty string. So telemetry in this project is a property of how the binary was produced, not a setting a user can inspect afterwards. Anyone auditing a build for outbound reporting has to check the build command, and anyone forking the project gets the empty default for free.
The KMS alias name is a convention the tool expects
Chamber looks for a KMS key with the alias `parameter_store_key` in the account it is reading and writing. That is a fixed expectation, not a discovery step, so a fresh account has no key to find and the tool needs one created before it does anything useful. The documentation hands the creation job to AWS's own guides and, for Terraform users, to a snippet that creates the key with a ten day deletion window and key rotation enabled, then attaches the alias the tool is looking for. An escape hatch exists for accounts that encrypt secrets with something else: setting `CHAMBER_KMS_KEY_ALIAS` to a different alias, with the example `CHAMBER_KMS_KEY_ALIAS=aws/ssm` to use the account's default SSM alias instead. The coupling between a command line tool and a naming convention inside your account is the part worth checking early, since it is the one piece of this setup that a wrong guess breaks loudly.
Key normalisation collapses two spellings into one name
Secret names are rewritten on the way in. Any dash in a key is replaced, and letters are upper cased, so `secret_key` and `secret-key` are stored as the same key. Writing a value under a key that already exists does not fail; it increments the version and stores the new value. Put those two facts together and the failure mode is clear: two logically distinct secrets whose names differ only by a dash or by case are one record with two versions, and the second write silently wins. The write command takes the service, the key and a value, with a dash as the value meaning read from standard input:
$ chamber write <service> <key> <value|->Version 3.0 also reserves the service name `_chamber` for internal use and warns when a command touches it. Tagging exists alongside this, on write with a tags argument for new secrets only, and as separate tag commands, with a flag to replace rather than merge that the documentation itself marks as subject to change before the next major release.
Three Makefiles and a packaging template behind the binary
The repository root carries three makefiles rather than one: the human-facing Makefile, a release makefile, and a tools makefile, plus a packaging template named nfpm.yaml.tmpl. That template is why the wiki advertises Linux packages alongside Docker images and precompiled binaries, since nfpm is what turns a build into system packages. The container build is a two stage Dockerfile that starts from a pinned Go image on Alpine, takes the version and target architecture as build arguments, and refuses to continue without a version by testing that the argument is non-empty. The final image is built from scratch, containing a certificate bundle and the binary and nothing else, so there is no shell to debug with inside a running container. Credentials still get resolved on a compute instance because the EC2 instance metadata client is a direct dependency of the module, which is what lets the tool run with no environment variables at all on an EC2 host.
Every documented command targets Parameter Store, not S3
The module is versioned as a v3 module and declares Go 1.23.0 as its language requirement, while the container build uses a 1.25 image, and one of the three most recent releases is titled after updating the Go version. Holding the declared minimum low while moving the release toolchain forward is a deliberate arrangement, and the documentation backs it by saying only versions covered by the Go release policy are tested. The dependency list is wider than the documentation. The AWS SDK modules include the S3 service client and the Secrets Manager service client alongside the Parameter Store client, and a shell escaping library is required for the command that runs a program with secrets in its environment. Those backends are reachable as a library, and the constructor for the S3 store is referenced in the breaking changes, yet every command in the usage documentation writes to SSM Parameter Store. A reader choosing this tool should confirm which backend they actually need before reading further.
Removed escape hatches and the one migration path left
The front of the documentation is a list of things that no longer work. The path based storage API became mandatory in 3.0, so `CHAMBER_NO_PATHS` has no effect at all, and the escape hatch that opted out of it has been withdrawn. `--min-throttle-delay` is gone with no direct replacement, because the underlying AWS SDK dropped support for it, and the suggested alternative is `--retry-mode` set to adaptive, which the documentation calls experimental. Store methods now require a context argument, a consequence of the move to the newer AWS SDK, which affects anyone importing chamber as a library and nobody using the command line. The deprecated `NewS3Store` constructor was removed in favour of one that takes a bucket. What survives as a migration path is a pair of commands, run with a 2.x binary against the old format:
CHAMBER_NO_PATHS=1 chamber export foo | chamber import foo -Editorial conclusion
Chamber is a sound choice when your secrets already belong in SSM Parameter Store and your organisation runs on IAM identities, because it adds a scripting interface over a service you are probably using anyway. Three checks decide whether it fits. First, confirm the KMS alias `parameter_store_key` exists in every account you will read and write, or set `CHAMBER_KMS_KEY_ALIAS`, because that name is a convention the tool expects rather than a setting it discovers. Second, audit your key names for normalisation collisions, since `secret-key` and `secret_key` resolve to the same stored name. Third, remember that the documented install gives you a binary reporting itself as chamber dev, so pin a tagged release if your tooling records versions. Anyone needing an audit trail beyond SSM's own versioning, or a backend other than Parameter Store, should read the store layout before adopting it.
Frequently asked questions
Where does Chamber store secrets?
In SSM Parameter Store, an AWS service for storing secrets, through its path based API by default since version 2.0. Versions before 2.0 needed the CHAMBER_USE_PATHS environment variable to opt in to that API.
What does Chamber need before it will run?
An authenticated AWS user with permission to read and write values in SSM Parameter Store, and a KMS key with the alias parameter_store_key in that account. The documentation suggests aws-vault as one way to supply credentials.
Why does chamber version print chamber dev?
Version information is passed at compile time by the Makefile, and installing with go install skips the Makefile entirely, so the resulting binary carries no version and prints the placeholder chamber dev.
How are old secrets migrated to the path based format?
With a 2.x version and the export and import commands: CHAMBER_NO_PATHS=1 chamber export foo | chamber import foo -. The CHAMBER_NO_PATHS variable has no effect at all in 3.0 and later.
How does Chamber normalise secret key names?
A dash becomes an underscore and letters are upper cased, so a key written as secret-key and one written as secret_key are both stored as SECRET_KEY. Writing over an existing key increments its version rather than failing.
What replaced the --min-throttle-delay option in Chamber?
Nothing directly. Support for a minimum throttle delay was removed from the underlying AWS SDK, and the documentation suggests setting --retry-mode to adaptive, which it describes as an experimental model that accounts for throttling errors.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/segmentio-chamber)Star history chart for your README
[](https://hysenlabs.com/projects/segmentio-chamber)Was this useful?