Skip to content

Readiness reports UP while every BFF path returns 500 — the discovery client is not covered #174

Description

@OliverWolffGIP

Summary

/q/health reports UP — including jwks: ready and issuer_reachability: reachable — on an
instance where every BFF path answers 500. The readiness check exercises the JWKS loader but not
the OIDC discovery client, and the BFF depends on the latter.

An operator deploying this sees green and reasonably concludes the gateway works.

Observed

Same instance, same minute:

$ curl -sk https://localhost:9000/q/health
{
    "status": "UP",
    "checks": [{
        "name": "gateway-readiness",
        "status": "UP",
        "data": {
            "config": "loaded",
            "oidc": "server",
            "issuers": 1,
            "jwks": "ready",
            "issuer_reachability": "reachable"
        }
    }]
}
$ curl -sk -o /dev/null -w '%{http_code}\n' https://gw:8443/auth/login?returnUrl=/gateway/landing.html
500
$ curl -sk -o /dev/null -w '%{http_code}\n' https://gw:8443/auth/logout
500

Both failures come from the same place:

SEVERE [de.cuioss.sheriff.token.client.discovery.DiscoveryResolver] OIDC discovery failed for issuer ...
	at de.cuioss.sheriff.gateway.bff.login.LoginFlow.initiate(LoginFlow.java:98)

Why the check misses it

Two different clients reach the same issuer:

  • HttpJwksLoader fetches the key set. It succeeds, and it is what jwks: ready and
    issuer_reachability: reachable report on.
  • DiscoveryResolver fetches .well-known/openid-configuration. Every BFF flow needs it, and
    nothing in the readiness check touches it.

So issuer_reachability: reachable is true in the narrow sense — one endpoint on that issuer was
reached — while the endpoint the BFF actually depends on was never tried.

Scope

This is not specific to the size-limit defect that surfaced it
(cuioss/TokenSheriff#628). Once that is fixed, discovery can still fail for ordinary operational
reasons — issuer down, DNS, certificate, egress policy — and readiness will stay green through all
of them. The gap is structural.

Note also that discovery is lazy (resolved on first use), which is a deliberate and good property:
the gateway boots without the IdP. But it means the first person to discover a broken discovery
configuration is a user hitting /auth/login, not the deployment pipeline.

Suggestion

When an oidc block is configured, let readiness cover the discovery path as well — either by
resolving provider metadata during the check, or by reporting a separate datum
(discovery: ready | failed | not-yet-resolved) so the two are distinguishable rather than conflated
under one issuer_reachability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions