a3s-gateway 0.2.2

A3S Gateway - AI-native API gateway with reverse proxy, routing, and agent orchestration
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# A3S Gateway

<p align="center">
  <strong>AI-Native API Gateway & Reverse Proxy</strong>
</p>

<p align="center">
  <em>HCL-configured traffic routing — TLS termination, 15 middlewares, Knative-style autoscaling, hot reload, Helm deployment.</em>
</p>

<p align="center">
  <a href="#quick-start">Quick Start</a><a href="#features">Features</a><a href="#configuration">Configuration</a><a href="#architecture">Architecture</a><a href="#deployment">Deployment</a><a href="#api-reference">API Reference</a><a href="#development">Development</a>
</p>

---

**A3S Gateway** is an application-agnostic reverse proxy built for the A3S ecosystem. It uses HCL (HashiCorp Configuration Language) for configuration, speaks Traefik's routing DSL, terminates TLS, enforces middleware policies, and forwards traffic to any HTTP/gRPC/TCP/UDP backend.

**872 tests** | **69 source files** | **~26,000 lines of Rust**

## Quick Start

```bash
# Start with HCL config
a3s-gateway --config gateway.hcl

# Debug logging
a3s-gateway --config gateway.hcl --log-level debug

# Validate config
a3s-gateway validate --config gateway.hcl
```

```hcl
# gateway.hcl — minimal reverse proxy
entrypoints "web" {
  address = "0.0.0.0:8080"
}

routers "api" {
  rule    = "PathPrefix(`/api`)"
  service = "backend"
}

services "backend" {
  load_balancer {
    strategy = "round-robin"
    servers  = [{ url = "http://127.0.0.1:8001" }]
  }
}
```

### Programmatic

```rust
use a3s_gateway::{Gateway, config::GatewayConfig};
use std::sync::Arc;

#[tokio::main]
async fn main() -> a3s_gateway::Result<()> {
    let config = GatewayConfig::from_file("gateway.hcl").await?;
    let gateway = Arc::new(Gateway::new(config)?);
    gateway.start().await?;
    gateway.wait_for_shutdown().await;
    Ok(())
}
```

## Features

### Core Proxy
- **Dynamic Routing**: Traefik-style rule engine (`Host()`, `PathPrefix()`, `Path()`, `Headers()`, `Method()`, `&&`)
- **Load Balancing**: Round-robin, weighted, least-connections, random
- **Health Checks**: Active HTTP probes + passive error-count removal
- **TLS Termination**: rustls with ACME/Let's Encrypt (HTTP-01 + DNS-01/Cloudflare + DNS-01/Route53)
- **Hot Reload**: File-watch config reload (inotify/kqueue) without restart
- **Sticky Sessions**: Cookie-based backend affinity with TTL and eviction
- **Traffic Mirroring**: Copy a percentage of live traffic to a shadow service
- **Failover**: Automatic fallback to secondary backend pool
- **Dashboard API**: Built-in `/health`, `/metrics`, `/config` endpoints

### Protocols
- HTTP/1.1 & HTTP/2, WebSocket, SSE/Streaming, gRPC (h2c), TCP, UDP
- **TCP SNI Router**: ClientHello SNI extraction with `HostSNI()` matching
- **WebSocket Multiplexing**: Named channel pub/sub over a single connection

### Middlewares (15 built-in)

| Type | Config Keys | Description |
|------|-------------|-------------|
| `api-key` | `header`, `keys` | API key validation |
| `basic-auth` | `username`, `password` | HTTP Basic authentication |
| `jwt` | `value` | JWT validation (HS256) |
| `forward-auth` | `forward_auth_url`, `forward_auth_response_headers` | Delegate auth to external IdP |
| `rate-limit` | `rate`, `burst` | Token bucket (in-memory) |
| `rate-limit-redis` | `rate`, `burst`, `redis_url` | Distributed rate limiting (`redis` feature) |
| `cors` | `allowed_origins`, `allowed_methods`, `allowed_headers` | CORS headers |
| `headers` | `request_headers`, `response_headers` | Header manipulation |
| `strip-prefix` | `prefixes` | Path prefix removal |
| `body-limit` | `max_body_bytes` | Max request body size (413 on exceed) |
| `retry` | `max_retries`, `retry_interval_ms` | Retry on failure |
| `circuit-breaker` | `failure_threshold`, `cooldown_secs`, `success_threshold` | Closed/Open/HalfOpen state machine |
| `ip-allow` | `allowed_ips` | CIDR/IP allowlist |
| `compress` || brotli/gzip/deflate (br preferred) |
| `tcp-filter` || In-flight connection limit + IP allowlist for TCP |

### Observability
- **Prometheus Metrics**: Per-router/service/middleware request counts, latency, errors
- **Structured Access Log**: JSON entries with duration, backend, router
- **Distributed Tracing**: W3C Trace Context and B3/Zipkin propagation

### Service Discovery
- **File Provider**: HCL with file watching and hot reload
- **DNS Provider**: Hostname resolution with caching
- **Health-based Discovery**: Auto-register backends via `/.well-known/a3s-service.json`
- **Kubernetes Ingress**: Watch K8s `networking.k8s.io/v1/Ingress` resources (feature `kube`)
- **Kubernetes IngressRoute CRD**: Advanced routing with Traefik-style rules (feature `kube`)

### Knative-Style Autoscaling (Optional)
- Autoscaler decision engine: Knative formula, min/max replicas, scale-down cooldown
- Scale-from-zero request buffering during cold starts
- Per-instance concurrency limit (`containerConcurrency`) with least-loaded selection
- Revision-based traffic splitting and gradual canary rollout with auto-rollback
- Pluggable `ScaleExecutor`: `BoxScaleExecutor` (HTTP), `K8sScaleExecutor` (kube-rs), `MockScaleExecutor`

## Configuration

All configuration uses HCL format (`.hcl` files).

```hcl
# Entrypoints — network listeners
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"
  }
}

entrypoints "tcp-db" {
  address         = "0.0.0.0:5432"
  protocol        = "tcp"
  max_connections  = 100
  tcp_allowed_ips  = ["10.0.0.0/8"]
}

# Routers — request matching
routers "api" {
  rule        = "Host(`api.example.com`) && PathPrefix(`/v1`)"
  service     = "api-service"
  entrypoints = ["websecure"]
  middlewares  = ["auth-jwt", "rate-limit"]
}

# Services — backend pools
services "api-service" {
  load_balancer {
    strategy = "round-robin"
    servers  = [
      { url = "http://127.0.0.1:8001" },
      { url = "http://127.0.0.1:8002" }
    ]
    health_check {
      path     = "/health"
      interval = "10s"
    }
    sticky {
      cookie = "srv_id"
    }
  }

  # Traffic mirroring (optional)
  mirror {
    service    = "shadow-backend"
    percentage = 10
  }

  # Failover (optional)
  failover {
    service = "backup-pool"
  }

  # Autoscaling (optional)
  scaling {
    min_replicas          = 0
    max_replicas          = 10
    container_concurrency = 50
    target_utilization    = 0.7
    buffer_enabled        = true
    executor              = "box"
  }

  # Revision traffic splitting (optional)
  revisions = [
    { name = "v1", traffic_percent = 90, strategy = "round-robin",
      servers = [{ url = "http://127.0.0.1:8001" }] },
    { name = "v2", traffic_percent = 10, strategy = "round-robin",
      servers = [{ url = "http://127.0.0.1:8003" }] }
  ]

  # Gradual rollout (optional)
  rollout {
    from                 = "v1"
    to                   = "v2"
    step_percent         = 10
    step_interval_secs   = 60
    error_rate_threshold = 0.05
    latency_threshold_ms = 5000
  }
}

# Middlewares
middlewares "auth-jwt" {
  type  = "jwt"
  value = "${JWT_SECRET}"
}

middlewares "rate-limit" {
  type  = "rate-limit"
  rate  = 100
  burst = 50
}

# Providers
providers {
  file {
    watch     = true
    directory = "/etc/gateway/conf.d/"
  }
  discovery {
    poll_interval_secs = 30
    seeds = [
      { url = "http://10.0.0.5:8080" },
      { url = "http://10.0.0.6:8080" }
    ]
  }
}
```

### Service Discovery Contract

Backends expose `/.well-known/a3s-service.json` (RFC 8615) for automatic registration:

```json
{
  "name": "auth-service",
  "version": "1.2.0",
  "routes": [
    { "rule": "PathPrefix(`/auth`)", "middlewares": ["rate-limit"] }
  ],
  "health_path": "/health",
  "weight": 1
}
```

## Architecture

```
                    ┌─────────────────────────────────────────────┐
                    │              A3S Gateway                     │
                    │                                             │
  Client ──────────┤  Entrypoint (HTTP/HTTPS/TCP/UDP)            │
  (HTTP/WS/gRPC)   │      │                                     │
                    │      ▼                                     │
                    │  TLS Termination (rustls + ACME)           │
                    │      │                                     │
                    │      ▼                                     │
                    │  Router ──── Rule Matching                 │
                    │      │       (host, path, headers, SNI)    │
                    │      ▼                                     │
                    │  Middleware Pipeline (15 built-in)          │
                    │  ┌─────┬──────┬───────┬──────────┐       │
                    │  │Auth │Rate  │Retry  │Circuit   │       │
                    │  │JWT  │Limit │CORS   │Breaker   │       │
                    │  └─────┴──────┴───────┴──────────┘       │
                    │      │                                     │
                    │      ▼                                     │
                    │  Load Balancer + Sticky Sessions           │
                    │  (round-robin / weighted / least-conn)     │
                    │      │                                     │
                    └──────┼─────────────────────────────────────┘
              ┌────────────┼────────────┐
              ▼            ▼            ▼
         ┌────────┐  ┌────────┐  ┌──────────┐
         │HTTP    │  │gRPC    │  │TCP/UDP   │
         │Backend │  │Backend │  │Backend   │
         └────────┘  └────────┘  └──────────┘
```

### Core Components

| Component | Description |
|-----------|-------------|
| `Gateway` | Top-level orchestrator with lifecycle management |
| `Entrypoint` | Listener on a port (HTTP, HTTPS, TCP, UDP) |
| `Router` | Matches requests by rules (`Host()`, `PathPrefix()`, `HostSNI()`) |
| `Middleware` | Composable request/response pipeline (15 types) |
| `Service` | Backend pool with LB, health checks, mirroring, failover |
| `Provider` | Dynamic config sources (file, DNS, discovery, K8s) |
| `Proxy` | Request forwarding (HTTP, WebSocket, gRPC, TCP, UDP, SSE) |
| `Scaling` | Knative-style autoscaler with revision traffic splitting |

## Deployment

### Helm (Kubernetes)

```bash
# Install
helm install gateway deploy/helm/a3s-gateway

# Custom config
helm install gateway deploy/helm/a3s-gateway \
  --set-file config=my-gateway.hcl \
  --set service.type=LoadBalancer

# With autoscaling
helm install gateway deploy/helm/a3s-gateway \
  --set autoscaling.enabled=true \
  --set autoscaling.maxReplicas=10

# With ingress
helm install gateway deploy/helm/a3s-gateway \
  --set ingress.enabled=true \
  --set ingress.hosts[0].host=api.example.com
```

### Docker

```bash
docker run -v $(pwd)/gateway.hcl:/etc/a3s-gateway/gateway.hcl \
  -p 8080:8080 ghcr.io/a3s-lab/gateway:latest
```

## API Reference

### Gateway

| Method | Description |
|--------|-------------|
| `Gateway::new(config)` | Create from configuration |
| `start()` | Start listening and proxying |
| `shutdown()` | Graceful shutdown |
| `reload(new_config)` | Hot reload without downtime |
| `health()` | Health status snapshot |
| `metrics()` | Metrics collector |
| `config()` | Current configuration |
| `state()` | Runtime state |

### Dashboard API

| Endpoint | Description |
|----------|-------------|
| `GET /api/gateway/health` | Health status (JSON) |
| `GET /api/gateway/metrics` | Prometheus metrics (text) |
| `GET /api/gateway/config` | Current configuration (JSON) |

## Development

```bash
cargo build -p a3s-gateway
cargo test -p a3s-gateway                  # 872 tests
cargo build -p a3s-gateway --all-features  # includes Redis + K8s
cargo clippy -p a3s-gateway
```

### Project Structure

```
src/
├── lib.rs, main.rs          # Public API + CLI
├── gateway.rs               # Orchestrator
├── dashboard.rs             # Dashboard API types
├── entrypoint.rs            # HTTP/HTTPS/TCP/UDP listeners
├── error.rs                 # GatewayError and Result
│
├── config/                  # Configuration model (HCL)
│   ├── entrypoint.rs, router.rs, service.rs
│   ├── scaling.rs, middleware.rs
│
├── router/                  # Rule matching
│   ├── rule.rs              # Host/Path/Header/Method engine
│   └── tcp.rs               # TCP SNI router
│
├── middleware/              # 15 built-in middlewares
│   ├── auth.rs, jwt_auth.rs, forward_auth.rs
│   ├── rate_limit.rs, rate_limit_redis.rs
│   ├── cors.rs, headers.rs, strip_prefix.rs
│   ├── body_limit.rs, retry.rs, circuit_breaker.rs
│   ├── ip_allow.rs, ip_matcher.rs, tcp_filter.rs
│   └── compress.rs
│
├── service/                 # Backend management
│   ├── load_balancer.rs, health_check.rs, passive_health.rs
│   ├── sticky.rs, mirror.rs, failover.rs
│
├── proxy/                   # Request forwarding
│   ├── http_proxy.rs, websocket.rs, streaming.rs
│   ├── grpc.rs, tcp.rs, udp.rs, tls.rs
│   ├── acme.rs, acme_client.rs, acme_manager.rs, acme_dns.rs
│   └── ws_mux.rs
│
├── observability/
│   ├── metrics.rs, access_log.rs, tracing.rs
│
├── scaling/                 # Knative-style autoscaling
│   ├── executor.rs, autoscaler.rs, buffer.rs
│   ├── concurrency.rs, revision.rs, rollout.rs
│
└── provider/                # Config providers
    ├── file_watcher.rs, dns.rs, discovery.rs
    ├── kubernetes.rs, kubernetes_crd.rs  (feature `kube`)

deploy/
└── helm/a3s-gateway/        # Helm chart for Kubernetes
```

## Community

Join us on [Discord](https://discord.gg/XVg6Hu6H) for questions, discussions, and updates.

## License

MIT