Bastion

Configuration

Programmatic and YAML configuration for Bastion with hot-reload support.

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 configuration

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

OptionDescription
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 configuration

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: true

YAML configuration is merged with programmatic defaults. Programmatic options that are explicitly set take precedence over YAML values.

Configuration keys reference

Top-level

KeyTypeDefaultDescription
enabledbooltrueEnable or disable the entire gateway
basePathstring"/api"Base URL prefix for all proxied routes

Routes (routes[])

KeyTypeDefaultDescription
pathstring--URL pattern to match (required)
targets[]object--Upstream targets (required, at least one)
targets[].urlstring--Target base URL
targets[].weightint1Relative traffic weight
stripPrefixboolfalseRemove matched prefix before forwarding
protocolstring"http"Proxy protocol: http, websocket, sse, grpc
enabledbooltrueWhether the route is active
loadBalancerstring""Override: round-robin, weighted-round-robin, random, least-connections, consistent-hash
timeoutduration30sOverride: upstream request timeout

Circuit breaker (circuitBreaker)

KeyTypeDefaultDescription
enabledboolfalseEnable circuit breakers
failureThresholdint5Consecutive failures before opening the circuit
resetTimeoutduration30sTime to wait before transitioning from open to half-open

Rate limiting (rateLimiting)

KeyTypeDefaultDescription
enabledboolfalseEnable rate limiting
requestsPerSecfloat641000Token refill rate (requests per second)
burstint100Maximum burst size (token bucket capacity)

Health check (healthCheck)

KeyTypeDefaultDescription
enabledboolfalseEnable active health probes
intervalduration10sTime between health check requests
pathstring"/health"HTTP path to probe on each target
timeoutduration5sHealth check request timeout

Discovery (discovery)

KeyTypeDefaultDescription
enabledboolfalseEnable FARP service discovery
watchModeboolfalseWatch for service registrations/deregistrations in real time
autoPrefixboolfalseAuto-create route prefixes from service names

Dashboard (dashboard)

KeyTypeDefaultDescription
enabledboolfalseEnable the admin dashboard and REST API
basePathstring"/bastion"Base path for dashboard and API routes
realtimeboolfalseEnable WebSocket real-time event stream

Authentication (auth)

KeyTypeDefaultDescription
typestring""Auth type: api-key, bearer, forward-auth
secretstring""Secret or token for validation
headerstring""Header name for API key auth
forwardURLstring""URL for forward-auth delegation

TLS (tls)

KeyTypeDefaultDescription
caCertFilestring""CA certificate for upstream verification
certFilestring""Client certificate for mTLS
keyFilestring""Client key for mTLS
insecureSkipVerifyboolfalseSkip certificate verification (development only)

Retry (retry)

KeyTypeDefaultDescription
maxRetriesint0Maximum retry attempts (0 = disabled)
strategystring"exponential"Backoff strategy: exponential, linear, fixed
baseDelayduration100msInitial delay between retries
maxDelayduration5sMaximum delay cap
jitterboolfalseAdd randomized jitter to delays

Cache (cache)

KeyTypeDefaultDescription
enabledboolfalseEnable response caching
ttlduration5mDefault cache entry time-to-live

Hot-reload behavior

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:

MethodPathDescription
POST/bastion/api/routesCreate a new route
PUT/bastion/api/routes/:idUpdate an existing route
DELETE/bastion/api/routes/:idRemove a route
POST/bastion/api/routes/:id/enableEnable a route
POST/bastion/api/routes/:id/disableDisable 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 overrides

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.

On this page