sentinel-agent-protocol 0.1.6

Agent protocol and IPC for Sentinel reverse proxy external processors
Documentation

Agent protocol for Sentinel proxy

This crate defines the protocol for communication between the proxy dataplane and external processing agents (WAF, auth, rate limiting, custom logic).

The protocol is inspired by SPOE (Stream Processing Offload Engine) and Envoy's ext_proc, designed for bounded, predictable behavior with strong failure isolation.

Architecture

  • [AgentClient]: Client for sending events to agents from the proxy
  • [AgentServer]: Server for implementing agent handlers
  • [AgentHandler]: Trait for implementing agent logic
  • [AgentResponse]: Response from agent with decision and mutations

Transports

Two transport options are supported:

Unix Domain Sockets (Default)

Messages are length-prefixed JSON:

  • 4-byte big-endian length prefix
  • JSON payload (max 10MB)

gRPC

Binary protocol using Protocol Buffers over HTTP/2:

  • Better performance for high-throughput scenarios
  • Native support for TLS/mTLS
  • Language-agnostic (agents can be written in any language with gRPC support)

Example: Client Usage (Unix Socket)

use sentinel_agent_protocol::{AgentClient, EventType, RequestHeadersEvent};

let mut client = AgentClient::unix_socket("my-agent", "/tmp/agent.sock", timeout).await?;
let response = client.send_event(EventType::RequestHeaders, &event).await?;

Example: Client Usage (gRPC)

use sentinel_agent_protocol::{AgentClient, EventType, RequestHeadersEvent};

let mut client = AgentClient::grpc("my-agent", "http://localhost:50051", timeout).await?;
let response = client.send_event(EventType::RequestHeaders, &event).await?;

Example: Server Implementation

use sentinel_agent_protocol::{AgentServer, AgentHandler, AgentResponse};

struct MyAgent;

#[async_trait]
impl AgentHandler for MyAgent {
    async fn on_request_headers(&self, event: RequestHeadersEvent) -> AgentResponse {
        // Implement your logic here
        AgentResponse::default_allow()
    }
}

let server = AgentServer::new("my-agent", "/tmp/agent.sock", Box::new(MyAgent));
server.run().await?;