Skip to content

Repository files navigation

opaq

Keep secrets out of terminals, context windows, shell histories, and command output.

InstallationQuick StartCommandsHow It WorksAI Agent IntegrationContributing


What is opaq?

opaq is a credential manager and execution wrapper for developers and AI agents. Secrets are stored encrypted, referenced by name, injected at runtime, and scrubbed from all output.

# Find a secret by keyword
opaq search gitlab
# {{GITLAB_TOKEN}} GitLab API personal access token# Use it in a command — the value is injected at runtime, never visible
opaq run -- curl -sS -H "Authorization: Bearer {{GITLAB_TOKEN}}" \
"https://gitlab.example.com/api/v4/projects"

The secret value never appears in your terminal, shell history, log files, or AI agent context. Any accidental output is replaced with [MASKED].

Why opaq?

  • Shell history is a liability. Every export API_KEY=sk-... is saved to disk in plaintext.
  • Clipboard mistakes happen. One wrong paste and a credential lands in a chat window.
  • AI agents amplify the risk. Secrets in context windows are vulnerable to prompt injection, exfiltration, and accidental persistence.

opaq eliminates these risks with a single workflow: search by name, run with placeholders, never see the value.

Installation

Homebrew (macOS & Linux)

brew tap moukrea/tap
brew install opaq

Debian / Ubuntu

# Add GPG key
curl -fsSL https://moukrea.github.io/apt-repo/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/moukrea.gpg
# Add repositoryecho"deb [signed-by=/usr/share/keyrings/moukrea.gpg] https://moukrea.github.io/apt-repo stable main"| \
sudo tee /etc/apt/sources.list.d/moukrea.list
# Install
sudo apt update && sudo apt install opaq

Fedora / RHEL

# Add repository
sudo tee /etc/yum.repos.d/moukrea.repo << 'EOF'[moukrea]name=moukrea Repositorybaseurl=https://moukrea.github.io/rpm-repo/gpgcheck=0repo_gpgcheck=1gpgkey=https://moukrea.github.io/rpm-repo/pubkey.gpgenabled=1EOF# Install
sudo dnf install opaq

Arch Linux

Download the PKGBUILD from the latest release and build:

makepkg -si

Pre-built Binaries

Download the archive for your platform from the latest release:

PlatformArchitectureArchive
Linuxx86_64opaq-<version>-linux-x86_64.tar.gz
Linuxaarch64opaq-<version>-linux-aarch64.tar.gz
macOSx86_64opaq-<version>-macos-x86_64.tar.gz
macOSApple Siliconopaq-<version>-macos-aarch64.tar.gz

Extract and copy the binary to your PATH:

tar xzf opaq-<version>-<os>-<arch>.tar.gz
sudo mv opaq /usr/local/bin/

From Source

Requires the Rust toolchain (stable).

git clone https://github.com/moukrea/opaq.git
cd opaq/opaq
# Linux
cargo build --release --features linux-keychain
# macOS
cargo build --release --features macos-keychain

The binary is at target/release/opaq. Copy it somewhere on your PATH.

Supported platforms

PlatformArchitectureKeychain Backend
Linuxx86_64, aarch64GNOME Keyring (D-Bus Secret Service)
macOSx86_64, Apple SiliconKeychain Services

Requirements

  • An OS keychain service (GNOME Keyring, macOS Keychain)
  • jq on PATH (used by Claude Code hooks)

Quick Start

# 1. Initialize the encrypted store and master key
opaq init
# 2. Add a secret (value is entered interactively, never as an argument)
opaq add GITHUB_TOKEN "GitHub personal access token" --tags github,ci
# 3. Search for secrets
opaq search github
# {{GITHUB_TOKEN}} GitHub personal access token# 4. Use in commands
opaq run -- gh api /user -H "Authorization: Bearer {{GITHUB_TOKEN}}"

Commands

For everyone (interactive terminal required)

CommandDescription
opaq initCreate the encrypted store and save the master key in your OS keychain
opaq add <NAME> <DESC>Add a secret (value entered via secure prompt)
opaq edit <NAME>Change a secret's description, tags, or value
opaq remove <NAME>Delete a secret
opaq export --to <FILE>Export an encrypted backup
opaq import --from <FILE>Restore from a backup
opaq lockClear the master key from the keychain
opaq unlockReload the master key into the keychain

For humans and AI agents

CommandDescription
opaq search <QUERY>Find secrets by name, tags, or description (never shows values)
opaq run -- <CMD>Execute a command with {{SECRET}} placeholders injected at runtime

Secret names are always uppercase with underscores: API_TOKEN, DB_PASSWORD, SSH_KEY_PATH.

Examples

# API calls
opaq run -- curl -sS \
-H "Authorization: Bearer {{API_TOKEN}}" \
"https://api.example.com/v1/issues"# Docker registry login
opaq run -- sh -c \
'echo {{REGISTRY_PASSWORD}} | docker login registry.example.com -u admin --password-stdin'# SSH
opaq run -- ssh -i "{{SSH_KEY_PATH}}" deploy@server.example.com uptime
# Pipe through jq (output is already scrubbed)
opaq run -- sh -c \
'curl -sS -H "PRIVATE-TOKEN: {{GITLAB_TOKEN}}" \ "https://git.example.com/api/v4/projects" | jq .[].name'# JSON output for scripting
opaq search ci --json

How It Works

Storage

Secrets are stored in a single encrypted file at ~/.config/opaq/store, encrypted with age (ChaCha20-Poly1305). The master key lives only in your OS keychain — never on the filesystem.

Runtime injection

When you run opaq run -- <command>, opaq:

  1. Decrypts secrets in memory
  2. Replaces {{PLACEHOLDER}} tokens with actual values in the command arguments
  3. Spawns the child process
  4. Filters stdout and stderr in real time, replacing any secret value with [MASKED]
  5. Scrubs files written during execution, replacing secret values in text files and deleting binary files that contain matches

The output filter uses an Aho-Corasick multi-pattern automaton to catch secrets in all their forms: raw, URL-encoded, Base64-encoded, and shell-escaped.

What [MASKED] means

If you see [MASKED] in output, the command ran successfully — you just can't see the credential value. This is a fixed-length token that doesn't leak the length of the original secret.

AI Agent Integration

opaq is designed to work with AI coding agents like Claude Code. The claude-code-plugins package provides:

  • A skill that teaches agents the search-then-run workflow
  • Hook scripts that block agents from accessing the store directly, prevent writing placeholders to files, and auto-wrap commands containing {{SECRET}} placeholders

Three enforcement layers

  1. Instruction layer — The skill file teaches agents the correct workflow
  2. Hook layer — Shell scripts intercept tool calls, blocking unsafe patterns and auto-correcting commands
  3. Binary layer — TTY enforcement prevents agents from running interactive commands; the output filter and file scrubber prevent value leakage regardless of agent behavior

Setup

opaq setup # Interactive wizard for Claude Code integration
opaq setup --check # Verify installation

Security Model

  • Secret values are never passed as CLI arguments (entered via /dev/tty)
  • The master key exists only in the OS keychain
  • The store file is encrypted at rest with age (ChaCha20-Poly1305)
  • Output filtering catches raw, URL-encoded, Base64, and shell-escaped variants
  • File scrubbing watches for secrets written to disk during command execution
  • Interactive commands (add, edit, remove, etc.) require a TTY — agents cannot run them

License

MIT

About

No description, website, or topics provided.

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages