Update Note: Version v1.0
v1.0 is the first stable release of Goma Gateway, and the point at which the configuration format becomes a compatibility promise. To get there, the configuration keys that were deprecated across the v0.x series have been removed.
Everything removed here has had a supported replacement for at least one minor release, and every v0.x release logged a warning when it encountered one of these keys.
A configuration that still uses a removed key will not start on v1.0. Work through the checklist at the bottom of this page against your current configuration before you upgrade.
Before you upgrade
The fastest way to see what has to change is to run the v1.0 binary's config check against your current file. It reports every removed key at once, with the line, the route or middleware it belongs to, and what to use instead:
goma config check -c /etc/goma/goma.yml
the configuration file "/etc/goma/goma.yml" uses configuration keys removed in v1.0:
line 2: `certificateManager` was removed in v1.0, use `certManager`
line 17, gateway.routes[0] (api): `destination` was removed in v1.0, use `target`
line 18, gateway.routes[0] (api): `disableHostForwarding` was removed in v1.0, use
`security.forwardHostHeaders` (the sense is inverted: disableHostForwarding: true
becomes forwardHostHeaders: false)
The same check runs at startup, so the gateway refuses to start rather than
ignoring a key it no longer understands. Extra-config files — the routes: and
middlewares: files loaded through extraConfig — are checked too.
If you are still on v0.x, its startup logs report the same keys as warnings:
`certificateManager` is deprecated, use `certManager` instead.
Migrate everything either one mentions, confirm the gateway still runs on v0.15 with the migrated configuration, and only then move to v1.0. Every replacement below is already accepted by v0.15, so you can migrate first and roll back safely if you need to.
Removed configuration keys
Gateway TLS: keys
Replaced by certificates (or certsDir to load a whole directory).
- Removed
gateway:
tls:
keys:
- cert: /etc/goma/certs/example.crt
key: /etc/goma/certs/example.key
- Use instead
gateway:
tls:
certificates:
- cert: /etc/goma/certs/example.crt
key: /etc/goma/certs/example.key
See TLS & Let's Encrypt.
Gateway: certificateManager
Renamed to certManager.
- Removed
gateway:
certificateManager:
acme:
email: admin@example.com
- Use instead
gateway:
certManager:
acme:
email: admin@example.com
Gateway: readTimeout, writeTimeout, idleTimeout
Grouped under timeouts.
- Removed
gateway:
readTimeout: 30
writeTimeout: 30
idleTimeout: 60
- Use instead
gateway:
timeouts:
read: 30
write: 30
idle: 60
Gateway: enableMetrics
Moved under monitoring.
# Removed
gateway:
enableMetrics: true
# Use instead
gateway:
monitoring:
enableMetrics: true
Gateway: errorInterceptor
Gateway-level error interception is replaced by the
errorInterceptor middleware, which can
be scoped to the routes that need it.
Gateway: cors
Global CORS is replaced by the
responseHeaders middleware. Apply one
middleware to every route that needs it rather than configuring it once for the
whole gateway.
- Removed
gateway:
cors:
origins:
- https://app.example.com
allowCredentials: true
- Use instead
middlewares:
- name: cors
type: responseHeaders
rule:
cors:
enabled: true
origins:
- https://app.example.com
allowCredentials: true
gateway:
routes:
- name: api
path: /api
target: http://api:8080
middlewares: [cors]
Removed route keys
destination
Renamed to target.
# Removed
routes:
- name: api
destination: http://api:8080
# Use instead
routes:
- name: api
target: http://api:8080
disabled
Replaced by enabled, with the sense inverted.
# Removed
routes:
- name: api
disabled: true
# Use instead
routes:
- name: api
enabled: false
blockCommonExploits
Moved under security.
# Removed
routes:
- name: api
blockCommonExploits: true
# Use instead
routes:
- name: api
security:
enableExploitProtection: true
disableHostForwarding
Replaced by security.forwardHostHeaders, with the sense inverted.
# Removed
routes:
- name: api
disableHostForwarding: true
# Use instead
routes:
- name: api
security:
forwardHostHeaders: false
disableHostForwarding: true becomes forwardHostHeaders: false. Copying the
old value across unchanged reverses the behaviour: the gateway would start
forwarding the Host header you meant to withhold.
insecureSkipVerify and security.tls.SkipVerification
Both are replaced by security.tls.insecureSkipVerify. SkipVerification was
also the only PascalCase key in the configuration; the replacement is
consistently camelCase.
- Removed
routes:
- name: internal
insecureSkipVerify: true # route level
security:
tls:
SkipVerification: true # or here
- Use instead
routes:
- name: internal
security:
tls:
insecureSkipVerify: true
cors
Per-route CORS is replaced by the
responseHeaders middleware, applied to
the route.
- Removed
routes:
- name: api
path: /api
target: http://api:8080
cors:
origins:
- https://app.example.com
allowedHeaders:
- Origin
- Authorization
allowCredentials: true
- Use instead
middlewares:
- name: api-cors
type: responseHeaders
rule:
cors:
enabled: true
origins:
- https://app.example.com
allowedHeaders:
- Origin
- Authorization
allowCredentials: true
routes:
- name: api
path: /api
target: http://api:8080
middlewares: [api-cors]
The headers map inside a cors block is removed with it. Set response headers
with the same middleware's setHeaders.
A route's CORS origins are also what the gateway puts on the error responses it
generates itself — a 405, or a 503 from a backend that is down. Those now come
from the route's responseHeaders policies, so a route with no CORS policy
returns gateway errors without an Access-Control-Allow-Origin, and the browser
hides the status from the caller's JavaScript. Apply the middleware to any route
whose errors a browser needs to read.
errorInterceptor
Per-route error interception is replaced by the
errorInterceptor middleware.
- Removed
routes:
- name: api
path: /api
target: http://api:8080
errorInterceptor:
enabled: true
contentType: application/json
errors:
- statusCode: 404
body: '{"error": "not found"}'
- Use instead
middlewares:
- name: api-errors
type: errorInterceptor
rule:
enabled: true
contentType: application/json
errors:
- statusCode: 404
body: '{"error": "not found"}'
routes:
- name: api
path: /api
target: http://api:8080
middlewares: [api-errors]
Removed middleware keys
jwt / jwtAuth: alg
A single algorithm is replaced by the algorithms list, which lets you accept
more than one and makes the accepted set explicit.
- Removed
rule:
secret: "..."
alg: HS256
- Use instead
rule:
secret: "..."
algorithms: ["HS256"]
Leaving algorithms unset is safe: the gateway falls back to a set scoped to
the key type you configured — HMAC algorithms for a shared secret, asymmetric
ones for a JWKS or public key. Setting it explicitly is still recommended.
jwt / jwtAuth: forwardHeaders
Moved under forward, alongside the newer query and cookies targets.
- Removed
rule:
forwardHeaders:
X-User-Email: email
X-User-Id: sub
- Use instead
rule:
forward:
headers:
X-User-Email: email
X-User-Id: sub
See JWT middleware.
forwardAuth: enableHostForwarding
Renamed to forwardHostHeaders.
# Removed
rule:
enableHostForwarding: true
# Use instead
rule:
forwardHostHeaders: true
forwardAuth: skipInsecureVerify
Renamed to insecureSkipVerify, matching the name Go itself uses and the key
already used on routes.
# Removed
rule:
skipInsecureVerify: true
# Use instead
rule:
insecureSkipVerify: true
errorInterceptor: code and status
Both were older spellings of statusCode, and all three were accepted at once.
- Removed
rule:
errors:
- code: 404
body: "not found"
- status: 500
body: "server error"
- Use instead
rule:
errors:
- statusCode: 404
body: "not found"
- statusCode: 500
body: "server error"
Removed middleware types
type: oauth and type: oauth2
Both were aliases for the OpenID Connect middleware. Use type: oidc.
- Removed
middlewares:
- name: sso
type: oauth
rule:
clientId: "..."
- Use instead
middlewares:
- name: sso
type: oidc
rule:
clientId: "..."
See OpenID Connect for the full option set, and
migrating from type: oauth.
Removed OIDC keys
The OIDC middleware gained a session model and PKCE during v0.x, which made four of its original keys redundant.
| Removed | Replacement |
|---|---|
redirectUrl | callbackPath — the full URL is derived from the incoming request. |
redirectPath | postLoginRedirect |
cookiePath | session.cookie.path |
state | None. The state parameter is now random per login. |
- Removed
rule:
clientId: "..."
clientSecret: "..."
redirectUrl: "https://example.com/callback"
redirectPath: "/dashboard"
cookiePath: "/"
state: "a-fixed-string"
- Use instead
rule:
clientId: "..."
clientSecret: "..."
callbackPath: "/callback"
postLoginRedirect: "/dashboard"
session:
cookie:
path: "/"
state was a security weaknessA fixed state value defeats the purpose of the parameter, which exists to bind
an authorization response to the browser session that started it. v1.0 generates
a fresh random value per login and ignores any configured one. If your
configuration sets state, simply delete the key.
Removed metrics
Three metric names carried over from before the gateway_ prefix was
introduced. Each has had an identically-labelled replacement for several
releases, and both were exported side by side until now.
| Removed | Replacement |
|---|---|
http_requests_total | gateway_requests_total |
http_response_status_total | gateway_response_status_total |
http_request_duration_seconds | gateway_request_duration_seconds |
Unlike a configuration key, nothing warns you about these: a dashboard panel or
an alert rule still querying the old name simply goes empty. Grep your
dashboards, recording rules and alert rules for http_requests_total,
http_response_status_total and http_request_duration_seconds before
upgrading. The labels are unchanged, so the rest of each query stands.
Checklist
-
goma config check -c <file>passes on v0.15 - v0.15 startup logs show no deprecation warnings
Gateway
-
tls.keys→tls.certificates/tls.certsDir -
certificateManager→certManager -
readTimeout/writeTimeout/idleTimeout→timeouts.* -
enableMetrics→monitoring.enableMetrics - gateway-level
errorInterceptor→errorInterceptormiddleware - gateway-level
cors→ aresponseHeadersmiddleware per route
Routes
-
destination→target -
disabled: true→enabled: false -
blockCommonExploits→security.enableExploitProtection -
disableHostForwarding: true→security.forwardHostHeaders: false(inverted) -
insecureSkipVerify/security.tls.SkipVerification→security.tls.insecureSkipVerify - route
cors→ aresponseHeadersmiddleware on the route - route
errorInterceptor→ anerrorInterceptormiddleware on the route
Middlewares
- JWT
alg→algorithms - JWT
forwardHeaders→forward.headers -
forwardAuthenableHostForwarding→forwardHostHeaders -
forwardAuthskipInsecureVerify→insecureSkipVerify -
type: oauth/type: oauth2→type: oidc - OIDC
redirectUrl→callbackPath - OIDC
redirectPath→postLoginRedirect - OIDC
cookiePath→session.cookie.path - OIDC
statedeleted -
errorInterceptorcode/status→statusCode
Metrics
- dashboards and alerts moved off
http_requests_total,http_response_status_totalandhttp_request_duration_seconds
Finally
- Gateway starts cleanly and routes resolve as expected