A curl wrapper that blocks outbound HTTP requests containing forbidden strings before they reach the network. Designed to prevent secret/identifier leakage to upstream services (e.g. accidentally posting a private ticket ID into a company Bitbucket PR).
Sister project: agent-git — same author, same model.
Engineers and AI agents alike sometimes paste the wrong context into the wrong place. A typical leak path:
curl -X POST .../pull-requests \
-d '{"title":"PRIVATE-42 fix something"}' # ← PRIVATE-42 should never reach the company PR systemagent-curl intercepts requests to a configured list of "guarded hosts" and refuses to send when the URL or payload matches any forbidden pattern. Everything else passes through to real curl transparently.
cargo install agent-curl
agent-curl init # writes ~/.config/agent-curl/config.toml + plugins.d/
agent-curl install # symlinks /opt/homebrew/bin/curl → agent-curl (RECOMMENDED)
agent-curl doctor # diagnose subprocess interceptionWhy
installand notalias? Shell aliases only work in interactive shells. Build scripts, Makefiles, and AI agents callbash -c "curl ...", which skips aliases. The PATH symlink installed byagent-curl installis the only reliable interception point. Thealiassubcommand is kept for backwards-compat but is deprecated.
agent-curl install auto-picks the first writable PATH dir that comes before /usr/bin:
/opt/homebrew/bin(macOS arm64 brew)/usr/local/bin(macOS x86_64 brew, common Linux)~/.local/bin(XDG userland)
Pass --dir <path> to override. Pass --force to overwrite an existing curl.
~/.config/agent-curl/config.toml:
guarded_hosts = [
"bitbucket\\.example\\.com",
".*\\.atlassian\\.net",
]
forbidden_patterns = [
"PRIVATE-\\d+",
"internal\\.example",
]
guarded_methods = ["POST", "PUT", "PATCH", "DELETE"]
scan_get = falseBoth guarded_hosts and forbidden_patterns are case-insensitive regular expressions.
Drop additional .toml files into ~/.config/agent-curl/plugins.d/. Each plugin uses the same schema; their guarded_hosts and forbidden_patterns are appended (deduplicated) to the base config. Plugins load in lexicographic order.
# ~/.config/agent-curl/plugins.d/00-mycompany.toml
guarded_hosts = ["jira\\.mycompany\\.com"]
forbidden_patterns = ["INTERNAL-\\d+"]Project-local override: drop a .agent-curl.toml at the project root (search walks up the directory tree). Env override: AGENT_CURL_CONFIG=/path/to/config.toml.
# Transparent: GET to non-guarded host
curl https://example.com
# Transparent: POST to guarded host with clean payload
curl -X POST -d '{"title":"PUBLIC-1 fix"}' https://bitbucket.example.com/...
# Blocked: POST to guarded host with forbidden payload
curl -X POST -d '{"title":"PRIVATE-42 leak"}' https://bitbucket.example.com/...
# ❌ agent-curl BLOCKED: payload contains forbidden pattern(s)
# Hit(s) : PRIVATE-42
# Exit code: 1 — request never sent.agent-curl # passthrough mode (or shows usage if no args)
agent-curl install # symlink as `curl` in PATH (recommended)
agent-curl uninstall # remove the symlink
agent-curl doctor # diagnose install + interception
agent-curl init # write default config + plugins.d/
agent-curl config # show effective config (with loaded plugins)
agent-curl check --url ... --data ... --data-file ...
# test guards without sending
agent-curl alias install|uninstall|status
# [DEPRECATED] shell-alias mode
When a request would go to a guarded_hosts host with a guarded_methods method (or any request with -d), agent-curl scans:
- The URL itself (path may carry forbidden refs)
- Inline payload from
-d/--data-*/-F - File payload from
-d @path
If any pattern matches, the request is blocked with exit code 1 and the network is never touched.
MIT
agent-git— git wrapper (duplicate-clone detection)