feat: railway code --codex — launch OpenAI Codex in a sandbox with your own sign-in#1006
Closed
codyde wants to merge 11 commits into
Closed
feat: railway code --codex — launch OpenAI Codex in a sandbox with your own sign-in#1006codyde wants to merge 11 commits into
railway code --codex — launch OpenAI Codex in a sandbox with your own sign-in#1006codyde wants to merge 11 commits into
Conversation
…th your local sign-in New top-level `railway code` agent launcher. `--codex` copies the user's existing ~/.codex/auth.json (the flow OpenAI documents for remote machines and containers) into a fresh or reused sandbox and drops into an interactive codex session over the relay. - consent-gated, client-side read of the credential; it rides ssh stdin into a 0600 file in the sandbox — never argv, Railway variables, or images - seeds COLORTERM + codex folder-trust config (only when absent) - installs @openai/codex in the sandbox when missing (marker-based errors distinguish no-npm / install-failed / relay failure) - reuses the active RUNNING sandbox; --new forces a fresh one; 30m idle cap - ports run_native_ssh_captured (stdin-payload ssh) into ssh::native - create_and_store now returns the sandbox id for reuse by launchers Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… real errors Plumbing ssh now captures stderr and retries up to 3x with backoff for transient relay/boot failures. Host-key verification failures fail fast with remediation instead of being retried — that's a security signal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dbox Provisioning seeds a guarded ~/.profile block: plain connects (railway sandbox ssh) run bash as a login shell (verified against a live sandbox), so interactive sessions drop straight into codex. Not exec'd — quitting codex lands in a shell. [ -t 1 ] keeps command/scp sessions out; env guard prevents re-entry; grep guard keeps the seed idempotent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ING boxes - print how to get back in on disconnect (sandbox ssh / code --codex) and the exact env-scoped 'sandbox list' invocation — 'railway sandbox ls' from a differently-linked dir silently shows a different environment - reuse now also matches CREATING sandboxes so a re-run seconds after a launch doesn't mint duplicates - --idle-timeout <minutes> (default 30) controls how long the box survives after disconnect Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n script The relay fleet answers with per-instance host keys, so every fresh TCP connection is a new host-key lottery. railway code was making four (seed, inject, install, launch) versus sandbox ssh's one — which is why it failed host-key verification far more often than sandbox ssh against the same sandbox. - provisioning is now ONE script over ONE connection (credential still arrives via stdin, markers still distinguish failure modes) - every ssh in a run shares an OpenSSH ControlMaster (ControlPersist=90s): the provisioning connection is verified once and the interactive launch multiplexes over it — verified the Go relay accepts muxed sessions - run_native_ssh_with_opts / extra_opts on the captured variant let the launcher opt in without changing the shared ssh paths Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rministic Relay connections verify against the CLI's own file (~/.railway/known_hosts_relay, accept-new) and heal it on mismatch — never the user's ~/.ssh/known_hosts. With the relay fleet presenting 7+ per-instance host keys behind one hostname, single-key pinning was both futile (most connections mismatch) and security theater (TOFU re-accept is indistinguishable from MITM). Documented for revert to strict checking once the relay ships a shared host key / SSH CA. Validated: 10/10 consecutive fresh create→provision→launch→destroy cycles, ~6s each (image ships codex preinstalled; install step short-circuits). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…h GitHub auth --variable / --env-file ride the same server-side resolution as sandbox create (reference forms like postgres.DATABASE_URL work); a note warns when they're ignored because an existing sandbox is being reused. --gh reads the host token via `gh auth token` (works regardless of where gh stores it — macOS keychain included), fails fast before a sandbox is spent, and provisions the sandbox with a 0600 token file, a GH_TOKEN profile export, and a git credential helper for github.com/gist — no gh install required in the box; gh honors GH_TOKEN natively if present. Token rides ssh stdin over the same multiplexed connection; the consent prompt names it when --gh is set. Verified e2e: fresh sandbox, variable visible in env, token file 0600, api.github.com authenticates, credential helper set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… the session The interactive launch exec'd codex, so quitting it tore down the whole ssh session. Now (matching the ~/.profile autostart behavior) codex runs un-exec'd and hands off to a login shell on exit; the exported RAILWAY_CODE_AUTOSTARTED guard keeps that shell's profile from relaunching codex on top of the user. Scripted runs (-- args) keep the exec-and-exit behavior so pipelines don't hang on a trailing shell. Verified live: Ctrl-C out of codex → shell responds → exit closes the session; `-- --version` still exits cleanly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ning The sandbox image doesn't ship distro bubblewrap yet, so codex warns at startup and falls back to its bundled copy (cosmetic — sandboxing works either way). Provisioning now apt-installs it when absent (~8s on fresh boxes); the command -v guard makes this a free no-op once the image ships bwrap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
Superseded by #1013 — the branch was renamed to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
New top-level agent launcher:
railway code --codexcreates (or reuses) a Railway sandbox, injects the user's own Codex sign-in, and drops them into an interactive, authenticated codex session — about 6 seconds end-to-end.How auth works (and why this shape)
~/.codex/auth.jsonis copied into their own sandbox (auth docs, CI/CD guide).--yes); the prompt names the GitHub token too when--ghis set.--ghreads the live token viagh auth token(correct even with macOS keychain storage), fails fast before a sandbox is spent, and provisions a 0600 token file +GH_TOKENexport + git credential helper — no gh install required in the box.DX details
~/.railway/known_hosts_relay, accept-new, self-healing) — the user's~/.ssh/known_hostsis never touched. This works around the relay fleet currently presenting per-instance host keys (7+ observed); the code is commented for revert to strict checking once the relay ships a shared host key / SSH CA.~/.profileseed means any interactiverailway sandbox sshinto the box drops straight into codex; quitting codex lands in a shell (verified the relay runs bash as a login shell).--newforces fresh; disconnect prints reconnect breadcrumbs and the env-scopedsandbox listinvocation.--variable/--env-filehave fullsandbox createparity (server-side reference resolution), with a warning when ignored due to reuse.Validation
--gh/--variableverified e2e: variable visible in the box env, token file 0600,api.github.comauthenticates, credential helper registered.Notes for reviewers
codex login --device-authin-sandbox, which this command's UX already points to on abort.railway ssh/sandbox sshtoo; writeup to follow separately.🤖 Generated with Claude Code