Repository navigation
Keep machines and sign-ins working when a deployment changes its origin - #725
Merged
Merged
Conversation
Stored machine GitHub authorizations and browser session credentials are encrypted with APP_ORIGIN as additional data, so changing it made every machine run `chopin pair` again and signed everyone out. The optional PREVIOUS_ORIGINS setting lists the origins a deployment moved from. A credential that only decrypts under one of them is re-encrypted under APP_ORIGIN as its next credential revision, through the existing compare-and-swap rotation, so concurrent moves are safe and later restarts no longer need the old origin. Origins outside APP_ORIGIN and PREVIOUS_ORIGINS are still refused. Origin and WebSocket checks also accept the previous origins, and MCP document links on them resolve to the same documents, while Chopin keeps writing links on APP_ORIGIN. Self-hosting documents how to move. Assistant-model: Claude Opus 5.5 (fast) Assistant-workflow: inline (fast subagents) Assistant-verification: bun test (6733 pass), bun run types, bun run ci Assistant-verification: PostgreSQL storage tests (121 pass) Assistant-verification: e2e auth, machines, connector, build restart, planner picker, experiments, machine choice (57 pass) Co-authored-by: Alex Lavaee <alexlavaee@microsoft.com>
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.
Changing
APP_ORIGINcurrently signs everyone out and makes every paired machine runchopin pairagain. Machine GitHub authorizations and browser session credentials are encrypted with the origin as AES-GCM additional data, so after a move they no longer decrypt, and the connector stops withmachine-reauthorize. Document links on the old name also stop resolving through MCP.This adds an optional
PREVIOUS_ORIGINSsetting: a comma-separated list of origins the deployment moved from. Each one is validated likeAPP_ORIGIN.Credentials
MachinesandSessionsdecrypt withAPP_ORIGINfirst and then with each previous origin. They never try an origin outside those.APP_ORIGINas its next credential revision. This goes through the existing compare-and-swaprotatein storage, so storage and migrations are unchanged. When concurrent requests move the same record, one wins and the others re-read what it stored. After one use, nothing depends on the old origin, soPREVIOUS_ORIGINScan be removed.Other places keyed on the origin
/ws,/ws/sidebar,/api/v1/agent) and/mcpOrigin checklocateDocument, also used by remote Planner attach)/channels/<id>links on a previous origin resolve. Links Chopin writes stay onAPP_ORIGIN.__Host-), so people sign in once on the new name. A session cookie still sent to the old name, or to a new port on the same host, restores and moves.redirect_uriAPP_ORIGIN, never fromHost. A sign-in that was in progress across the restart has to start again./auth/github/setupon the old nameAPP_ORIGIN. Connectors keep calling the old name with their bearer token.The connector does not change.
Docs and config
docs/self-hosting.mdadds a "Moving to a new origin" section: add the new callback URL to the GitHub App, keep serving/mcp,/api,/connector*,/auth/github/callbackand/auth/github/setupon the old name while redirecting browsers on other paths, then setAPP_ORIGINto the new origin andPREVIOUS_ORIGINSto the old one.docs/authentication.mddescribes the decrypt and re-encrypt rule.PREVIOUS_ORIGINSis added to.env.exampleand is late-bound incompose.yaml. An unset value is ignored.Tests
New tests failed before the change:
APP_ORIGINand the old origin inPREVIOUS_ORIGINS. Concurrent uses from two instances all succeed, the grant is stored as revision 2 under the new origin, and the machine still works afterPREVIOUS_ORIGINSis removed./api/sessionandmachines.use./mcpand socket admission accept a previous Origin and refuse an unlisted one.PREVIOUS_ORIGINSis validated.Storage did not change, so no contract tests were added.
Verification
bun test: 6733 passbun run typesbun run ciNo UI changes.