Bastion can be configured programmatically via option functions, declaratively via YAML/JSON configuration files, or through a combination of both. Configuration changes can be applied at runtime without restarting the gateway.
Programmatic configuration01
Bastion uses the functional options pattern. Options are passed to bastion.NewExtension:
bastion.NewExtension(
bastion.WithBasePath("/api"),
bastion.WithRoute(bastion.RouteConfig{
Path: "/users/*",
Targets: []bastion.TargetConfig{
{URL: "http://user-service:8080", Weight: 1},
},
StripPrefix: true,
Protocol: bastion.ProtocolHTTP,
Enabled: true,
}),
bastion.WithCircuitBreaker(bastion.CircuitBreakerConfig{
Enabled: true,
FailureThreshold: 5,
ResetTimeout: 30 * time.Second,
}),
bastion.WithRateLimiting(bastion.RateLimitConfig{
Enabled: true,
RequestsPerSec: 1000,
Burst: 100,
}),
bastion.WithHealthCheck(bastion.HealthCheckConfig{
Enabled: true,
Interval: 10 * time.Second,
Path: "/health",
}),
bastion.WithDiscovery(bastion.DiscoveryConfig{
Enabled: true,
WatchMode: true,
AutoPrefix: true,
}),
bastion.WithDashboard(bastion.DashboardConfig{
Enabled: true,
BasePath: "/bastion",
Realtime: true,
}),
)Available option functions
| Option | Description |
WithBasePath(path) | Sets the base URL prefix for all gateway routes (default: "/api") |
WithRoute(cfg) | Adds a static route. Can be called multiple times. |
WithCircuitBreaker(cfg) | Configures global circuit breaker settings |
WithRateLimiting(cfg) | Configures global rate limiting |
WithHealthCheck(cfg) | Configures active health checking |
WithDiscovery(cfg) | Configures FARP service discovery integration |
WithDashboard(cfg) | Enables the admin dashboard and REST API |
WithTLS(cfg) | Configures default upstream TLS settings |
WithCORS(cfg) | Configures CORS headers |
WithIPFilter(cfg) | Configures IP allow/deny lists |
WithAuth(cfg) | Configures global authentication |
WithCache(cfg) | Configures global response caching |
WithRetry(cfg) | Configures global retry policy |
WithTimeout(d) | Sets the global upstream request timeout |
WithLogger(l) | Sets the structured logger (*slog.Logger) |
YAML configuration02
Bastion reads configuration from Forge YAML config files under the bastion key:
bastion:
enabled: true
basePath: "/api"
routes:
- path: "/users/*"
targets:
- url: "http://user-service:8080"
weight: 1
stripPrefix: true
protocol: http
enabled: true
- path: "/orders/*"
targets:
- url: "http://order-service:8080"
weight: 1
stripPrefix: true
protocol: http
enabled: true
circuitBreaker:
enabled: true
failureThreshold: 5
resetTimeout: 30s
rateLimiting:
enabled: true
requestsPerSec: 1000
burst: 100
healthCheck:
enabled: true
interval: 10s
path: "/health"
timeout: 5s
discovery:
enabled: true
watchMode: true
autoPrefix: true
dashboard:
enabled: true
basePath: "/bastion"
realtime: trueYAML configuration is merged with programmatic defaults. Programmatic options that are explicitly set take precedence over YAML values.
Configuration keys reference03
Top-level
| Key | Type | Default | Description |
enabled | bool | true | Enable or disable the entire gateway |
basePath | string | "/api" | Base URL prefix for all proxied routes |
Routes (routes[])
| Key | Type | Default | Description |
path | string | -- | URL pattern to match (required) |
targets | []object | -- | Upstream targets (required, at least one) |
targets[].url | string | -- | Target base URL |
targets[].weight | int | 1 | Relative traffic weight |
stripPrefix | bool | false | Remove matched prefix before forwarding |
protocol | string | "http" | Proxy protocol: http, websocket, sse, grpc |
enabled | bool | true | Whether the route is active |
loadBalancer | string | "" | Override: round-robin, weighted-round-robin, random, least-connections, consistent-hash |
timeout | duration | 30s | Override: upstream request timeout |
Circuit breaker (circuitBreaker)
| Key | Type | Default | Description |
enabled | bool | false | Enable circuit breakers |
failureThreshold | int | 5 | Consecutive failures before opening the circuit |
resetTimeout | duration | 30s | Time to wait before transitioning from open to half-open |
Rate limiting (rateLimiting)
| Key | Type | Default | Description |
enabled | bool | false | Enable rate limiting |
requestsPerSec | float64 | 1000 | Token refill rate (requests per second) |
burst | int | 100 | Maximum burst size (token bucket capacity) |
Health check (healthCheck)
| Key | Type | Default | Description |
enabled | bool | false | Enable active health probes |
interval | duration | 10s | Time between health check requests |
path | string | "/health" | HTTP path to probe on each target |
timeout | duration | 5s | Health check request timeout |
Discovery (discovery)
| Key | Type | Default | Description |
enabled | bool | false | Enable FARP service discovery |
watchMode | bool | false | Watch for service registrations/deregistrations in real time |
autoPrefix | bool | false | Auto-create route prefixes from service names |
Dashboard (dashboard)
| Key | Type | Default | Description |
enabled | bool | false | Enable the admin dashboard and REST API |
basePath | string | "/bastion" | Base path for dashboard and API routes |
realtime | bool | false | Enable WebSocket real-time event stream |
Authentication (auth)
| Key | Type | Default | Description |
type | string | "" | Auth type: api-key, bearer, forward-auth |
secret | string | "" | Secret or token for validation |
header | string | "" | Header name for API key auth |
forwardURL | string | "" | URL for forward-auth delegation |
TLS (tls)
| Key | Type | Default | Description |
caCertFile | string | "" | CA certificate for upstream verification |
certFile | string | "" | Client certificate for mTLS |
keyFile | string | "" | Client key for mTLS |
insecureSkipVerify | bool | false | Skip certificate verification (development only) |
Retry (retry)
| Key | Type | Default | Description |
maxRetries | int | 0 | Maximum retry attempts (0 = disabled) |
strategy | string | "exponential" | Backoff strategy: exponential, linear, fixed |
baseDelay | duration | 100ms | Initial delay between retries |
maxDelay | duration | 5s | Maximum delay cap |
jitter | bool | false | Add randomized jitter to delays |
Cache (cache)
| Key | Type | Default | Description |
enabled | bool | false | Enable response caching |
ttl | duration | 5m | Default cache entry time-to-live |
Hot-reload behavior04
Bastion supports hot-reloading of configuration changes without restarting the gateway process. There are two mechanisms:
File watcher
When the Forge configuration file changes on disk, Bastion detects the change and reloads:
Route additions and removals -- New routes are added to the route table; removed routes stop accepting traffic
Target changes -- New targets are added to the load balancer pool; removed targets are drained
Rate limit changes -- Token bucket parameters are updated immediately
Circuit breaker changes -- Thresholds are updated; existing circuit states are preserved
Health check changes -- Interval and path changes take effect on the next probe cycle
Admin API
The admin REST API provides runtime configuration changes:
| Method | Path | Description |
POST | /bastion/api/routes | Create a new route |
PUT | /bastion/api/routes/:id | Update an existing route |
DELETE | /bastion/api/routes/:id | Remove a route |
POST | /bastion/api/routes/:id/enable | Enable a route |
POST | /bastion/api/routes/:id/disable | Disable a route |
Changes made through the admin API take effect immediately and are reflected in the running configuration.
What does not hot-reload
Some settings require a restart to take effect:
basePath(the gateway base URL prefix)dashboard.basePath(the admin dashboard prefix)TLS certificate file paths (though certificate contents are reloaded automatically when the files change)
Per-route config overrides05
Many global settings can be overridden at the route level. Route-level settings take precedence over global settings.
bastion:
rateLimiting:
enabled: true
requestsPerSec: 1000
burst: 100
routes:
- path: "/uploads/*"
targets:
- url: "http://upload-service:8080"
rateLimit:
enabled: true
requestsPerSec: 10 # stricter limit for uploads
burst: 5
- path: "/api/*"
targets:
- url: "http://api-service:8080"
# inherits the global rate limit (1000 req/s)Overridable settings: rateLimit, loadBalancer, auth, cache, timeout, retryPolicy.