Skip to content

lore-server: dial the auth service on a scheme tonic understands - #1

Closed
nollbit wants to merge 1 commit into
mainfrom
fork/auth-endpoint-scheme
Closed

nollbit wants to merge 1 commit into
mainfrom
fork/auth-endpoint-scheme

Conversation

@nollbit

@nollbit nollbit commented Oct 1, 2026

Copy link
Copy Markdown

Staging ground for an upstream contribution. Opened against our main (pure upstream, 91 behind) so the diff here is exactly what EpicGames/lore would see. Draft — not for merging into our main.

The same change is already in goals/gcp-prod-deploy as a733d9e and shipped in server image 0-1-38.

The bug

[environment.endpoint] auth_url carries the configured scheme — ucs-auth://, oidc:// — which is not a scheme tonic can dial. Both server auth clients pass it to Endpoint::from_shared unchanged and gate TLS on a literal prefix:

// lore-server/src/authnz/auth.rs  (and rebac.rs)
if auth_url.starts_with("https://") {
    endpoint = endpoint.tls_config(...)
}

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 returns transport error with 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: most traffic never touches it.

The fix

lore_transport::auth::ucs_auth::grpc_endpoint already performs exactly this rewrite for the client side, loopback-http exemption included. The client used it; the server did not. This makes it pub and calls it from authnz::auth and authnz::rebac rather 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 — the absence of such a test is why this was reintroduced here once already after being fixed.

Scope

Present in v0.8.6, v0.9.0, v0.10.0 and current upstream main. Not a recent regression.

Verification

Reproduced against a real TLS auth listener before and after:

Dialled as Result
plaintext HTTP/2 preface peer closes the connection — reproduces the failure
TLS, valid bearer token grpc-status: 0 and the expected response

Build, cargo test -p lore-server, clippy and cargo +nightly fmt --check all clean, both on this base and on upstream main.

Note

The failure mode is fail-closed against a TLS auth service: the handshake fails and nothing is transmitted. Against an auth service that accepts h2c, the same code path would send authorization: Bearer <token> over an unencrypted channel. That is the reason grpc_endpoint upgrades non-loopback http:// to https:// in the first place — the server side simply was not using it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VFWPcxHtgaa51mmocMa6dj

`[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

nollbit commented Oct 1, 2026

Copy link
Copy Markdown
Author

Superseded by EpicGames/lore#230, which is open and green on Epic's CI.

This was a review vehicle only — never for merging, since main here is kept pure upstream. The change is already in goals/gcp-prod-deploy as a733d9e and deployed in server image 0-1-38.

@nollbit nollbit closed this Oct 1, 2026
@nollbit
nollbit deleted the fork/auth-endpoint-scheme branch October 1, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant