an hour ago
Hi Railway community,
I'm evaluating Railway for hosting a small Python/FastAPI application that will eventually handle authenticated business/customer data.
Before proceeding with a pilot, I'm trying to establish a trustworthy HTTPS ingress boundary.
The application uses Uvicorn behind Railway's managed networking. I understand that Railway provides HTTPS for public domains, but I want to ensure the application can reliably distinguish requests that entered through the intended public HTTPS endpoint from requests that may reach the application through another network path.
My main questions are:
-
HTTPS verification: Is there a documented, supported method for a Railway application to verify that a request arrived through Railway's public HTTPS edge, rather than relying solely on client-supplied forwarding headers?
-
Origin isolation: Can a Railway service be configured to accept application traffic exclusively through its public HTTPS ingress, preventing other private-network callers from reaching the origin directly?
-
Trusted proxy configuration: Does Railway provide a supported mechanism for identifying trusted ingress proxies without relying on potentially changing internal IP addresses?
-
Alternative architecture: If these guarantees aren't available directly, what architecture does Railway recommend for applications requiring strict HTTPS-origin verification? Would a separate authenticated gateway or application-level TLS termination be appropriate?
I'm not reporting a vulnerability or suggesting that Railway's HTTPS implementation is insecure. I'm trying to understand the supported trust model so I can configure my application correctly.
I'd appreciate links to official documentation or examples of recommended production configurations.
Thanks in advance!
1 Replies
an hour ago
Our public HTTP edge terminates TLS and overwrites X-Real-IP, X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host before forwarding, replacing any caller-supplied copies, so a client cannot forge those through the edge. X-Forwarded-Proto arrives as https, and the edge-to-container hop runs over an encrypted WireGuard tunnel even though your app sees plain HTTP. The public networking specs document these headers.
There is no edge-only ingress switch, signed forwarding header, or application-visible mTLS identity that proves a request came through the edge. Services in the same project and environment can reach your listening port directly over private networking and can send their own forwarding headers, so a header alone does not prove edge traversal. Private networks are isolated between projects and environments, so everything inside one environment shares that trust boundary, as described in how private networking works. A TCP proxy on the service would be another ingress path to account for.
We do not publish a stable range for the proxy addresses your container sees as its socket peer. An observed 100.64.0.0/10 address is not a supported contract and can change. With Uvicorn, --proxy-headers plus --forwarded-allow-ips="*" trusts every peer, which is only appropriate if you treat every service in that environment as trusted.
In practice, isolating the app in its own environment (or project) with no other services, and not exposing a TCP proxy, keeps the public HTTPS domain as its only ingress path.
Status changed to Awaiting User Response Railway • about 1 hour ago