Skip to main content

koffer

koffer >_

A CLI tool for managing API keys and tokens. Instead of scattering .env files across your projects, store your secrets in one encrypted file and inject them into your shell right before you need them.

Keys are AES-256-GCM encrypted with Argon2id key derivation, decrypted only when you run koffer unlock.

Why "koffer"?

"Koffer" is a versatile Dutch word for trunk, briefcase or suitcase; a strangely suitable name for this project.

Koffer is designed to be an easy-to-install, portable, no-subscription keystore that works across Windows, Linux (WSL2), PowerShell, and Bash. It keeps your secrets (somewhat) organized and locked away from casual prying eyes. It is not a vault however, and it doesn't pretend to be. It's just a simple container for your API keys and other CLI secrets so they don't get lost in translation or left out in half a dozen .env files. Think of it as "carry-on" security for your development workflow.

Features

  • 🔐 Strong encryption: AES-256-GCM with Argon2id key derivation
  • 🔑 System keyring integration: Optional password storage in OS credential manager
  • 🐚 Shell integration: Works with PowerShell, Bash, and Zsh
  • 📦 Zero config: Sensible defaults for 40+ popular services
  • 💾 Portable: Single encrypted file, easy to backup/restore

Installation

Using uv

# Install as a tool (globally) using uv:
uv tool install koffer
# Install the latest (unreleased) development version:
uv tool install git+https://github.com/jsnel/koffer.git

Quick Start

# Add your first secret
koffer add openai
# Enter master password (first time creates the koffer)
# Enter your API key when prompted

# Recommended: run commands with secrets injected (secrets never printed)
koffer run -- python -c "import os; print('OPENAI_API_KEY' in os.environ)"

# If you really need env vars in the current shell:
# PowerShell:
Invoke-Expression (koffer unlock)

# Bash/Zsh:
eval "$(koffer unlock)"

Usage

Add secrets

# Known services get sensible defaults
koffer add openai          # -> OPENAI_API_KEY
koffer add anthropic       # -> ANTHROPIC_API_KEY
koffer add github          # -> GITHUB_TOKEN

# Custom env var or type
koffer add myservice --env-var MY_SECRET --type secret

Unlock (inject into current shell)

unlock is meant for convenience when tools insist on reading env vars from the current shell. For day-to-day usage, prefer koffer run -- <command> so secrets never need to be printed.

PowerShell:

Invoke-Expression (koffer unlock)
# or (equivalent)
koffer unlock | iex

Bash / Zsh / WSL:

eval "$(koffer unlock)"

Unlock specific secrets only:

eval "$(koffer unlock openai anthropic)"

💡 Tip: Your master password is automatically stored in your system's credential manager (Windows Credential Manager, macOS Keychain, or Linux Secret Service) after first use. Use --no-keyring to disable this.

By default, unlock base64-wraps its payload and prefers using the clipboard to reduce accidental exposure. If you want to inspect the generated commands, use:

# Print unlock payload to stdout (still base64-wrapped)
koffer unlock --stdout

# Print commands directly (masked, but decodable)
koffer unlock --stdout --no-obfuscate

# Show plaintext secrets (least secure)
koffer unlock --show-keys

Other commands

koffer list              # Show stored secrets
koffer remove <name>     # Delete a secret
koffer rotate            # Change master password
koffer export backup.enc # Backup koffer
koffer import backup.enc # Restore koffer
koffer run -- <command>  # Run a command with secrets injected (recommended)
koffer store-keyring     # Re-store password in credential manager
koffer purge-keyring     # Remove password from credential manager

Shell Profile Integration

Add to your shell profile for automatic unlocking:

PowerShell ($PROFILE):

# Unlock API keys on shell start (optional)
if (Get-Command koffer -ErrorAction SilentlyContinue) {
    Invoke-Expression (koffer unlock 2>$null)
}

Bash/Zsh (~/.bashrc or ~/.zshrc):

# Unlock API keys on shell start (optional)
command -v koffer &>/dev/null && eval "$(koffer unlock 2>/dev/null)"

WSL2 Integration

To share the same koffer between Windows and WSL2, create a symlink to your Windows koffer file:

cd ~
ln -s /mnt/c/Users/<username>/.koffer.enc .koffer.enc

Now both environments use the same encrypted secrets.

Security Model

Aspect Implementation
Encryption AES-256-GCM with 12-byte random nonce per secret
Key derivation Argon2id (64 MB memory, 3 iterations, 4 parallelism)
Storage ~/.koffer.enc with 600 permissions (Unix)
Credential storage Optional OS keyring (Windows Credential Manager, macOS Keychain, Linux Secret Service)

How it works

  1. Your master password derives an encryption key using Argon2id
  2. Each secret is encrypted with AES-256-GCM using a unique nonce
  3. The unlock command outputs shell export commands
  4. You eval the output to set environment variables in your current shell
  5. Environment variables are process-local and inherited only by child processes

What this protects against

  • ✅ Secrets at rest (encrypted on disk)
  • ✅ Casual shoulder surfing (secrets are masked in output)
  • ✅ Other users on shared systems (file permissions)

What this does NOT protect against

  • ❌ Malware with access to your shell's memory
  • ❌ Root/admin users on the same machine
  • ❌ Keyloggers capturing your master password

Remember: This is a koffer, not a vault. It's designed for convenience and "good enough" security for development workflows, not for high-stakes production secrets.

Supported Services

Supported is a big word here, but koffer includes default environment variable mappings for some number of services (and you can easily add your own):

AI/ML: OpenAI, Anthropic, Google/Gemini, Groq, Mistral, Cohere, Together, Perplexity, Fireworks, DeepSeek, xAI, HuggingFace, Replicate

DevOps: GitHub, GitLab, Vercel, Netlify, Railway, Fly.io, Render, Ngrok

Cloud: AWS, DigitalOcean, Linode, Vultr

Communication: Discord, Slack, Telegram, Twilio

Other: Stripe, SendGrid, Sentry, and more...

Unknown services default to SERVICENAME_API_KEY (or _TOKEN/_SECRET based on --type).

Development

# Clone the repository
git clone https://github.com/jsnel/koffer.git
cd koffer

# Setup env with dev dependencies
uv sync --extra dev

# Install git hooks (runs Ruff + basic hygiene checks)
uv run pre-commit install

# Run hooks against all files
uv run pre-commit run -a

# Run tests
uv run pytest

# Run tests with coverage
uv run pytest --cov

License

MIT License - see LICENSE for details.

Metadata

Release files for koffer 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for koffer 0.1.1
File Size Uploaded
koffer-0.1.1.tar.gz 76.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for koffer 0.1.1
File Interpreter ABI Platform
koffer-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 94.3 kB

Release files / koffer-0.1.1.tar.gz

Download URL koffer-0.1.1.tar.gz
Size 76.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e440e4ad0bd033d0d6eba39a7f3f32e1d317caf56653ca7421db308485ad7656
BLAKE2b-256 checksum
How to use checksums
ba6c085381c26f0e31689816de921bf867f76dee514c9f8c08631311594365c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Release files / koffer-0.1.1-py3-none-any.whl

Download URL koffer-0.1.1-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d6ee1bede0142818f3335cf57dabbc9e82b94d6952ab44c9e56ae6afd0056ca
BLAKE2b-256 checksum
How to use checksums
a7bb0737ace913061f86b4b7a7971dae8d66b6c5137f2a383b6ed39d0e0fe1bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page