agentguard 0.1.0

Network egress firewall for AI agent tools. Declarative domain allowlist; throws on violation. Optional reqwest-middleware integration.
Documentation

agentguard

crates.io docs.rs License: MIT

Network egress firewall for AI agent tools. Declarative domain allowlist; throws on violation.

[dependencies]
agentguard = "0.1"
# Or, with reqwest-middleware integration:
agentguard = { version = "0.1", features = ["reqwest"] }

Why

Your agent's tools call out to the network. Without a sandbox, a prompt injection or a confused-deputy bug can exfiltrate secrets to attacker-controlled domains. agentguard is the smallest possible primitive that stops it: a declarative allowlist you check before each call (or install once as reqwest-middleware and forget).

Quick start

use agentguard::Allowlist;

let allow = Allowlist::new()
    .domain("api.openai.com")
    .domain("api.anthropic.com")
    .subdomains_of("amazonaws.com");   // permits s3.us-east-1.amazonaws.com etc.

allow.check("https://api.openai.com/v1/chat").unwrap();
allow.check("https://s3.us-east-1.amazonaws.com/bucket/key").unwrap();

// Everything else is rejected:
assert!(allow.check("https://evil.example/leak").is_err());
assert!(allow.check("file:///etc/passwd").is_err());

With reqwest-middleware

Enable the reqwest feature, then plug GuardMiddleware into a reqwest_middleware::ClientBuilder:

# #[cfg(feature = "reqwest")]
# {
use agentguard::{Allowlist, GuardMiddleware};
use reqwest::Client;
use reqwest_middleware::ClientBuilder;

let allow = Allowlist::new().subdomains_of("anthropic.com");
let client = ClientBuilder::new(Client::new())
    .with(GuardMiddleware::new(allow))
    .build();

// Calls to anthropic.com pass; everything else returns a Middleware error.
# }

Rules

  • .domain("api.openai.com") — exact-match host. sub.api.openai.com is not allowed.
  • .subdomains_of("anthropic.com") — apex + any subdomain. anthropic.com, api.anthropic.com, us.api.anthropic.com all pass.
  • .allow_schemes(["https", "wss"]) — override the default ["http", "https"].

Order doesn't matter — a URL is allowed if it matches any rule.

What it doesn't do

  • No DNS resolution; matches on the URL host string. (DNS rebinding is a different threat — pin IPs at the resolver level.)
  • No path filtering; full host gates everything.
  • No regex; subdomain matching is structural (.endsWith(.apex)).

Sibling: JS @mukundakatta/agentguard

JS users: see @mukundakatta/agentguard on npm.

License

MIT