Conversation
`[environment.endpoint] auth_url` carries the configured scheme --
`ucs-auth://`, `oidc://` -- which is not one tonic can dial. Both server
auth clients passed it to `Endpoint::from_shared` unchanged and gated
TLS on `starts_with("https://")`, so any auth service not literally
configured as `https://` was dialled in plaintext: the HTTP/2 preface
arrives at a TLS listener, which closes the connection, and the call
comes back as `transport error` with a broken pipe.
`lore_transport::auth::ucs_auth::grpc_endpoint` already does this
rewrite for the client side, loopback-http exemption included. Make it
public and use it from `authnz::auth` and `authnz::rebac` rather than
repeating the rule.
Only calls that reach the auth service online are affected; where a
token's claims answer the question locally, nothing dials out. The
endpoint construction moves into a function so the scheme rewrite can
be tested without a listener.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Johan Mjönes <johan@playgoals.com>
nollbit
marked this pull request as ready for review
October 1, 2026 10:12
This branch has not been deployed
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The bug
[environment.endpoint] auth_urlcarries the configured scheme —ucs-auth://,oidc://— which is not a scheme tonic can dial. Both server auth clients pass it toEndpoint::from_sharedunchanged and gate TLS on a literal prefix:So an auth service configured as anything other than
https://is dialled in plaintext. The HTTP/2 preface arrives at a TLS listener, which closes the connection, and the call returnstransport errorwith a broken pipe.Only calls that reach the auth service online are affected. Where a token's claims answer the question locally, nothing dials out — which is why this can sit unnoticed for a long time: on a deployment whose tokens carry a
resourcesclaim, most traffic never touches it. The first thing to fail is whatever has no repository id to short-circuit on, which for us wasRepositoryList.The fix
lore_transport::auth::ucs_auth::grpc_endpointalready performs exactly this rewrite for the client side, loopback-httpexemption included. The client used it; the server did not. This makes itpuband calls it fromauthnz::authandauthnz::rebacrather than restating the rule in two more places.Endpoint construction moves into a function so the rewrite can be tested without standing up a listener.
Scope
Present in v0.8.6, v0.9.0, v0.10.0 and current
main. Not a recent regression.Verification
Reproduced against a real TLS auth listener, before and after:
grpc-status: 0and the expected responsecargo build -p lore-server,cargo test -p lore-server,cargo clippy --all-targetsandcargo +nightly fmt --checkare clean on top ofmain.Tests added:
ucs_auth_scheme_dials_https(both modules),https_auth_url_is_unchanged,loopback_http_stays_plaintext.One note on severity
Against a TLS auth service this fails closed — the handshake fails and nothing is transmitted, which is how we found it. Against an auth service that accepts h2c, the same path would send
authorization: Bearer <token>over an unencrypted channel. That is the reasongrpc_endpointupgrades non-loopbackhttp://tohttps://in the first place; the server side simply was not using it.I raised this with your security team rather than assume it was purely a functional bug, and opened this PR on the basis that the failure is fail-closed in the configuration that actually ships. Happy to pull it if you would rather handle it privately.
Alternatives
Reusing
grpc_endpointkeeps one definition of the rule. Duplicating the scheme handling into the server, or normalisingauth_urlonce at config load, would also work — the latter is arguably cleaner if you would rather the server never carry a non-dialable URL at all. Glad to rework it whichever way you prefer.