SkillAgentSearch skills...

Murmur

Pass secrets as environment variables to a process

Install / Use

/learn @busser/Murmur
About this skill

Quality Score

0/100

Category

Operations

Supported Platforms

Universal

README

🤫 Murmur <!-- omit in toc -->

License Go Report Card tests-passing

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

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

View on GitHub
GitHub Stars128
CategoryOperations
Updated2mo ago
Forks7

Languages

Go

Security Score

100/100

Audited on Jan 9, 2026

No findings