Turnstile is a reverse proxy that authenticates requests via Railway's OAuth flow. It sits in front of your Railway web services and gates access using your Railway workspace's access controls.
This is similar to Vercel or Netlify password protection, but integrated with Railway.
Turnstile is a Go service that deploys to Railway. When a request comes in, Turnstile intercepts it and redirects unauthenticated users through Railway's OAuth flow. Once authenticated, Turnstile ensures they have project:viewer access to your project. If they do, the user is proxied through to your backend service using Railway's private networking.
The service handles session management, WebSocket and SSE upgrades, and all OAuth token exchange automatically.
- Ship internal demos to your team without building authentication
- Protect internal tooling and dashboards that are convenient online but not public
- Auth gate staging/development environments using existing Railway workspace access controls
- An existing Railway project with a service to protect
- A Railway OAuth application (created in Railway's developer settings)
- A custom domain or Railway-generated domain for Turnstile
- Go to Railway's Developer Settings and create a new OAuth application
- Note the Client ID and Client Secret
- You'll add the redirect URL in a later step once you have your Turnstile domain
- Deploy the Turnstile template to your Railway project
- Ensure you've setup all the required environment variables correctly:
| Variable | Required | Description |
|---|---|---|
RAILWAY_CLIENT_ID |
Yes | OAuth app client ID from Railway Developer Settings |
RAILWAY_CLIENT_SECRET |
Yes | OAuth app client secret |
RAILWAY_PROJECT_ID |
Yes | The project to gate access to |
TURNSTILE_BACKEND_URL |
Yes | Internal URL of the service to proxy (e.g., http://${{my-service.RAILWAY_PRIVATE_DOMAIN}}:${{my-service.PORT}}) |
TURNSTILE_PUBLIC_URL |
Yes | Public URL Turnstile is served from (https://${{RAILWAY_PUBLIC_DOMAIN}}) |
TURNSTILE_AUTH_PREFIX |
No | Prefix for auth routes (defaults to /_turnstile) |
PORT |
No | Port to listen on (defaults to 8080) |
TURNSTILE_LOG_LEVEL |
No | Log verbosity: debug, info, warn, error (defaults to info) |
TURNSTILE_PROXY_MAX_RETRIES |
No | Max upstream retry attempts on connection errors (defaults to 3) |
TURNSTILE_PROXY_RETRY_DELAY |
No | Base delay between retries with exponential backoff, e.g. 500ms, 1s (defaults to 1s) |
- Add the OAuth redirect URL to your OAuth application registration:
https://<your-turnstile-domain>/_turnstile/oauth/callback - Redeploy your turnstile service
- Visit Turnstile's public domain
- Complete Railway's OAuth flow, selecting the project to authenticate against
- You'll be forwarded to your protected service OR shown an error page if you don't have access.
The source code is available on GitHub.
Turnstile is open source: If you're interested in how the OAuth flow, proxying, or session management works, check out the repo.
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Turnstile on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.