CONNECT Egress Proxy
Relevant source files
The following files were used as context for generating this wiki page:
The CONNECT Egress Proxy is the primary data-plane component of Honmoon responsible for intercepting and regulating outbound traffic from AI agents. It operates as a terminating forward proxy that utilizes the HTTP CONNECT method to establish tunnels to external destinations. By intercepting these requests, the proxy can apply declarative security policies—returning verdicts of allow, deny, or pause—before any sensitive data leaves the controlled environment.
This proxy is implemented in Rust using the tokio asynchronous runtime. It serves as the enforcement point where wire-level facts are extracted and passed to the Policy Engine for validation. In its current implementation, it primarily filters based on target domains and ports, ensuring a "fail-closed" security posture by default.
Sources: ARCHITECTURE.md:10-18, crates/honmoon-proxy/src/gateway.rs:62-112, wiki/getting-started/overview.md
Request Lifecycle and Decision Flow
The proxy follows a strict lifecycle for every incoming connection to ensure security and auditability. It canonicalizes the requested host and port before consulting the policy engine.
The diagram shows the standard flow of a connection request through the proxy.
Sources: crates/honmoon-proxy/src/gateway.rs:112-201, crates/honmoon-core/src/engine.rs:19-28, wiki/deep-dive/architecture.md
1. Interception and Parsing
When an agent connects, the proxy reads the HTTP request head with a strict size limit and timeout to prevent "slowloris" style attacks. It specifically looks for the CONNECT method; all other HTTP methods are rejected with a 405 Method Not Allowed response.
Sources: crates/honmoon-proxy/src/gateway.rs:64-67, crates/honmoon-proxy/src/gateway.rs:125-128
2. Policy Evaluation
The proxy constructs a Facts structure containing the target domain and port. This is passed to decide_explained(), which evaluates the request against:
- Protocol Rules: Fine-grained CEL expressions.
- Egress Lists: Simple domain allow/deny lists.
Sources: crates/honmoon-core/src/engine.rs:19-91, crates/honmoon-proxy/src/gateway.rs:136-140
3. Verdict Enforcement
- Allow: The proxy initiates a TCP connection to the target. If successful, it returns
200 Connection Establishedand begins bi-directional byte copying. - Deny: The proxy returns
403 Forbiddenand terminates the connection. - Pause: The connection is placed in an
ApprovalRegistry. The proxy waits for a resolution (Approved/Rejected) or a timeout.
Sources: crates/honmoon-proxy/src/gateway.rs:156-201, crates/honmoon-proxy/src/gateway.rs:206-271
Key Components
| Component | Responsibility | Source |
|---|---|---|
GatewayState | Shared state holding policy, audit log, and approval registry. | gateway.rs:46-55 |
handle_connection | The main async loop processing the HTTP CONNECT handshake. | gateway.rs:112-201 |
ApprovalRegistry | Manages connections held in a Pause state awaiting human intervention. | crates/honmoon-proxy/src/approval.rs |
Facts | Data structure containing wire-extracted details (domain, port, protocol). | crates/honmoon-core/src/lib.rs:88-100 |
Error Handling and HTTP Status Codes
The proxy maps internal logic outcomes to standard HTTP status codes to communicate with the AI agent.
| Status Code | Meaning | Reason |
|---|---|---|
200 | Connection Established | Verdict was Allow and upstream connection succeeded. |
400 | Bad Request | Malformed HTTP request or oversized header. |
403 | Forbidden | Verdict was Deny or a Pause request was rejected/timed out. |
405 | Method Not Allowed | The agent attempted a non-CONNECT method. |
408 | Request Timeout | The agent took too long to send the HTTP head. |
502 | Bad Gateway | Upstream connection failed (e.g., DNS error or host unreachable). |
503 | Service Unavailable | Pause verdict received but the approval queue is full. |
Sources: crates/honmoon-proxy/src/gateway.rs:112-201, wiki/getting-started/quick-start.md
Implementation Details: "Fail-Closed" Invariant
The proxy ensures a "fail-closed" posture through its integration with the policy engine. If the policy engine encounters an error during CEL evaluation or if no rule matches, the system falls back to the egress.default verdict, which is Deny by default.
// crates/honmoon-core/src/engine.rs:30-45
fn egress_verdict(policy: &Policy, facts: &Facts) -> Verdict {
if let Some(domain) = &facts.domain {
if policy.egress.deny.iter().any(|p| matches_domain(p, domain)) {
return Verdict::Deny;
}
if policy.egress.allow.iter().any(|p| matches_domain(p, domain)) {
return Verdict::Allow;
}
}
policy.egress.default // Typically Verdict::Deny
}
Sources: crates/honmoon-core/src/engine.rs:30-45, ARCHITECTURE.md:83-85
Operating Modes
The CONNECT proxy can be launched in two primary ways via the honmoon-cli:
- Standalone Gateway: Launched via
honmoon gateway, it runs as a persistent service listening on a specific address (default127.0.0.1:8443). It also hosts the management API and dashboard. - Process Wrapper: Launched via
honmoon run -- <command>, it starts an ephemeral instance of the proxy on a random port and injectshttps_proxyenvironment variables into the child process.
Sources: crates/honmoon-cli/src/main.rs:34-98, wiki/getting-started/quick-start.md
Summary
The CONNECT Egress Proxy serves as the critical gatekeeper in the Honmoon architecture. By strictly enforcing the HTTP CONNECT protocol and integrating deeply with a transport-agnostic policy engine, it provides a robust layer of protection against unauthorized network activity by AI agents while maintaining a clear audit trail and support for human-in-the-loop approvals.