A3S Docs
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.acl

Add 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.acl
management {
  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(())
}

On this page