HTTP Input Module
🌐 Other Languages
The HTTP Input module provides a webhook server that allows external systems to invoke Symbiont agents via HTTP requests. This module enables integration with external services, webhooks, and APIs by exposing agents through HTTP endpoints.
Overview
The HTTP Input module consists of:
- HTTP Server: An Axum-based web server that listens for incoming HTTP requests
- Authentication: Support for Bearer token and JWT-based authentication
- Request Routing: Flexible routing rules to direct requests to specific agents
- Response Control: Configurable response formatting and status codes
- Security Features: CORS support, request size limits, and audit logging
- Concurrency Management: Built-in request rate limiting and concurrency control
The module is conditionally compiled with the http-input feature flag and integrates seamlessly with the Symbiont agent runtime.
Configuration
The HTTP Input module is configured using the HttpInputConfig structure:
Basic Configuration
use symbiont_runtime::http_input::HttpInputConfig;
use symbiont_runtime::types::AgentId;
let config = HttpInputConfig {
bind_address: "127.0.0.1".to_string(),
port: 8081,
path: "/webhook".to_string(),
agent: AgentId::from_str("webhook_handler")?,
// ... other fields
..Default::default()
};
Configuration Fields
| Field | Type | Default | Description |
|---|---|---|---|
bind_address |
String |
"127.0.0.1" |
IP address to bind the HTTP server |
port |
u16 |
8081 |
Port number to listen on |
path |
String |
"/webhook" |
HTTP path endpoint |
agent |
AgentId |
New ID | Default agent to invoke for requests |
auth_header |
Option<String> |
None |
Bearer token for authentication |
jwt_public_key_path |
Option<String> |
None |
Path to JWT public key file |
max_body_bytes |
usize |
65536 |
Maximum request body size (64 KB) |
concurrency |
usize |
10 |
Maximum concurrent requests |
routing_rules |
Option<Vec<AgentRoutingRule>> |
None |
Request routing rules |
response_control |
Option<ResponseControlConfig> |
None |
Response formatting config |
forward_headers |
Vec<String> |
[] |
Headers to forward to agents |
cors_origins |
Vec<String> |
[] |
Allowed CORS origins (empty = CORS disabled) |
audit_enabled |
bool |
true |
Enable request audit logging |
Agent Routing Rules
Route requests to different agents based on request characteristics:
use symbiont_runtime::http_input::{AgentRoutingRule, RouteMatch};
let routing_rules = vec![
AgentRoutingRule {
condition: RouteMatch::PathPrefix("/api/github".to_string()),
agent: AgentId::from_str("github_handler")?,
},
AgentRoutingRule {
condition: RouteMatch::HeaderEquals("X-Source".to_string(), "slack".to_string()),
agent: AgentId::from_str("slack_handler")?,
},
AgentRoutingRule {
condition: RouteMatch::JsonFieldEquals("source".to_string(), "twilio".to_string()),
agent: AgentId::from_str("sms_handler")?,
},
];
Response Control
Customize HTTP responses with ResponseControlConfig:
use symbiont_runtime::http_input::ResponseControlConfig;
let response_control = ResponseControlConfig {
default_status: 200,
agent_output_to_json: true,
error_status: 500,
echo_input_on_error: false,
};
Security Features
Authentication
The HTTP Input module supports multiple authentication methods:
Bearer Token Authentication
Configure a static bearer token:
let config = HttpInputConfig {
auth_header: Some("Bearer your-secret-token".to_string()),
..Default::default()
};
Secret Store Integration
Use secret references for enhanced security:
let config = HttpInputConfig {
auth_header: Some("vault://webhook/auth_token".to_string()),
..Default::default()
};
JWT Authentication (EdDSA)
Configure JWT-based authentication with Ed25519 public keys:
let config = HttpInputConfig {
jwt_public_key_path: Some("/path/to/jwt/ed25519-public.pem".to_string()),
..Default::default()
};
The JWT verifier loads an Ed25519 public key from the specified PEM file and validates incoming Authorization: Bearer <jwt> tokens. Only the EdDSA algorithm is accepted — HS256, RS256, and other algorithms are rejected.
Health Endpoint
The HTTP Input module does not expose its own /health endpoint. Health checks are available via the main HTTP API at /api/v1/health when running symbi up, which starts the full runtime including the API server:
# Health check via the main API server (default port 8080)
curl http://127.0.0.1:8080/api/v1/health
# => {"status": "ok"}
If you need health probes for the HTTP Input server specifically, route your load balancer to the main API health endpoint instead.
Security Controls
- Loopback-Only Default:
bind_addressdefaults to127.0.0.1— the server only accepts local connections unless explicitly configured otherwise - CORS Disabled by Default:
cors_originsdefaults to an empty list, meaning CORS is disabled; add specific origins to enable cross-origin access - Request Size Limits: Configurable maximum body size prevents resource exhaustion
- Concurrency Limits: Built-in semaphore controls concurrent request processing
- Audit Logging: Structured logging of all incoming requests when enabled
- Secret Resolution: Integration with Vault and file-based secret stores
Usage Example
Starting the HTTP Input Server
use symbiont_runtime::http_input::{HttpInputConfig, start_http_input};
use symbiont_runtime::secrets::SecretsConfig;
use std::sync::Arc;
// Configure the HTTP input server
let config = HttpInputConfig {
bind_address: "127.0.0.1".to_string(),
port: 8081,
path: "/webhook".to_string(),
agent: AgentId::from_str("webhook_handler")?,
auth_header: Some("Bearer secret-token".to_string()),
audit_enabled: true,
cors_origins: vec!["https://example.com".to_string()],
..Default::default()
};
// Optional: Configure secrets
let secrets_config = SecretsConfig::default();
// Start the server
start_http_input(config, Some(runtime), Some(secrets_config)).await?;
Example Agent Definition
Create a webhook handler agent in webhook_handler.dsl:
agent webhook_handler(body: JSON) -> Maybe<Alert> {
capabilities = ["http_input", "event_processing", "alerting"]
memory = "ephemeral"
privacy = "strict"
policy webhook_guard {
allow: use("llm") if body.source == "slack" || body.user.ends_with("@company.com")
allow: publish("topic://alerts") if body.type == "security_alert"
audit: all_operations
}
with context = {} {
if body.type == "security_alert" {
alert = {
"summary": body.message,
"source": body.source,
"level": body.severity,
"user": body.user
}
publish("topic://alerts", alert)
return alert
}
return None
}
}
Example HTTP Request
Send a webhook request to trigger the agent:
curl -X POST http://localhost:8081/webhook \
-H "Content-Type: application/json" \
-H "Authorization: Bearer secret-token" \
-d '{
"type": "security_alert",
"message": "Suspicious login detected",
"source": "slack",
"severity": "high",
"user": "admin@company.com"
}'
Expected Response
The server returns a JSON response with the agent’s output:
{
"status": "execution_started",
"agent_id": "webhook_handler",
"timestamp": "2024-01-15T10:30:00Z"
}
Integration Patterns
Webhook Endpoints
Configure different agents for different webhook sources:
let routing_rules = vec![
AgentRoutingRule {
condition: RouteMatch::HeaderEquals("X-GitHub-Event".to_string(), "push".to_string()),
agent: AgentId::from_str("github_push_handler")?,
},
AgentRoutingRule {
condition: RouteMatch::JsonFieldEquals("source".to_string(), "stripe".to_string()),
agent: AgentId::from_str("payment_processor")?,
},
];
API Gateway Integration
Use as a backend service behind an API gateway:
let config = HttpInputConfig {
bind_address: "0.0.0.0".to_string(),
port: 8081,
path: "/api/webhook".to_string(),
cors_origins: vec!["https://example.com".to_string()],
forward_headers: vec![
"X-Forwarded-For".to_string(),
"X-Request-ID".to_string(),
],
..Default::default()
};
Health Check Integration
The HTTP Input module does not include a dedicated health endpoint. Use the main API health endpoint (/api/v1/health) for load balancer and monitoring integration. See the Health Endpoint section above for details.
Error Handling
The HTTP Input module provides comprehensive error handling:
- Authentication Errors: Returns
401 Unauthorizedfor invalid tokens - Rate Limiting: Returns
429 Too Many Requestswhen concurrency limits are exceeded - Payload Errors: Returns
400 Bad Requestfor malformed JSON - Agent Errors: Returns configurable error status with error details
- Server Errors: Returns
500 Internal Server Errorfor runtime failures
Monitoring and Observability
Audit Logging
When audit_enabled is true, the module logs structured information about all requests:
INFO HTTP Input: Received request with 5 headers
INFO Would invoke agent webhook_handler with input data
Metrics Integration
The module integrates with the Symbiont runtime’s metrics system to provide:
- Request count and rate
- Response time distributions
- Error rates by type
- Active connection counts
- Concurrency utilization
Best Practices
- Security: Always use authentication in production environments
- Rate Limiting: Configure appropriate concurrency limits based on your infrastructure
- Monitoring: Enable audit logging and integrate with your monitoring stack
- Error Handling: Configure appropriate error responses for your use case
- Agent Design: Design agents to handle webhook-specific input formats
- Resource Limits: Set reasonable body size limits to prevent resource exhaustion