cli-with

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2026 License: MIT

README ΒΆ

with

Go Version

Run any command with your secrets. No leaks. No drama.

with exec -- curl -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models

Your API keys stay encrypted, never touch your shell history, and vanish after the command runs.

Why?

  • πŸ” Your secrets, your vault β€” encrypted locally with a master password
  • πŸš€ Zero config exports β€” no more export API_KEY=... in your bashrc
  • πŸ‘₯ Shared server friendly β€” each user gets their own isolated vault
  • 🧹 Clean environment β€” secrets exist only in the subprocess, nowhere else

Features

  • Encryption: Argon2id + AES-256-GCM (industry standard)
  • Per-user vaults: Perfect for shared machines β€” your keys, your vault
  • Minimal env inheritance: Only essential vars (PATH, HOME, etc.) pass through
  • Cross-platform: Linux, macOS, Windows

Installation

Go Install
go install github.com/Grovy-3170/cli-with/cmd/with@latest

Note: This installs to $(go env GOPATH)/bin. Add it to your PATH:

# Add to ~/.zshrc or ~/.bashrc
export PATH="$PATH:$(go env GOPATH)/bin"

Then run source ~/.zshrc or restart your terminal.

Build from Source
git clone https://github.com/Grovy-3170/cli-with.git
cd cli-with
make build

The binary will be created at ./with. Install it system-wide with:

make install
Binary Releases

Download pre-built binaries from the Releases page.

Updating
# If installed via go install
go install github.com/Grovy-3170/cli-with/cmd/with@latest

# If built from source
git pull && make build && make install
Uninstalling
# If installed via go install
rm $(go env GOPATH)/bin/with

# If built from source
make uninstall

Quick Start

1. Initialize Your Vault

Interactive mode (prompts for username):

with init

Explicit username:

with init --user alice

You'll be prompted to create a master password. This password encrypts all your API keys.

2. Store an API Key
with set --user alice OPENAI_API_KEY

or

with set OPENAI_API_KEY

You'll be prompted to enter the key value securely (hidden input).

Alternatively, provide the value directly:

with set --user alice ANTHROPIC_API_KEY --value "your-api-key-here"
3. List Your Keys
with list

or

with list --user alice

This shows the names of all stored keys (not their values).

4. Use Keys in Commands
with exec -- curl -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models

With explicit user:

with exec --user alice -- curl -H "Authorization: Bearer $OPENAI_API_KEY" https://api.openai.com/v1/models

The $OPENAI_API_KEY environment variable is available inside the command, but never exposed to your shell history or parent process.

5. Get a Key Value
with get --user alice OPENAI_API_KEY
6. Remove a Key or Vault

Remove a specific key:

with remove --user alice OLD_API_KEY

Remove entire vault:

with remove --user alice

Usage

Global Flags
Flag Description
--user string Username for the vault (prompts interactively if not provided)
--password-file string Path to file containing the vault password
Commands
with init

Initialize a new user vault.

with init              # Interactive - prompts for username
with init --user <username>

Creates an encrypted vault file at ~/.config/cli-with/users/<username>.vault.

with set

Add or update an API key.

with set --user <username> <KEY_NAME>
with set --user <username> <KEY_NAME> --value "secret-value"

Key names must start with a letter or underscore, followed by letters, digits, or underscores.

with get

Retrieve the value of a specific key.

with get --user <username> <KEY_NAME>
with list

List all key names stored in the vault.

with list --user <username>
with exec

Execute a command with all keys available as environment variables.

with exec -- <command> [args...]
with exec --user <username> -- <command> [args...]

The -- separator is required to distinguish command arguments from flags.

Examples:

# Run a script with your secrets
with exec -- python my_script.py

# With explicit user
with exec --user alice -- python my_script.py

# Use with curl
with exec -- curl -H "X-API-Key: $MY_API_KEY" https://api.example.com

# Chain commands
with exec -- sh -c 'echo $OPENAI_API_KEY | wc -c'
with remove

Remove a specific key or the entire vault.

# Remove a specific key
with remove --user <username> <KEY_NAME>

# Remove entire vault (prompts for confirmation)
with remove --user <username>
with version

Print the version number.

with version
Automation with Password Files

For CI/CD or automation, use --password-file to avoid interactive prompts:

# Store password securely in a temp file (restricted permissions)
echo "my-secure-password" > /tmp/vault-password
chmod 600 /tmp/vault-password

# Use in commands
with --user alice --password-file /tmp/vault-password list

# Clean up
rm /tmp/vault-password

Warning: Password files should have strict permissions (0600) and be deleted after use.

Custom Vault Location

Set the WITH_VAULT_DIR environment variable to change where vaults are stored:

export WITH_VAULT_DIR=/secure/vault-location
with init --user alice

Security Considerations

Password Best Practices
  1. Use strong master passwords: At least 12 characters with mixed case, numbers, and symbols
  2. Never share master passwords: Each user should have their own vault
  3. Avoid password files in production: Use only in secure, automated environments with proper access controls
  4. Consider a password manager: Store your master password in a password manager like 1Password or Bitwarden
File Permissions

The vault directory (~/.config/cli-with/users/) is created with 0700 permissions. Vault files have 0600 permissions. Verify these permissions:

ls -la ~/.config/cli-with/users/

If permissions are incorrect, fix them:

chmod 700 ~/.config/cli-with/users/
chmod 600 ~/.config/cli-with/users/*.vault
Environment Isolation

When using with exec or with <command>:

  • Keys are injected only into the subprocess environment
  • The parent shell never sees the key values
  • Keys don't appear in shell history
  • Only minimal environment variables (PATH, HOME, USER, SHELL, TMPDIR) are inherited

This prevents accidental key exposure through:

  • Shell history logging
  • Process listing (ps eww)
  • Environment dumps
  • Debug output
Key Rotation

Regularly rotate your API keys:

# Update a key
with set --user alice EXISTING_KEY --value "new-secret-value"

# Remove old keys you no longer need
with remove --user alice DEPRECATED_KEY
Shared Server Considerations

On shared servers:

  • Each user has a separate vault file
  • File permissions prevent users from reading each other's vaults
  • The master password is required to decrypt any vault
  • Consider using OS keychain integration for additional security

Troubleshooting

"vault for user 'X' already exists"

You're trying to initialize a vault that already exists. Either use a different username or remove the existing vault:

with remove --user X
with init --user X
"vault for user 'X' does not exist"

Run with init --user X first to create the vault.

"passwords do not match"

During with init, the password and confirmation must match exactly. Try again.

"incorrect password" or "decrypting vault: ..."

The master password you entered is incorrect. Try again carefully. If you've forgotten your password, there's no recovery option. You must delete the vault and reinitialize:

with remove --user alice
with init --user alice
"keyring unavailable"

On Linux, the OS keychain requires a running secret service (like GNOME Keyring or KDE Wallet). If unavailable, the vault falls back to file-based encrypted storage.

Key names with special characters

Key names must follow these rules:

  • Start with a letter (a-z, A-Z) or underscore (_)
  • Followed by letters, digits (0-9), or underscores

Valid: API_KEY, _secret, openai2 Invalid: 2FAST, my-key, api.key

Permission denied errors

Ensure you have write access to the vault directory:

# Check directory permissions
ls -la ~/.config/cli-with/

# Fix if needed
chmod 700 ~/.config/cli-with
chmod 700 ~/.config/cli-with/users
Command not found in exec

When using with exec, the command must be in PATH. Use the full path if needed:

with exec --user alice -- /usr/bin/curl https://example.com
Environment variables not expanded in shell

When using shell variables in commands, wrap with sh -c:

# This won't work - $VAR is expanded by parent shell
with exec --user alice -- echo $MY_KEY

# This works - variable is expanded in subprocess
with exec --user alice -- sh -c 'echo $MY_KEY'

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Make your changes
  4. Run tests (make test)
  5. Run linters (make lint)
  6. Commit your changes
  7. Push to the branch
  8. Open a Pull Request
Development Setup
git clone https://github.com/Grovy-3170/cli-with.git
cd cli-with
go mod download
make test

License

MIT License - see LICENSE file for details.

Directories ΒΆ

Path Synopsis
cmd
with command
internal
commands
Package commands contains all CLI command implementations.
Package commands contains all CLI command implementations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL