Sign-ins a runtime refreshes are kept sealed and carried by the bridge
ADR 0019 left out sign-ins that a runtime keeps in a file and refreshes itself, such as Codex signed in with a ChatGPT plan, since a copy thrown away with each container goes stale. We decided that Mission Control keeps such a sign-in sealed, like any other credential, and that the agent image's bridge carries it: it is handed into each container by variable, written into a home only the container has (never onto a mount), and every version the runtime writes, after signing in or refreshing, is sent back to Mission Control, which seals it again. A configuration signs in through its runtime, by URL and code: Mission Control starts the runtime without a sign-in and asks it to sign in, its owner opens the page and enters the code it shows, and the sign-in comes back the same way.
Considered Options
- A sign-in directory per configuration, mounted into its containers: rejected; the sign-in would sit unencrypted in the data directory, where ADR 0002 keeps credentials sealed.
- Sealing what the container left behind, after it stops: rejected; it would need the file on a mount meanwhile, and a container killed before it stops would lose a refresh.
- Signing in with a pasted file (
auth.jsonfromcodex loginelsewhere): rejected for now; the runtime's own sign-in by URL and code needs nothing installed where the person is.
Consequences
- A runtime kind declares a sign-in (
RuntimeKind.signIn): the variable naming its home, the file, what else in the home outlives the container (Codex's sessions, linked into the run's own directory), and the ACP authentication methods to sign in with and to use. Codex declares one; Claude Code needs none, sinceclaude setup-tokengives a token that does not refresh. - The container sends sign-ins back with a sign-in token good for that configuration alone. Of two versions, as from two runs refreshing at once, the one the file says was refreshed last is kept; a run whose refresh lost such a race may be signed out until its next start.
- Plaintext exists only in the container, in the bridge's environment and in transit to Mission Control. Docker passes the variable by name, so it is never on a command line, though whoever can inspect the container sees it, as with API keys.
- A configuration of such a kind may be set up without a credential, and serves nothing until it signs in. Signing out removes the sign-in.