Mask your secrets in bash tool_call results when using OpenClaw/Hermes/... .
# Before:
# The model thinks: "Why isn't this working? Let me check if API_KEY exists."
echo $API_KEY
sk-123454545677888 # secret exposed in a tool message
# After:
# The model thinks: "Why isn't this working? Let me check if API_KEY exists. The skill says to prefix commands with maskrun? OK."
maskrun -- echo $API_KEY
sk-1*************8agent-env-guard ships maskrun, a tiny CLI wrapper for developers and coding agents.
It masks matched secret values from stdout and stderr.
- 🤖 Agent-safe: mask secrets in exec outputs
Use one of the install commands below.
From your agent workspace:
npx skills add ctxinf/agent-env-guardThen update AGENTS.md or the other agent instruction files to force the model to follow the skill.
The skill tells agents to wrap risky commands with
maskrun --.
After installing maskrun, add a direct requirement to User.md, AGENTS.md, or another agent instruction file:
## Requirements
When running Bash (or any tool call that executes a command such as Exec or Run), always use the `maskrun --` wrapper.
Use it directly. You do not need to read the skill first.
Examples:
```sh
maskrun -- cargo test
maskrun -- npm run build
maskrun -- curl "https://api.example.com?key=${API_KEY}"
maskrun -- sh -c 'echo "$API_KEY"'
maskrun -- echo "$API_KEY"
maskrun -- cat openclaw.json
```🌍 Cross-platform: Linux, macOS, Windows
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/ctxinf/agent-env-guard/releases/latest/download/agent-env-guard-installer.sh | shpowershell -ExecutionPolicy Bypass -c "irm https://github.com/ctxinf/agent-env-guard/releases/latest/download/agent-env-guard-installer.ps1 | iex"brew install ctxinf/tap/agent-env-guardnpm install @ctxinf/agent-env-guard@latestmaskrun -- curl "https://api.example.com?key=${API_KEY}"
# normal output, with matching secret values masked
maskrun -- bash -lc 'echo "$API_KEY"'
# a*******zHow it works:
- Read environment variables.
- Select variables whose names match the config.
- Replace their exact values in stdout and stderr.
- Return the child command exit code.
maskrun filters command output to reduce accidental secret exposure.
It is not a sandbox, container, secret manager, network firewall, or permission boundary.
The child process can still read environment variables, access files, and use the network.
Default config path:
- Linux / Unix:
$XDG_CONFIG_HOME/maskrun/config.tomlor$HOME/.config/maskrun/config.toml - macOS:
$HOME/Library/Application Support/maskrun/config.toml - Windows:
%APPDATA%\maskrun\config.toml
Default config is created on first run:
[filter]
exact = [
"API_KEY",
"SECRET",
"PASSWORD",
]
glob = [
"*_KEY",
"*_TOKEN",
"*_SECRET",
"*_PASSWORD",
]
regex = [
"(?i)^.*password.*$",
]Rules match environment variable names. Matched values are masked by exact string replacement.
Use a custom config:
maskrun --config ./maskrun.toml -- envShow matched env names without printing raw values:
maskrun --verbose -- sh -c 'echo "$API_KEY"'API_KEY=abc123xyz maskrun -- sh -c 'echo "$API_KEY"'
# a*******zUse single quotes when secret expansion should happen inside the child shell.
maskrun --helpusage: maskrun [--verbose] [--config <path>] -- <raw_command> [raw_args...]