-
Notifications
You must be signed in to change notification settings - Fork 45
Description
Discussed in #633
Originally posted by renuka-fernando January 6, 2026
Summary
This proposal discusses migrating our gateway configuration from YAML to TOML format. The primary motivation is to improve configuration maintainability and reduce indentation-related errors.
Current State
Our configuration file (gateway/configs/config.yaml) is a 364-line YAML file with deep nesting (up to 4-5 levels). Key sections include:
gateway_controller.servergateway_controller.policyserver.tlsgateway_controller.router.downstream_tlsgateway_controller.router.policy_engine.tlspolicy_engine.xds.tlsanalytics.publishers[].settings
Problems with Current YAML Configuration
1. Indentation Sensitivity
YAML's strict indentation requirements make configuration error-prone. A single misaligned space can cause:
- Silent parsing failures
- Unexpected configuration merging
- Hard-to-debug runtime errors
Example from our config:
gateway_controller:
router:
policy_engine:
tls:
enabled: false
cert_path: "" # Must be exactly 8 spaces
key_path: "" # One wrong space = broken config2. Copy-Paste Friction
When adding new configuration sections, users must:
- Find the correct location in the hierarchy
- Calculate the exact indentation level
- Carefully paste while preserving whitespace
- Manually adjust if the source had different indentation
This is particularly problematic when copying configuration examples from documentation.
3. Implicit Type Conversion
YAML silently converts values based on content, which can cause unexpected behavior:
# These are interpreted differently:
port: 9090 # Integer
port: "9090" # String
enabled: yes # Boolean (true)
enabled: "yes" # String
version: 1.0 # Float
version: "1.0" # StringOur config has several values that could be misinterpreted (ports, timeouts, versions).
4. Deep Nesting Becomes Unreadable
Current nesting example:
gateway_controller:
router:
envoy_upstream:
tls:
minimum_protocol_version: TLS1_2
maximum_protocol_version: TLS1_3
ciphers: "ECDHE-ECDSA-AES128..."Users must trace 4 levels of indentation to understand the context.
Proposed Solution: TOML
What is TOML?
TOML (Tom's Obvious, Minimal Language) is a configuration format designed to be:
- Simple and readable
- Predictable (no whitespace sensitivity)
- Explicit (clear type definitions)
It's used by modern tools including Cargo (Rust), pyproject.toml (Python), Hugo, and many Go projects.
Benefits of TOML
1. Indentation Independence
Copy-paste anywhere - Users can add configuration sections without worrying about indentation:
[gateway_controller.router.policy_engine.tls]
enabled = false
cert_path = ""
key_path = ""
ca_path = ""Indentation is purely cosmetic and ignored by the parser.
2. Explicit Section Headers
Clear visual separation between configuration sections:
[gateway_controller.server]
api_port = 9090
xds_port = 18000
shutdown_timeout = "15s"
[gateway_controller.policyserver]
enabled = true
port = 18001
[gateway_controller.policyserver.tls]
enabled = false
cert_file = "./certs/server.crt"
key_file = "./certs/server.key"3. Type Safety
TOML requires explicit syntax for types:
port = 9090 # Always integer
port_str = "9090" # Always string
enabled = true # Always boolean (no "yes"/"no" ambiguity)
timeout = "15s" # Always string4. Easier Navigation
Section headers act as natural anchors. Users can search for [gateway_controller.router.policy_engine] directly instead of counting indentation levels.
5. Better Tooling Support
- Most modern editors have TOML syntax highlighting
- Go has excellent TOML libraries (
github.com/BurntSushi/toml,github.com/pelletier/go-toml) - IDE schema validation works well with TOML
Example: Current YAML vs Proposed TOML
Current YAML:
gateway_controller:
server:
api_port: 9090
xds_port: 18000
shutdown_timeout: 15s
policyserver:
enabled: true
port: 18001
tls:
enabled: false
cert_file: "./certs/server.crt"
key_file: "./certs/server.key"
router:
gateway_host: "*"
listener_port: 8080
https_enabled: true
https_port: 8443
downstream_tls:
cert_path: "./listener-certs/default-listener.crt"
key_path: "./listener-certs/default-listener.key"
minimum_protocol_version: TLS1_2
maximum_protocol_version: TLS1_3Proposed TOML:
[gateway_controller.server]
api_port = 9090
xds_port = 18000
shutdown_timeout = "15s"
[gateway_controller.policyserver]
enabled = true
port = 18001
[gateway_controller.policyserver.tls]
enabled = false
cert_file = "./certs/server.crt"
key_file = "./certs/server.key"
[gateway_controller.router]
gateway_host = "*"
listener_port = 8080
https_enabled = true
https_port = 8443
[gateway_controller.router.downstream_tls]
cert_path = "./listener-certs/default-listener.crt"
key_path = "./listener-certs/default-listener.key"
minimum_protocol_version = "TLS1_2"
maximum_protocol_version = "TLS1_3"Handling Arrays (e.g., Publishers)
Current YAML:
analytics:
publishers:
- type: moesif
enabled: true
settings:
application_id: <MOESIF_APPLICATION_ID>
publish_interval: 5Proposed TOML:
[[analytics.publishers]]
type = "moesif"
enabled = true
[analytics.publishers.settings]
application_id = "<MOESIF_APPLICATION_ID>"
publish_interval = 5Considerations
Potential Drawbacks
| Concern | Mitigation |
|---|---|
| Less common in cloud-native ecosystem (K8s uses YAML) | We're not Kubernetes; our config is for our own services |
| Team familiarity with YAML | TOML has simpler spec; learning curve is minimal |
| Arrays look more verbose | Trade-off for clarity and reduced errors |
Implementation Notes
- Go configuration libraries (Viper, Koanf) support TOML natively
- We already use Koanf which has TOML support via
koanf/parsers/toml - Schema validation can be maintained with struct tags