A3S Gateway
Quick Start
Get A3S Gateway running with a basic reverse proxy configuration
Quick Start
Minimal Configuration
Create a gateway.acl file with an entrypoint, a router, and a service:
entrypoints "web" {
address = "0.0.0.0:80"
}
routers "my-api" {
rule = "PathPrefix(`/api`)"
service = "api-backend"
entrypoints = ["web"]
}
services "api-backend" {
load_balancer {
strategy = "round-robin"
servers = [{ url = "http://127.0.0.1:8001" }]
}
}Start the Gateway
# Start with ACL config
a3s-gateway --config gateway.acl
# Start with debug logging
a3s-gateway --config gateway.acl --log-level debug
# Validate configuration without starting
a3s-gateway validate --config gateway.aclAdd HTTPS
entrypoints "web" {
address = "0.0.0.0:80"
}
entrypoints "websecure" {
address = "0.0.0.0:443"
tls {
cert_file = "/etc/certs/cert.pem"
key_file = "/etc/certs/key.pem"
}
}
routers "my-api" {
rule = "Host(`api.example.com`) && PathPrefix(`/v1`)"
service = "api-backend"
entrypoints = ["websecure"]
}
services "api-backend" {
load_balancer {
strategy = "round-robin"
servers = [{ url = "http://127.0.0.1:8001" }]
}
}Add Middleware
entrypoints "websecure" {
address = "0.0.0.0:443"
tls {
cert_file = "/etc/certs/cert.pem"
key_file = "/etc/certs/key.pem"
}
}
routers "my-api" {
rule = "Host(`api.example.com`)"
service = "api-backend"
entrypoints = ["websecure"]
middlewares = ["auth", "rate-limit"]
}
middlewares "auth" {
type = "jwt"
value = "my-jwt-secret"
}
middlewares "rate-limit" {
type = "rate-limit"
rate = 100
burst = 50
}
services "api-backend" {
load_balancer {
strategy = "round-robin"
servers = [
{ url = "http://127.0.0.1:8001" },
{ url = "http://127.0.0.1:8002" },
]
}
}Health Check
services "api-backend" {
load_balancer {
strategy = "least-connections"
servers = [
{ url = "http://127.0.0.1:8001" },
{ url = "http://127.0.0.1:8002" },
]
health_check {
path = "/health"
interval = "10s"
timeout = "5s"
unhealthy_threshold = 3
healthy_threshold = 1
}
}
}Management
Gateway management is CLI-first by default. If you need remote inspection for a
console or operator, enable the Dashboard API on a dedicated listener. It does
not reserve /api/gateway/* on traffic entrypoints.
a3s-gateway validate --config gateway.acl
a3s-gateway config --config gateway.acl summary
a3s-gateway config --config gateway.acl entrypoints
a3s-gateway config --config gateway.acl routes
a3s-gateway config --config gateway.acl services
a3s-gateway config --config gateway.acl middlewares
a3s-gateway config --config gateway.acl providers
a3s-gateway config --config gateway.acl json
a3s-gateway management events --url http://127.0.0.1:9090/api/gateway
a3s-gateway management validate --url http://127.0.0.1:9090/api/gateway --file gateway.acl
a3s-gateway management reload --url http://127.0.0.1:9090/api/gateway --file gateway.aclmanagement {
enabled = true
address = "127.0.0.1:9090"
path_prefix = "/api/gateway"
auth_token_env = "A3S_GATEWAY_ADMIN_TOKEN"
allowed_ips = ["127.0.0.1", "::1"]
tls {
cert_file = "/etc/a3s/admin/server.crt"
key_file = "/etc/a3s/admin/server.key"
client_ca_file = "/etc/a3s/admin/client-ca.crt"
require_client_cert = true
}
}Programmatic Usage
use a3s_gateway::{Gateway, config::GatewayConfig};
#[tokio::main]
async fn main() -> a3s_gateway::Result<()> {
let config = GatewayConfig::from_file("gateway.acl").await?;
let gateway = Gateway::new(config)?;
gateway.start().await?;
// Check health
let health = gateway.health();
println!("State: {:?}, Uptime: {}s", health.state, health.uptime_secs);
// Wait for shutdown signal
gateway.wait_for_shutdown().await;
Ok(())
}