Network Security
Control what network resources sandboxes can access using network policies.
Default Behavior
By default, sandboxes have no network access:
let vm = capsa::sandbox()
.build()
.await?;
// No network access by defaultEnable Network with VirtualNetwork
Use VirtualNetwork to enable networking:
let network = VirtualNetwork::new();
let vm = capsa::sandbox()
.network(&network)?
.build()
.await?;
// Full network access via NATNetwork Policies
Fine-grained control over allowed destinations:
let policy = NetworkPolicy::deny_all()
.allow_domain("api.github.com")
.allow_domain("api.anthropic.com");
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap().policy(policy).unwrap()
);
let vm = capsa::sandbox()
.network(&network)?
.build()
.await?;Domain Filtering
Exact Domain
Allow a specific domain:
let policy = NetworkPolicy::deny_all()
.allow_domain("api.github.com");
// Allows: api.github.com
// Blocks: github.com, www.github.com, anything elseWildcard Domain
Allow a domain and all subdomains:
let policy = NetworkPolicy::deny_all()
.allow_domain("*.github.com");
// Allows: api.github.com, raw.github.com, etc.
// Blocks: github.com (exact match not included)Multiple Domains
Chain multiple domain rules:
let policy = NetworkPolicy::deny_all()
.allow_domain("api.anthropic.com")
.allow_domain("*.github.com")
.allow_domain("registry.npmjs.org")
.allow_domain("pypi.org");Common Use Cases
AI Agent Sandbox
Allow only the AI API:
let policy = NetworkPolicy::deny_all()
.allow_domain("api.anthropic.com")
.allow_domain("api.openai.com");
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap().policy(policy).unwrap()
);
let vm = capsa::sandbox()
.network(&network)?
.build()
.await?;Package Installation
Allow package registries:
let policy = NetworkPolicy::deny_all()
// Rust
.allow_domain("crates.io")
.allow_domain("static.crates.io")
// Python
.allow_domain("pypi.org")
.allow_domain("files.pythonhosted.org")
// Node
.allow_domain("registry.npmjs.org");
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap().policy(policy).unwrap()
);
let vm = capsa::sandbox()
.network(&network)?
.build()
.await?;CI/CD Build
Allow source control and build services:
let policy = NetworkPolicy::deny_all()
.allow_domain("*.github.com")
.allow_domain("*.githubusercontent.com")
.allow_domain("*.docker.io")
.allow_domain("*.docker.com");
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap().policy(policy).unwrap()
);
let vm = capsa::sandbox()
.network(&network)?
.build()
.await?;DNS Resolution
When using domain-based policies, DNS lookups are automatically allowed to resolve the permitted domains. The policy checks the resolved IP against the domain allow list.
Note: If any allow_domain(...) rules are present, DNS (UDP/53) is implicitly allowed ahead of other rules. This means explicit DNS deny/log rules will not apply to DNS queries in that case. If you need to block DNS, avoid domain rules and use IP-based rules instead.
Port Forwarding
Forward ports from host to sandbox:
let network = VirtualNetwork::new();
let vm = capsa::sandbox()
.interface(NetworkInterface::new(&network).forward_tcp(8080, 80))? // host:8080 -> guest:80
.build()
.await?;
// Access sandbox's port 80 at localhost:8080Combining Policies and Port Forwarding
let policy = NetworkPolicy::deny_all()
.allow_domain("api.example.com");
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap()
.policy(policy).unwrap()
);
let vm = capsa::sandbox()
.interface(NetworkInterface::new(&network).forward_tcp(3000, 3000))?
.build()
.await?;Complete Example
use capsa::{VirtualNetwork, Gateway, NetworkPolicy, AccessMode};
async fn run_ai_agent() -> capsa::Result<()> {
let policy = NetworkPolicy::deny_all()
.allow_domain("api.anthropic.com");
let network = VirtualNetwork::with_gateway(
Gateway::new("10.0.2.0/24").unwrap().policy(policy).unwrap()
);
let vm = capsa::sandbox()
.cpus(2)
.memory_mb(1024)
.network(&network)?
.share("./workspace", "/workspace", AccessMode::ReadWrite)
.build()
.await?;
let agent = vm.agent().await?;
// AI-generated code can call the API but nothing else
let result = agent.exec("python3").arg("/workspace/agent.py").run().await?;
println!("Output: {}", result.stdout);
vm.shutdown().await?;
Ok(())
}Next Steps
- Running Commands - Command execution details
- Working with Files - File operations