an hour ago
Hello Railway Team,
We are preparing an owner-only internal web application on Railway Hobby, deployed in a dedicated preview project and environment.
The application uses Auth0 authentication and requires a secure HTTPS transport boundary.
We understand from previous Railway Central discussions that Railway does not currently provide published stable proxy CIDRs, signed edge headers, or an edge-only ingress setting.
Our proposed approach is to isolate the application in a dedicated project with no untrusted services, no TCP proxy, and a fixed HTTPS public origin. The application would not trust client-controlled forwarded headers for authentication decisions.
Could a Railway engineer please confirm whether this is an appropriate security model for an internal, owner-only application?
Specifically:
- Can any external party directly reach the application’s private-network listener without having access to another service within the same Railway project and environment?
- Is project/environment isolation a supported security boundary for preventing untrusted private-network requests?
- If HTTPS termination occurs at Railway’s public edge, is there a recommended way to safely enforce HTTPS-only access in this isolated deployment without relying on undocumented proxy CIDRs?
- Are there any additional network settings required to prevent bypass of the public edge?
We are seeking an engineering-confirmed recommendation before deployment, not requesting infrastructure changes.
Thank you.
3 Replies
an hour ago
No external party can reach your service's private-network listener directly. The private network belongs to one project and environment, so services in other projects or environments can't talk to it, and browsers can't reach it at all. Only services in that same project and environment can, and they all share one trust boundary. A dedicated project and environment with no untrusted services is the right way to use that boundary.
Without a TCP proxy, the only way in from the internet is our public HTTP edge, on your custom domain or the generated .up.railway.app domain. TLS terminates at the edge, and the hop from the edge to your container runs over an encrypted WireGuard tunnel, even though your app sees plain http://. The edge overwrites X-Real-IP, X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host, replacing any copies the caller sends. X-Forwarded-Proto is set to https.
For HTTPS-only checks inside your app, you can read X-Forwarded-Proto without needing proxy CIDRs. Don't hard-code the socket peer address, because that range isn't stable. Don't read an edge-set header as proof that a request came through the edge, either: any service in the same environment can send its own forwarding headers over the private network. Keeping that environment free of other services covers that path.
No other network settings are needed beyond what you described: no TCP proxy, no other services in the environment, and Auth0 authentication enforced in the app. There is no edge-only ingress switch or signed edge header to turn on.
Status changed to Awaiting User Response Railway • about 1 hour ago
an hour ago
Thank you for the detailed explanation.
Since this is a security-critical decision involving HTTPS enforcement and authentication, could a member of the Railway engineering or support team please confirm that this guidance is correct and supported?
In particular, we would appreciate confirmation that relying on X-Forwarded-Proto: https is appropriate when the application is isolated in a dedicated project/environment, with no other services and no TCP proxy.
We want to ensure this is an officially supported security model before deploying our application.
Thank you.
Status changed to Awaiting Railway Response Railway • about 1 hour ago
an hour ago
Yes, that guidance is correct. For requests that come through our public HTTP edge, the edge overwrites X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Host and X-Real-IP, so any copies the caller sends are replaced. X-Forwarded-Proto is set to https. TLS terminates at the edge, and the hop from the edge to your container runs over an encrypted WireGuard tunnel.
The trust assumption is that every route to your listener is trusted. Private networks are isolated between projects and environments, but services inside the same environment can reach your port directly over the private network and set their own forwarding headers. A dedicated environment with no other services and no TCP proxy leaves the public edge as the only way in from the internet, so reading X-Forwarded-Proto is a sound HTTPS check in that setup. If you add a service or a TCP proxy to that environment later, that assumption no longer holds.
Two limits apply. We don't publish proxy CIDR ranges, and we don't offer signed edge headers or an edge-only ingress setting, so the forwarded header doesn't prove a request came through the edge. That's why the isolation matters. Also, the public networking specifications note that networking details can change, so keep Auth0 enforced in the app as your real access control.
Status changed to Awaiting User Response Railway • about 1 hour ago