Murmur
Pass secrets as environment variables to a process
Install / Use
/learn @busser/MurmurREADME
🤫 Murmur <!-- omit in toc -->
Plug-and-play executable to pass secrets as environment variables to a process.
Murmur is a small binary that reads its environment variables, replaces references to secrets with the secrets' values, and passes the resulting variables to your application. Variables that do not reference secrets are passed as-is.
Several tools like Murmur exist, each supporting a different secret provider. Murmur aims to support as many providers as possible, so you can use Murmur no matter which provider you use.
| | Scaleway | AWS | Azure | GCP | Vault | 1Password | Doppler | | ---------------------------------------------------------- | -------- | --- | ----- | --- | ----- | --------- | ------- | | 🤫 Murmur | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | | Berglas | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | | Bank Vaults | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | | 1Password CLI | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | | Doppler CLI | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
If you know of a similar tool that is not listed here, please open an issue so that we can add it to the list.
If you use a secret provider that is not supported by Murmur, please open an issue so that we can track demand for it.
- Fetching a database password
- Adding Murmur to a container image
- Adding Murmur to a Kubernetes pod
- Parsing JSON secrets
- Go library usage
- Providers and filters
- Error handling and troubleshooting
- Changes from v0.4 to v0.5
Fetching a database password
Murmur runs as a wrapper around any command. For example, if you want to connect to a PostgreSQL database, instead of running this command:
export PGPASSWORD="Q-gVzyDPmvsX6rRAPVjVjvfvR@KGzPJzCEg2"
psql -h 10.1.12.34 -U my-user -d my-database
You run this instead:
export PGPASSWORD="scwsm:database-password"
murmur run -- psql -h 10.1.12.34 -U my-user -d my-database
Murmur will fetch the value of the database-password secret from Scaleway
Secret Manager, set the PGPASSWORD environment variable to that value, and
then run psql.
Adding Murmur to a container image
Murmur is a static binary, so you can simply copy it into your container image and use it as your entrypoint. For convenience, the murmur binary is released as a container image you can copy from in your Dockerfile:
COPY --from=ghcr.io/busser/murmur:latest /murmur /bin/murmur
Then you can change your image's entrypoint:
# from this:
ENTRYPOINT ["/bin/run-my-app"]
# to this:
ENTRYPOINT ["/bin/murmur", "run", "--", "/bin/run-my-app"]
Adding Murmur to a Kubernetes pod
You can use Murmur in a Kubernetes pod even if your application's container image does not include Murmur. To do so, you can use an init container that copies Murmur into an emptyDir volume, and then use that volume in your application's container.
Here is an example:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
initContainers:
- name: copy-murmur
image: ghcr.io/busser/murmur:latest
command: ["cp", "/murmur", "/shared/murmur"]
volumeMounts:
- name: shared
mountPath: /shared
containers:
- name: my-app
image: my-app:latest
command: ["/shared/murmur", "run", "--", "/bin/run-my-app"]
volumeMounts:
- name: shared
mountPath: /shared
volumes:
- name: shared
emptyDir: {}
Parsing JSON secrets
Storing secrets as JSON is a common pattern. For example, a secret might contain a JSON object with multiple fields:
{
"host": "10.1.12.34",
"port": 5432,
"database": "my-database",
"username": "my-user",
"password": "Q-gVzyDPmvsX6rRAPVjVjvfvR@KGzPJzCEg2"
}
Murmur can parse that JSON and set environment variables for each field by using
the jsonpath filter:
export PGHOST="scwsm:database-credentials|jsonpath:{.host}"
export PGPORT="scwsm:database-credentials|jsonpath:{.port}"
export PGDATABASE="scwsm:database-credentials|jsonpath:{.database}"
export PGUSER="scwsm:database-credentials|jsonpath:{.username}"
export PGPASSWORD="scwsm:database-credentials|jsonpath:{.password}"
murmur run -- psql
If you have multiple references to the same secret, Murmur will fetch the secret only once to avoid unnecessary API calls.
Alternatively, you can use the jsonpath filter to set a single environment
variable with the entire JSON object:
# psql supports connection strings, so we can use a single variable
export PGDATABASE="scwsm:database-credentials|jsonpath:postgres://{.username}:{password}@{.host}:{.port}/{.database}"
murmur run -- psql
Murmur uses the Kubernetes JSONPath syntax for the jsonpath filter. See the
Kubernetes documentation
for a full list of capabilities.
Go library usage
As of v0.7.0, Murmur's internal components are available as a public Go library. You can import and use Murmur's provider system and secret resolution pipeline directly in your Go applications.
Basic secret resolution
package main
import (
"fmt"
"log"
"github.com/busser/murmur/pkg/murmur"
)
func main() {
// Define secrets using the same syntax as environment variables
secrets := map[string]string{
"DB_PASSWORD": "awssm:my-database-secret",
"API_KEY": "gcpsm:my-project/api-credentials|jsonpath:{.key}",
"DEBUG_MODE": "passthrough:true", // Non-secret values pass through
}
// Resolve all secrets
resolved, err := murmur.ResolveAll(secrets)
if err != nil {
log.Fatal(err)
}
fmt.Printf("DB Password: %s\n", resolved["DB_PASSWORD"])
fmt.Printf("API Key: %s\n", resolved["API_KEY"])
fmt.Printf("Debug Mode: %s\n", resolved["DEBUG_MODE"])
}
Using providers directly
package main
import (
"context"
"fmt"
"log"
"github.com/busser/murmur/pkg/murmur"
)
func main() {
// Get a specific provider
providerFactory, exists := murmur.ProviderFactories["awssm"]
if !exists {
log.Fatal("AWS Secrets Manager provider not available")
}
provider, err := providerFactory()
if err != nil {
log.Fatal(err)
}
defer provider.Close()
// Fetch a secret directly
secret, err := provider.Resolve(context.Background(), "my-secret")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Secret value: %s\n", secret)
}
Available providers
All built-in providers are available through murmur.ProviderFactories:
"awssm"- AWS Secrets Manager"azkv"- Azure Key Vault"gcpsm"- GCP Secret Manager"scwsm"- Scaleway Secret Manager"passthrough"- Testing/no-op provider
Use cases
The Go library enables several powerful patterns:
- Configuration-based secret resolution instead of environment variables
- Custom secret injection workflows in Go applications
- Testing with mock providers for unit tests
- Building custom secret management tools on top of Murmur's provider system
Providers and filters
Murmur's architecture is built around providers and filters. Providers fetch secrets from a secret manager, and filters parse and transform the secrets.
Murmur only edits environment variables which contain valid queries. A valid query is structured as follows:
provider_id:secret_ref|filter_id:filter_rule
Using a filter is optional, so this is also a valid query:
provider_id:secret_ref
Murmur does not support chaining multiple filters yet.
scwsm provider: Scaleway Secret Manager
To fetch a secret from Scaleway Secret Manager, the query must be structured as follows:
scwsm:[region/]{name|id}[#version]
If region is not specified, Murmur will delegate region selection to the
Scaleway SDK. The SDK determines the region based on the environment, by looking
at environment variables and configuration files.
One of name or id must be specified. Murmur guesses whether the string is a
name or an ID depending on whether it is a valid UUID. UUIDs are treated as IDs,
and other strings are treated as names.
The version must either be a positive integer or the "latest" string. If
version is not specified, Murmur defaults to "latest".
Examples:
scwsm:my-secret
scwsm:my-secret#123
scwsm:my-secret#latest
scwsm:fr-par/my-secret
scwsm:fr-par/my-secret#123
scwsm:fr-par/my-secret#latest
scwsm:3f34b83f-47a6-4344-bc
Related Skills
tmux
347.2kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
claude-opus-4-5-migration
108.0kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
diffs
347.2kUse the diffs tool to produce real, shareable diffs (viewer URL, file artifact, or both) instead of manual edit summaries.
terraform-provider-genesyscloud
Terraform Provider Genesyscloud
