Repository navigation
feat(health): probe platform backends where the deployment keeps them - #685
Merged
Merged
Conversation
Health checks can name a platform backend as ${endpoint:<id>}, resolved
through the same resolver its client queries with: the self-hosted service,
then the operator's URL, then the public default. The Overpass client uses
that resolver, and the three Overpass health checks probe
${endpoint:overpass}/api/status instead of always pinging the public
instance. The contract lists the endpoint ids and rejects others.
The host now sends URL credentials as Basic auth for every probe and keeps
them out of the displayed URL and error messages, and trusts the operator's
own instance like a self-hosted service.
Medformatik
force-pushed
the
fix/overpass-health-follows-instance
branch
from
October 30, 2026 09:19
658a750 to
ad69ec1
Compare
An endpoint can be an internal host carrying the operator's credentials.
Allow ${endpoint:<id>} only as the whole URL prefix of a built-in
manifest's urlTemplate, never in headers; strip the operator's credentials
before the endpoint enters the template, and exempt the host and send them
as Basic auth only when the final URL is on the endpoint's own origin.
Medformatik
force-pushed
the
fix/overpass-health-follows-instance
branch
from
October 30, 2026 09:38
b4cbfc2 to
a566289
Compare
CodeQL flagged /\/+$/ on an operator URL as polynomial: strip trailing slashes with a loop.
Medformatik
enabled auto-merge (squash)
October 30, 2026 10:00
## What changed and why Stacked on #685, whose core helper it reuses; the diff against #685's branch is this one commit. An operator can point OpenMapX at a hosted Overpass with `OVERPASS_URL`, including one that needs a login (`https://user:pass@host`). Every query to such an instance failed. Node's `fetch` refuses a URL that carries credentials, throwing `Request cannot be constructed from a URL that includes credentials: https://user:pass@host/…`, so the password also ended up in the error. The Overpass client now sends such credentials as a Basic `Authorization` header and queries the URL without them, through the same `urlCredentialsAsBasicAuth` helper the health checks use since #685. Attribution keeps resolving from the host, now taken from the URL without credentials. Instances without credentials are unaffected. ## Verification - **Query test:** a query to an `OVERPASS_URL` with credentials goes to `https://overpass.example.org/api/interpreter` with `Authorization: Basic …` for those credentials. The existing Overpass client tests still pass, including the public-mirror fallback. - **Node behaviour:** I confirmed that `fetch("https://u:p@example.com")` throws the error quoted above. - **Repository checks:** `pnpm lint`, `pnpm check-types` and `pnpm check:policy` pass. The full Vitest suite passes (1,953 files, 24,087 tests) except `motis-probe.test.ts`'s socket-retry test. That test is flaky: it failed 1 of 5 isolated reruns on this same code, and it drives a real socket through `node:http` in the data manager, which this change doesn't touch. - **Not run:** a query against a real credential-protected Overpass instance; none is configured anywhere I can reach. ## Release and upgrade impact Product impact: ordinary No package release: the change is limited to the Overpass client in the private `@openmapx/core` package; neither published package's source changes in this commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed and why
The Overpass POI search, the Overpass transit fallback and the hiking overlay's Overpass check always probed the public
overpass-api.de/api/status, whichever instance the deployment uses. On openmapx.com all three query the self-hostedoverpassservice, yet the status page showed them down whenever the public server was at capacity (502).A health check should probe the instance actually queried, as Valhalla and MOTIS already do. The Overpass endpoint, though, is chosen at runtime inside the core client (self-hosted service, then
OVERPASS_URL, then the public default), which no manifest placeholder could express. This makes that choice a shared, declarative concept instead of special-casing Overpass.One resolver in core.
resolvePlatformEndpoint(id, selfHostedUrl)returns the instance a platform backend's requests go to: the enabled self-hosted service, then the operator's URL, then the public default. The Overpass client now resolves through it instead of its own precedence logic. Only the public default still falls back to thekumi.systemsmirror, as before.A declarative manifest placeholder. Health checks can use
${endpoint:<id>}beside${configKey}and${service:<id>}. The host resolves it through the same resolver, so a check cannot drift from what the client queries. The three Overpass checks become plain manifest entries,"urlTemplate": "${endpoint:overpass}/api/status", including the hiking overlay's entry in its list of checks. No integration code changes.Contract.
HEALTH_CHECK_ENDPOINT_IDS(currentlyoverpass) lives in@openmapx/extension-contracts. Manifest validation now rejects an unknown${endpoint:…}id, naming the known ones. Nothing validated placeholders before. Adding Nominatim or MOTIS later means registering them here and moving their clients to the resolver; their precedence differs today, so they are not part of this change.The endpoint stays where the probe goes. An endpoint can be an internal host carrying the operator's credentials. An automated security review of the first push pointed out that a manifest could otherwise copy it into another host's URL or a header, for example
https://collector.example/?u=${endpoint:overpass}.${endpoint:<id>}to be the whole URL prefix ofurlTemplate, used once and followed by a path or nothing, and rejects it in headers.Host probe hygiene, for every check.
https://user:pass@host) are sent as Basic auth.fetchrefuses such a URL and names it, password included, in its error.Authorizationheader takes precedence. The shared helperurlCredentialsAsBasicAuthlives in core.Docs. The integration-system reference now documents all three placeholders.
${service:<id>}had never been documented.The earlier version of this PR used custom health-check code and a framework extension for named custom checks. Both are gone. That version bypassed the host's shared probe handling, which is how an
OVERPASS_URLpassword could have reached the public status page. Overpass queries with credentials inOVERPASS_URLstill fail as before; that older bug gets its own PR.Verification
OVERPASS_URL, an operator URL with its/api/interpreterroute and trailing slash removed, the public default, and the known ids.manifest-smokevalidates every shipped manifest against the new rule.http://overpass:80/api/statuswhen the service is enabled, even withOVERPASS_URLset, and neveroverpass-api.de.https://overpass-api.de/api/statusas a public host.http://overpass:80/api/statusanswers 200 from app-api.pnpm lint,pnpm check-types,pnpm check:policyandpnpm check-openapipass, and the contract's JSON schemas are unchanged. The full Vitest suite passes: 1,953 files, 24,086 tests.Release and upgrade impact
Product impact: ordinary
.changeset/health-check-platform-endpoints.mdreleases@openmapx/extension-contracts(minor:${endpoint:<id>},HEALTH_CHECK_ENDPOINT_IDSand the validation) and rebuilds@openmapx/extension-cli(patch). A community manifest that already contained a literal${endpoint:…}other than${endpoint:overpass}would now fail validation; no such placeholder existed before.