Skip to content

crhuber/crumb

Repository files navigation

Crumb - Secret Management Tool

crumb is a command line tool designed to securely store, manage, and export API keys and secrets for developers. It uses age encryption with SSH public/private key pairs, and supports both local file storage and S3-compatible backends (AWS S3, MinIO, LocalStack).

crumb is inspired by tools such as:

but, designed for the non-enterprise developer without access to a cloud Secrets Manager, raft storage, etc. Crumb was born out of the need to be able to load secrets without leaving ecrets unencrypted on disk.

How it works

crumb keeps all your secrets inside a single file encryped with an ssh key.

When getting on your secrets, crumb loads the file into memory, decrypts the payload, creates, retrieves or updates secrets, and, if necessary, encrypts the changes back to the store. Each secret is referenced by a path.

Quick Start

# 1. Install crumb
kelp add crhuber/crumb --install

# 2. Initialize your secret store (uses your existing SSH keys)
crumb setup

# 3. Store a secret
crumb set /myapp/api_key
# Enter secret value: [hidden]

# 4. Retrieve it
crumb get /myapp/api_key

# 5. Export secrets as environment variables
eval "$(crumb export --path /myapp)"

Features

  • SSH Key Encryption/Decryption: Securely encrypt your password storage file using SSH Keys
  • S3 Storage Backend: Store encrypted secrets in AWS S3 or S3-compatible services (MinIO, LocalStack)
  • Bulk Export: Exports multiple secrets from an entire path like /myapp/dev/
  • Multi-Profile Support: Manage separate secret stores for work, personal, or different projects
  • .env Import: Import multiple secrets from .env files
  • Shell Integration: Automatic secret loading with shell hooks (bash, zsh, fish)

Installation

  1. Download and add binary to $PATH from https://github.com/crhuber/crumb/releases

OR

  1. Use kelp
kelp add crhuber/crumb --install

Usage

Setup Command

The setup command initializes the secure storage backend for a specific profile.

crumb setup [--profile <profile-name>]

Prerequisites

Before running setup, you need to have SSH keys generated. If you don't have them, create them with:

# For Ed25519 keys (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"

Example Setup Sessions

Default setup:

$ crumb setup

Setup with S3 storage:

$ crumb setup --storage s3 --s3-bucket my-secrets-bucket --s3-key /crumb/secrets

Setup with non default profile

$ crumb --profile work setup

Set Command

The set command adds or updates a secret key-value pair. The value is entered securely on a new line and is not echoed to the terminal or stored in shell history.

crumb set <key-path>

Example Usage

# Add a new secret
$ crumb set /myapp/api_key
Enter secret value: [secret not shown]
Successfully set key: /myapp/api_key

# Update an existing secret (with confirmation)
$ crumb set /myapp/api_key
Key '/myapp/api_key' already exists.
key already exists. Overwrite? (y/n): y
Enter secret value: [secret not shown]
Successfully set key: /myapp/api_key

List Command

The ls command lists all stored secret keys, optionally filtered by path.

crumb ls [path]

Example Usage

# List all secrets
$ crumb ls
/myapp/dev/api_key

# Filter by path prefix
$ crumb ls /myapp
/myapp/api_key
/myapp/secret

Get Command

The get command retrieves a secret by its key path.

crumb get <key-path> [--mask] [--export] [--shell=bash|fish]

Example Usage

# Get a secret
$ crumb get /myapp/api_key
secret123

# Get a secret masked
$ crumb get /myapp/api_key --mask
****

# Export a secret for bash sourcing
$ crumb get /myapp/api_key --export
export API_KEY=secret123

# Export a secret for fish shell
$ crumb get /myapp/api_key --export --shell fish
set -x API_KEY secret123

# Source the export directly in bash
$ eval "$(crumb get /myapp/api_key --export)"
$ echo $API_KEY
secret123

Variable Name Conversion

When using the --export flag, the key path is automatically converted to a valid environment variable name:

  • Leading slash (/) is removed
  • Remaining slashes (/) are converted to underscores (_)
  • Hyphens (-) are converted to underscores (_)
  • The result is converted to uppercase

Examples:

  • /myapp/my-service/auth-tokenAUTH_TOKEN

Shell Integration

The --export flag makes it easy to integrate secrets into shell scripts and workflows:

Bash:

# Source a single secret
eval "$(crumb get /myapp/key --export)"
echo "Key: $KEY"

# Source multiple secrets in a script
#!/bin/bash
eval "$(crumb get /myapp/  --export)"

Fish:

# Source a single secret
eval (crumb get /myapp/key --export --shell fish)

# Source multiple secrets
eval (crumb get /myapp/ --export --shell fish)

Init Command

The init command creates a YAML configuration file in the current project directory.

crumb init

Example Usage

# Create a new .crumb.yaml file
$ crumb init
Successfully created .crumb.yaml

#### Default Configuration Structure

The created `.crumb.yaml` file contains:

```yaml
version: "1.0"
environments:
  default:
    path: ""
    remap: {}
    env: {}

This structure allows you to configure multiple environments, each with:

  • path: A path to sync secrets from (e.g., /myapp/api-key)
  • remap: Key remapping for environment variables
  • env: Individual environment variable configurations

You can add additional environments for different deployment contexts:

version: "1.0"
environments:
  default:
    path: "/myapp/dev/"
    remap: {}
    env: {}
  production:
    path: "/myapp/prod/"
    remap: {}
    env: {}
export MY_KEY=******

Delete Command

The delete command deletes a secret key-value pair from the encrypted file.

crumb delete <key-path>

Example Usage

# Delete a secret (with confirmation)
$ crumb delete /myapp/dev/api_key
Type the key path to confirm deletion: /myapp/dev/api_key
Successfully deleted key: /myapp/dev/api_key

Move Command

The move (or mv) command renames a secret key to a new path, preserving its value. This is useful for reorganizing or refactoring your secret key structure without losing data.

crumb move <old-key-path> <new-key-path>
# or using the alias
crumb mv <old-key-path> <new-key-path>

Import Command

The import command allows you to import multiple secrets from a .env file into your encrypted storage. This is particularly useful when migrating from .env files to Crumb or when setting up a new project with existing environment variables.

crumb import --file <path-to-env-file> --path <destination-path>

.env File Format Support

The import command supports standard .env file formats:

# Comments are ignored
API_KEY=secret123
DATABASE_URL="postgresql://localhost:5432/mydb"
DEBUG=true

Example Usage

Basic import:

# Import to /myapp/dev path
$ crumb import --file .env --path /myapp/dev/

# Verify the imported secrets
$ crumb ls /myapp/dev/

Using with different profiles:

# Import to work profile
$ crumb --profile work import --file work.env --path /work/secrets/

Storage Management Commands

The storage command provides subcommands to manage storage file paths for profiles.

Storage Set

Set the storage file path for the current profile:

crumb storage set <path> [--profile <profile-name>]

Example:

# Set storage path for work profile
$ crumb --profile work storage set ~/.config/crumb/work-secrets

# Set storage path for default profile
$ crumb storage set ~/personal-secrets

Storage Get

Show the current storage file path for the current profile:

crumb storage get [--profile <profile-name>]

Example:

# Check storage path for work profile
$ crumb --profile work storage get
Storage: /Users/username/.config/crumb/work-secrets (profile: work)

# Check storage path for default profile
$ crumb storage get
Storage: /Users/username/.config/crumb/secrets (profile: default)

Storage Clear

Clear the storage file path for the current profile (reverts to default):

crumb storage clear [--profile <profile-name>]

Example:

# Clear custom storage path for work profile
$ crumb --profile work storage clear
Storage path cleared for profile: work (using default)

Profile Management

Multiple Profiles

You can maintain separate secret stores for different contexts (work, personal, projects):

# Set up different profiles
crumb --profile work setup

# Add secrets to different profiles
crumb --profile work set /myapp/key
# Enter "work-secret" when prompted

# List secrets by profile
crumb --profile work ls

# Set default profile via environment variable
export CRUMB_PROFILE=work
crumb ls  # Lists work profile secrets

Export Command

The export command exports secrets as shell-compatible environment variable assignments. It supports two modes:

  1. Config-based export: Uses a .crumb.yaml configuration file (traditional mode)
  2. Direct path export: Exports all secrets from a specific path without requiring a config file (new!)
# Config-based export
crumb export [-f config-file] [--env environment] [--shell=bash|fish] [--profile <profile-name>]

# Direct path export
crumb export --path <secret-path> [--shell=bash|fish] [--profile <profile-name>]

Example Usage

First, create a .crumb.yaml configuration file:

version: "1.0"
environments:
  default:
    path: "/myapp/dev/"
    remap: {}
    env: {}

Then export the secrets:

# Export default environment
$ crumb export

# Export staging environment
$ crumb export --env staging

# Export for fish shell
$ crumb export --shell fish

# Use a custom config file
$ crumb export -f my-project.yaml

# Use custom config file
$ crumb export --file my-project.yaml --shell fish

# Export from work profile
$ crumb export --profile work

# Use environment variable for profile
$ CRUMB_PROFILE=work crumb export --shell=fish

# Source the output directly
$ eval "$(crumb export)"

#### Direct Path Export Examples

The `--path` flag allows you to export secrets directly without a `.crumb.yaml` file:

```bash
# Export all secrets from /api path
$ crumb export --path /myapp/dev/

# Export with fish shell format
$ crumb export --path /myapp/dev/ --shell fish

# Use with different profile
$ crumb export --path /myapp/dev/ --profile work

# Source directly into shell
$ eval "$(crumb export --path /myapp/)"

Path to Variable Name Conversion:

  • Only the final segment (actual secret name) is used, intermediate path segments are ignored
  • Hyphens in the secret name are converted to underscores, and the result is uppercase mgsecret

Remapping Keys

You can change what finally gets exported to shell by using the remap section within an environment:

version: "1.0"
environments:
  default:
    path: "/myapp/dev/"
    remap:
      "FROM": "TO"

For example:

version: "1.0"
environments:
  default:
    path: "/myapp/dev/"
    remap:
      "SOME_SECRET_KEY": "MY_KEY"

will result in SOME_SECRET_KEY being exported as MY_KEY

Manually Setting Environment Varables

Say you want to also export a variable that isnt in your secrets file you can do so by adding it in the env key.

environments:
  default:
    ...
    env:
      MESSAGE: "Hello staging"

If you want to load a single secret from a key you can do it like this:

environments:
  default:
    ...
    env:
      API_KEY: "/myapp/staging/api_key"

Hook Command

The hook command generates shell integration scripts that automatically load secrets when you enter a directory containing a .crumb.yaml file. This provides seamless, automatic environment variable management similar to direnv.

crumb hook <shell>

Supported shells:

  • bash
  • zsh
  • fish

Setup Instructions

Add the following to your shell's configuration file:

Bash (~/.bashrc or ~/.bash_profile):

eval "$(crumb hook --shell bash)"

Zsh (~/.zshrc):

eval "$(crumb hook --shell zsh)"

Fish (~/.config/fish/config.fish):

crumb hook --shell fish | source

How It Works

Once the hook is installed:

  1. When you enter a directory containing a .crumb.yaml file, the hook automatically runs crumb export
  2. The secrets defined in .crumb.yaml are loaded as environment variables
  3. When you leave the directory, the environment variables remain (they are not automatically unloaded)

Example Workflow

# 1. Create a project with secrets
$ mkdir myapp && cd myapp
$ crumb init

# 2. Edit .crumb.yaml to configure your secrets
$ cat > .crumb.yaml << EOF
version: "1.0"
environments:
  default:
    path: "/myapp/dev"
    env: {}
    remap: {}
EOF

# 3. Add some secrets to crumb
$ crumb set /myapp/dev/API_KEY
Enter secret value: ********

$ crumb set /myapp/dev/DATABASE_URL
Enter secret value: ********

# 4. With the hook installed, cd into the directory
$ cd myapp
# Secrets are automatically loaded!

$ echo $API_KEY
your-api-key-value

$ echo $DATABASE_URL
your-database-url

Notes

  • The hook checks for .crumb.yaml in the current directory only (not parent directories)
  • Errors from crumb export are silently suppressed (redirected to /dev/null)
  • The hook preserves the exit status of the previous command (important for bash prompt functions)
  • For bash/zsh, the hook runs on each prompt display and directory change
  • For fish, the hook runs on PWD changes and prompt events

Configuration

~/.config/crumb/config.yaml - Stores profile configurations with SSH key paths and storage locations.

Multi-profile structure:

profiles:
  default:
    public_key_path: ~/.ssh/id_ed25519.pub
    private_key_path: ~/.ssh/id_ed25519
    storage:
      local:
        path: ~/.config/crumb/secrets
  work:
    public_key_path: ~/.ssh/work.pub
    private_key_path: ~/.ssh/work
    storage:
      local:
        path: ~/.config/crumb/work-secrets

Storage Files

Each profile has its own encrypted storage file:

  • Default profile: ~/.config/crumb/secrets (unless customized)
  • Named profiles: Configurable per profile (e.g., ~/.config/crumb/work-secrets)

User Preferences

~/.config/crumb/crumb.toml - Optional TOML configuration file for user preferences.

Shell configuration:

shell = "bash". # Supported values: "bash", "fish", "zsh". Default: "bash"
mask_values = true

Priority order for shell configuration:

  1. Command-line flag (e.g., crumb hook --shell fish)
  2. TOML config file (~/.config/crumb/crumb.toml)
  3. Default value (bash)

Development

This project uses Task for build automation. Common tasks:

  • task test - Run all tests
  • task test-coverage - Run tests with coverage report
  • task bench - Run benchmark tests
  • task build - Build the application
  • task ci - Run CI pipeline
  • task clean - Clean build artifacts
  • task --list - Show all available tasks

Contributing

If you find bugs, please open an issue first.

About

A command line secret management tool

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages