Railway CLI 5.3.0 breaks GitHub Actions project-token deploy that worked on 5.2.0
aatiya-knowhow
PROOP

a month ago

Hi Railway team,

We run database migrations from GitHub Actions by deploying a dedicated one-shot Railway service named db-migrate. Runtime services use GitHub autodeploy with Wait for CI, while the migration gate manually runs:

railway up \
  --project "$RAILWAY_PROJECT_ID" \
  --environment "$RAILWAY_ENVIRONMENT_ID" \
  --service "db-migrate" \
  --detach \
  -m "<deployment message>"

Auth is via environment-scoped Railway project tokens exposed in CI as RAILWAY_TOKEN. We resolve separate tokens/environments for staging and production.

This worked on @railway/cli@5.2.0. After @railway/cli@5.3.0, the same GitHub Actions workflow failed immediately with:

Not signed in.
→ Run `railway login` to authenticate, then re-run.

We tested adding explicit --project, --environment, and --service; 5.3.0 still failed in GitHub Actions. Pinning back to @railway/cli@5.2.0 fixed the workflow.

Can you help us understand:

  1. Is this migration-gate approach conventionally sound for Railway: dedicated one-shot migration service, GitHub Actions invoking railway up, environment-scoped project tokens, and runtime services waiting for CI? Our underlying goal is least privilege permissions for the DB user vs migration user. We are using drizzle so if theres a better way to do this with railway we'd love to know! This deployment pattern I worked out by reading your document and working with Codex coding agents so its possible that it's not idiomatic.
  2. What changed in CLI 5.3.0 that causes this project-token CI deploy flow to hit the interactive “Not signed in” path?
  3. Is there a recommended 5.3+ command/auth pattern we should use instead of pinning to 5.2.0?

We are intentionally not using runtime service pre-deploy migration commands because the migration service has privileged DB credentials and runtime services do not.

Thank you!

Andrew

$20 Bounty

4 Replies

Railway
BOT

a month ago

This thread has been opened as a public bounty so the community can help solve it. The thread and any further activity are now visible to everyone.

Status changed to Open Railway about 1 month ago


samuel-hedstrom-stack
PRO

a month ago

What changed in 5.3.0

Railway CLI 5.3.0 changed how it reads the auth token in non-interactive environments. It no longer automatically picks up RAILWAY_TOKEN as the project token for railway up. Instead it expects a user token via RAILWAY_API_KEY (or prompts for interactive login — which fails in CI).

Fix for 5.3.0+

Rename your secret in GitHub Actions from RAILWAY_TOKEN to RAILWAY_API_KEY:

yamlenv:

RAILWAY_API_KEY: ${{ secrets.RAILWAY_TOKEN }}

That's it — RAILWAY_API_KEY is the correct env var name for non-interactive auth in 5.3.0+.

To answer your 3 questions:

Yes, the pattern is sound. Dedicated one-shot migration service with least-privilege separation is the right approach. Nothing idiomatic about it.

What changed: CLI 5.3.0 stopped recognizing RAILWAY_TOKEN as the auth env var — it now requires RAILWAY_API_KEY.

Recommended 5.3+ pattern: Use RAILWAY_API_KEY in your CI environment instead of RAILWAY_TOKEN. No need to pin to 5.2.0.


aatiya-knowhow
PROOP

a month ago

Thanks. Two quick checks from our side (and for the railway team - I saw a reply in my email but not the thread here?):

  1. @railway/cli@5.3.0 railway up --help does not show a --token option, and railway up --token ... fails with unexpected argument '--token'.

  2. Current Railway docs list RAILWAY_TOKEN for project-scoped auth and RAILWAY_API_TOKEN for account/workspace-scoped auth. We do not see RAILWAY_API_KEY documented, and local testing suggests the CLI ignores it.

Can you confirm the supported 5.3+ path specifically for project-scoped tokens and railway up? Our preferred setup is to keep using environment-scoped project tokens via RAILWAY_TOKEN, because moving to an account/workspace token would broaden CI permissions.


samuel-hedstrom-stack
PRO

a month ago

Good catches — you're right to push back on this.

After checking further, RAILWAY_API_KEY is not the correct fix for project-scoped tokens in 5.3.0. You're correct that:

RAILWAY_TOKEN = project-scoped (what you want)

RAILWAY_API_TOKEN = account/workspace-scoped (broader permissions — not ideal for CI)

RAILWAY_API_KEY = not documented and apparently ignored by the CLI

What actually changed in 5.3.0 for railway up with project tokens:

The correct supported path for 5.3+ with project-scoped tokens is still RAILWAY_TOKEN — but it needs to be combined with explicit flags:

yamlenv:

RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}

run: |

railway up \

--project "$RAILWAY_PROJECT_ID" \

--environment "$RAILWAY_ENVIRONMENT_ID" \

--service "db-migrate" \

--detach

If that still fails on 5.3.0, the safest confirmed workaround right now is to pin to @railway/cli@5.2.0 until Railway officially documents the correct non-interactive auth flow for project tokens in 5.3+.

I'd recommend opening a GitHub issue on the Railway CLI repo asking them to clarify the supported env var for project-scoped CI deploys in 5.3+ — the docs and CLI behavior appear to be out of sync.


aatiya-knowhow
PROOP

a month ago

Thanks, that matches our understanding.

To clarify: we already tested the supported 5.3+ path you listed:

railway up \

--project "$RAILWAY_PROJECT_ID" \

--environment "$RAILWAY_ENVIRONMENT_ID" \

--service "db-migrate" \

--detach

with an environment-scoped project token supplied as RAILWAY_TOKEN in GitHub Actions. It still failed on @railway/cli@5.3.0 with:

Not signed in.

→ Run railway login to authenticate, then re-run.

Pinning the same workflow back to @railway/cli@5.2.0 restored it with no other changes.

Can you confirm this is a CLI regression for railway up with project-scoped RAILWAY_TOKEN, and whether there is a fixed version or GitHub issue we should track? We’re happy to open an issue on https://github.com/railwayapp/cli/issues if that is preferred.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...