Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

348 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cagent

Secure development and execution environment for AI agents with isolated networking.

Problem

AI agents need network access to be usefulβ€”fetching documentation, calling APIs, installing packages. But unrestricted access creates serious risks:

The core tension: agents need enough access to work, but not so much that a misaligned or compromised agent can cause damage.

Threat Model

Cagent assumes the AI agent is untrusted by default. The agent may be:

Threat Description
Misaligned Pursues goals that don't match user intent (prompt injection, jailbreak)
Compromised Executes malicious code from a poisoned dependency or hostile input
Overly capable Has access to credentials/APIs it shouldn't, even if behaving correctly
Unpredictable Makes unexpected network requests due to hallucination or bugs

Security Principles

Principle Description
Network Isolation Cell can only reach proxy (Envoy or mitmproxy) and CoreDNS (DNS filter) - no direct internet access
Credential Hiding Cell never sees API keys; credentials injected by proxy at egress
Defense in Depth Multiple layers: network, container, optional kernel (gVisor) isolation
Least Privilege Minimal capabilities, read-only filesystem, resource limits
Audit Everything All HTTP requests, DNS queries, and syscalls logged

Hardening Details

Container Security

Control Implementation
No privilege escalation no-new-privileges security option
Seccomp profile Blocks raw sockets (prevents packet-crafting bypass)
Resource limits CPU, memory, PID limits enforced
Forced proxy HTTP_PROXY/HTTPS_PROXY environment variables
Forced DNS Container DNS set to CoreDNS filter IP

Network Security

Control Implementation
Internal network cell-net marked as internal: true (no default gateway)
Protocol restriction Cell can ONLY reach Envoy (HTTP), mitmproxy (HTTPS), and CoreDNS (DNS)
IPv6 disabled Prevents bypass of IPv4 egress controls
Allowlist enforcement CoreDNS blocks resolution of non-allowed domains
Egress proxy All HTTP routed through Envoy; HTTPS through mitmproxy β†’ Envoy
Raw socket blocked Seccomp profile prevents packet crafting

Protocol Smuggling Prevention: Raw TCP/UDP to external hosts is impossible. The cell can only reach a few IPs on the internal network: Envoy (port 8443, HTTP), mitmproxy (port 8080, HTTPS), and CoreDNS (port 53, DNS). Seccomp blocks raw socket creation (AF_PACKET), preventing packet crafting.

Residual Exfiltration Channels: Small amounts of data could theoretically be exfiltrated via DNS queries or HTTPS traffic to allowlisted domains. Mitigations: DNS tunneling detection (blocks long subdomains) and audit logging.

Defense in Depth: Network isolation doesn't depend solely on Envoy/CoreDNS being healthy. The internal: true network flag removes the default gateway at the Docker level.

Kernel Isolation (gVisor)

The standard profile uses gVisor to intercept syscalls in user-space. This is the recommended default for production.

Control Implementation
gVisor runtime runsc - syscalls never reach host kernel

Credential Security

Control Implementation
Injection at proxy Envoy ext_authz filter injects credentials at egress
Short-lived cache Credentials cached for 5 minutes

Quick Start

Standalone Mode

Run with local configuration - ideal for local use of one cell.

Minimal (Static Config)

Lightweight setup with just 3 containers. Edit cagent.yaml and run the config generator, or edit raw coredns/Corefile and envoy/envoy.yaml directly for advanced use. Ideal for simple static domain policies on one cell.

Limitation: Credential injection is not available in minimal mode. It requires warden (add --profile admin or --profile managed). Without warden, Envoy's ext_authz fails open β€” requests pass through but credentials defined in cagent.yaml are not injected.

graph TD
    subgraph cellnet["cell-net (isolated)"]
        Cell["πŸ”’ Cell<br/>Isolated network Β· no direct internet<br/>All HTTP(S) via proxy Β· DNS via filter"]
        HP["HTTP(S) Proxy"]
        DNS["DNS Filter"]
        Cell --> HP
        Cell --> DNS
    end
Loading
# Recommended: with gVisor (requires installation: https://gvisor.dev/docs/user_guide/install/)
docker compose --profile standard up -d

# Development: without gVisor (if not installed)
docker compose --profile dev up -d

Locally Managed (With Admin UI)

Adds warden (watches cagent.yaml) and local admin UI for browser-based management and observability. Ideal for complex and changing domain policies on one cell.

graph TD
    subgraph dp["DATA PLANE"]
        Warden["πŸ›‘οΈ Warden (:8081)<br/>Admin UI Β· config editor Β· terminal Β· logs<br/>Watches cagent.yaml Β· regenerates configs"]

        subgraph cellnet["cell-net (isolated)"]
            Cell["πŸ”’ Cell"]
            HP["HTTP(S) Proxy<br/>egress controls"]
            DNS["DNS Filter<br/>allowlist"]
            Cell --> HP
            Cell --> DNS
        end

        Warden --> cellnet
    end
Loading
# Recommended: with gVisor (requires installation)
docker compose --profile standard --profile admin up -d

# Development: without gVisor
docker compose --profile dev --profile admin up -d

Admin UI (http://localhost:8081):

  • Structured config editor (domains, rate limits, credentials)
  • Container status with health checks
  • Log viewer with traffic analytics
  • Browser-based web terminal

Locally Managed with Auditing

Adds log collection and a local log store for standalone deployments. Vector collects logs from all containers and ships them to OpenObserve (local log analytics) and local files. The warden queries OpenObserve for the traffic analytics dashboard. Configure additional sinks (S3, Elasticsearch) in configs/vector/sinks/standalone.yaml.

graph TD
    subgraph dp["DATA PLANE"]
        Warden["πŸ›‘οΈ Warden (:8081)<br/>Admin UI Β· config sync"]
        Vector["πŸ“‹ Log Shipper (Vector)<br/>also writes to file"]
        OO["πŸ“Š Log Store (OpenObserve)<br/>30d retention"]

        Vector --> OO
        Warden -- "queries" --> OO

        subgraph cellnet["cell-net (isolated)"]
            Cell["πŸ”’ Cell"]
            HP["HTTP(S) Proxy<br/>egress controls"]
            DNS["DNS Filter<br/>allowlist"]
            Email["πŸ“§ Email Proxy β€” beta<br/>IMAP/SMTP Β· per-recipient policy"]
            Cell --> HP
            Cell --> DNS
            Cell --> Email
        end

        Warden --> cellnet

        style Email stroke-dasharray: 5 5
    end
Loading
# With auditing (log collection + local log store)
docker compose --profile dev --profile admin --profile auditing up -d

# With email proxy (beta)
docker compose --profile dev --profile admin --profile auditing --profile email up -d

Multiple Cells

Run multiple isolated cells on the same data plane. Each cell gets its own container with independent network isolation, sharing the same proxy, DNS filter, and policy configuration.

# 3 cells with admin UI and auditing
docker compose --profile dev --profile admin --profile auditing up -d --scale cell-dev=3

Cells are named cagent-cell-dev-1, cagent-cell-dev-2, etc. All share the same cell-net network and are subject to the same domain allowlist, rate limits, and credential injection policies.

Accessing the Cell

Method How
Web Terminal http://localhost:8081 (admin UI)
Docker exec docker exec -it cell bash
SSH Direct SSH to port 2222 (configure via admin UI)

Connected Mode

For centralized management of multiple data planes, connect to a control plane. Connected mode adds:

  • Centralized policy management β€” domain policies, security profiles, and credentials managed from a single admin UI
  • Multi-tenant isolation β€” multiple teams share one control plane with full tenant isolation
  • Remote cell management β€” start, stop, restart, and wipe cells from the control plane
  • Centralized log querying β€” the control plane queries each DP's local OpenObserve via warden for traffic analytics
  • OAuth authentication β€” GitHub/Google login, API tokens, and IP ACL enforcement
graph TD
    subgraph cp["CONTROL PLANE"]
        UI["Admin UI"] --- API["API"] --- DB["Postgres"]
    end

    subgraph dp["DATA PLANE"]
        Warden["πŸ›‘οΈ Warden<br/>config sync Β· heartbeat"]
        Vector["πŸ“‹ Log Shipper (Vector)<br/>also writes to file"]
        OO["πŸ“Š Log Store (OpenObserve)<br/>30d retention"]

        Vector --> OO
        Warden -- "queries" --> OO

        subgraph cellnet["cell-net (isolated)"]
            Cell["πŸ”’ Cell"]
            HP["HTTP(S) Proxy<br/>egress controls"]
            DNS["DNS Filter<br/>allowlist"]
            Cell --> HP
            Cell --> DNS
        end

        Warden --> cellnet
    end

    Warden -- "heartbeat / config sync / alerts<br/>(outbound)" --> API
    API -- "log queries / commands / config pushes<br/>(inbound via mTLS)" --> Warden
Loading

All connections from DP to CP are outbound β€” no inbound ports needed on the data plane. Log queries from the CP to warden use mTLS.

# Connected mode
CONTROL_PLANE_URL=https://api.example.com CONTROL_PLANE_TOKEN=your-agent-token \
docker compose --profile dev --profile managed --profile auditing up -d

Features

Feature Description
Domain Allowlist Only approved domains can be accessed (enforced by CoreDNS and Envoy)
HTTPS Interception HTTP(S) proxy decrypts HTTPS so all controls apply to encrypted traffic
Credential Injection API keys injected by proxy, never exposed to cell (works for both HTTP and HTTPS)
Rate Limiting Per-domain rate limits to control API usage
Traffic Analytics Requests/sec, top domains, error rates in log viewer
Web Terminal Browser-based shell access to cells (xterm.js)
gVisor Isolation Optional kernel-level syscall isolation for defense in depth
Data Loss Prevention Detects secrets, API keys, and PII in egress request bodies (log, block, or redact)
Email Proxy Controlled IMAP/SMTP access with per-recipient policies - beta

Configuration

See docs/configuration.md for detailed configuration including:

  • Domain policies (allowlist, path filtering, rate limits, egress limits, credentials)
  • Cell management commands
  • Per-cell configuration (cell-specific domain policies)

Documentation

Roadmap

  • Improved secret management in standalone mode (encrypted local storage)
  • Alert rules for security events (gVisor syscall denials, rate limit hits)
  • Per-path rate limits and credential injection (path-level policies within a domain)
  • Prompt injection protection (detect and block injected instructions in agent inputs/outputs)

License

MIT

About

A secure devbox to run AI worksload with network allowlists and API proxies

Resources

Stars

3 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages