Browse docsDevelopers

Push from a VM

Connect your own GitHub account so that what an agent pushes and the pull requests it opens are yours.

updated 2026-10-06

git and gh on a VM are the real ones, at the jail's own authority: everything local works, and anything that needs GitHub fails as git and gh fail. What reaches GitHub is a verb — push, force-push, fetch, clone, pr-create, pr-view, pr-checks, pr-merge — that runs outside the jail as you, with your GitHub token, so a commit an agent pushes is your commit and a pull request it opens is your pull request. That needs your GitHub account connected to Rift once, by GitHub's device flow. This page is the verbs, that step, and how to undo it.

The verbs

verbs on a VM lists the catalog, and each verb answers --help with its declaration. A verb takes --name value for each declared argument and nothing else:

sh
push --branch my-branch
force-push --branch my-branch
pr-create --title "…" --body-file notes.md
fetch

fetch refreshes the VM's mirror of the repository from GitHub and then does the local git fetch origin for you — your checkout's origin is that mirror, on the VM. push sends a branch of the checkout up, as a new branch or a fast-forward. After a rebase, force-push overwrites the branch on GitHub, but only if it is where the mirror last saw it: if someone else pushed to it since your last fetch, it is refused. Reads reach whatever your token reaches; writes are refused for any repository but the VM's own.

You don't need this to get a VM.

A VM clones, builds and runs without your account connected — the App's installation handles the clone. The first thing that needs you is a push — or connecting your personal organization, which needs to know your GitHub user (Connect GitHub). Otherwise connect when a push is refused, not before; rift_whoami says whether you're connected.

Connect, through your agent

When a verb on a VM is refused because you haven't connected GitHub, the agent calls rift_github_login. The first call answers a URL and a code; the agent shows you both. Open the URL in a browser signed in to GitHub, enter the code, and approve. Tell the agent; it calls the tool again to check, and sees connected.

The token is handed to a verb per run, from the control plane, at the moment it runs — it never sits on the VM. So the VM you're in pushes the moment you're connected; nothing to destroy or claim again.

What the token may do

Your token is scoped by GitHub to the repositories the App's installation covers and you can already reach — Rift's App has no reach of its own on your behalf. It may read and write contents and pull requests, which is what push and pr-create need, and no more. The token is sealed the moment Rift receives it, and it exists on a VM in one process, for one verb's run, and then not at all. Every run that asks for it is recorded on the VM — the verb, its target, whether it writes, its arguments — before anything is answered.

Tokens expire; Rift keeps them fresh.

GitHub's user tokens expire after eight hours. Rift keeps the refresh token sealed beside it and refreshes the token before it expires, so a VM claimed a day later still pushes as you. If a push is refused after a long while, log in again — that's the whole fix.

Disconnect

In the app at https://fixedlabs.dev/app, open Settings and click Disconnect under GitHub. The sealed token and its refresh token are destroyed, then the record is cleared. Every verb that needs GitHub is refused from then on, until you log in again with rift_github_login.