The problem
getCimdClientMetadataUrlError (core/client/config-parse.ts) rejects any CIMD client metadata URL that is not HTTPS:
if (url.protocol !== "https:") {
return CIMD_METADATA_URL_HTTPS_ERROR;
}
There is no loopback exemption. The check is applied to the settings form and, through refineCimdMetadataUrl → CimdConfigSchema, to client.json as it comes off disk — so it cannot be worked around by hand-editing the file either.
The consequence is that CIMD cannot be exercised against anything served locally. Every test server in this repo speaks plain HTTP, so a CIMD metadata document hosted by one of them is not a legal clientMetadataUrl, and the whole registration path is unreachable in local development.
Why this is worth fixing rather than documenting
This is the same shape as #2280 / #1944, from the other side. There, the SDK's over-narrow loopback allow-list for token endpoints made a legitimate local setup fail, and we treated it as a real defect worth explaining carefully. This is our own over-narrow allow-list doing the same thing to our own testing story.
Concretely, it is why #2242 shipped verified by unit and integration tests alone: the v2.6.0 release smoke recorded it as the one row with an observable UI surface that could not be reached. Driving it required standing up a self-signed HTTPS listener purely to hold a JSON document, plus NODE_TLS_REJECT_UNAUTHORIZED=0 in the test server's environment so its own fetch of that document would succeed. That worked — Connection Info read Client registration — Client ID Metadata (CIMD) with the client id equal to the metadata URL — but it is not a reproduction anyone will run casually.
The security question, stated honestly
The HTTPS requirement is not arbitrary: a CIMD client id is a URL an authorization server dereferences, and over plain HTTP its contents are attacker-modifiable in transit. SEP-991 is right to expect HTTPS in production.
But loopback is the documented exception to exactly this reasoning everywhere else in the stack — it is why the SDK exempts localhost, 127.0.0.1 and ::1 from its own token-endpoint TLS assertion, and why core/auth/cimd.ts already says in a comment that an already-stored client_id may be an http:// URL "used by local dev/test metadata servers". So the runtime is willing to use one; only the config validation refuses to accept one.
Options
- Exempt the three loopback literals, matching the SDK's token-endpoint exemption and this repo's own comment. Narrowest change, and consistent with what the runtime already tolerates.
- Keep the check and add optional TLS to the composable test server, so a fixture can serve the document over HTTPS with a self-signed cert. Heavier, and pushes a cert into the repo or a generation step into the harness.
- Gate the exemption behind an explicit dev flag.
Option 1 is the one that matches existing precedent; recording the others because the trade is a real one and the security reasoning above deserves a decision rather than a default.
Acceptance
Context
Found while building the CIMD fixture during the v2.6.0 release smoke, to clear the one finding the ledger recorded as unreachable.
The problem
getCimdClientMetadataUrlError(core/client/config-parse.ts) rejects any CIMD client metadata URL that is not HTTPS:There is no loopback exemption. The check is applied to the settings form and, through
refineCimdMetadataUrl→CimdConfigSchema, toclient.jsonas it comes off disk — so it cannot be worked around by hand-editing the file either.The consequence is that CIMD cannot be exercised against anything served locally. Every test server in this repo speaks plain HTTP, so a CIMD metadata document hosted by one of them is not a legal
clientMetadataUrl, and the whole registration path is unreachable in local development.Why this is worth fixing rather than documenting
This is the same shape as #2280 / #1944, from the other side. There, the SDK's over-narrow loopback allow-list for token endpoints made a legitimate local setup fail, and we treated it as a real defect worth explaining carefully. This is our own over-narrow allow-list doing the same thing to our own testing story.
Concretely, it is why #2242 shipped verified by unit and integration tests alone: the v2.6.0 release smoke recorded it as the one row with an observable UI surface that could not be reached. Driving it required standing up a self-signed HTTPS listener purely to hold a JSON document, plus
NODE_TLS_REJECT_UNAUTHORIZED=0in the test server's environment so its own fetch of that document would succeed. That worked — Connection Info readClient registration — Client ID Metadata (CIMD)with the client id equal to the metadata URL — but it is not a reproduction anyone will run casually.The security question, stated honestly
The HTTPS requirement is not arbitrary: a CIMD client id is a URL an authorization server dereferences, and over plain HTTP its contents are attacker-modifiable in transit. SEP-991 is right to expect HTTPS in production.
But loopback is the documented exception to exactly this reasoning everywhere else in the stack — it is why the SDK exempts
localhost,127.0.0.1and::1from its own token-endpoint TLS assertion, and whycore/auth/cimd.tsalready says in a comment that an already-storedclient_idmay be anhttp://URL "used by local dev/test metadata servers". So the runtime is willing to use one; only the config validation refuses to accept one.Options
Option 1 is the one that matches existing precedent; recording the others because the trade is a real one and the security reasoning above deserves a decision rather than a default.
Acceptance
http://CIMD metadata URL is accepted (whatever mechanism is chosen), or a decision is recorded against this issue explaining why it should not betest-servers/configs/oauth-cimd-http.jsoncan be driven end to end from the web client with no self-signed HTTPS listenerhttp://public host is still rejecteddocs/test-servers.md's CIMD section updated to drop the workaroundContext
Found while building the CIMD fixture during the v2.6.0 release smoke, to clear the one finding the ledger recorded as unreachable.