The honest part first
An authenticated browser must possess usable session state inside its environment. Obol does not claim these sessions never enter the sandbox: the contract requiresplaintext_present_in_environment: true, as a required field with a fixed value, precisely so that no surface can quietly imply otherwise.
That is a different boundary from the one that governs model and vendor API credentials. Those keep gateway-only plaintext handling and reach no environment and no log. A session profile is the narrow, reviewed exception, and it is scoped to a single named account.
What is stored, and what cannot be
The stored state lives sealed behindsealed_state_ref. The contract carries metadata only, and it has no field that could hold a password, a cookie value, a token, or a bearer string. There is no export of the profile bytes.
The only supported way to acquire one is user_assisted_login: a person authenticates in a private session and the resulting state is sealed. A password is never placed in a model prompt, and no Worker instruction should contain one — control screens free text for recognisable credential material and refuses the request rather than saving it.
The rules that follow from calling it a secret
The structural refusal is worth stating plainly: a code environment cannot mount a session profile at all. That is enforced in the data model, not by convention, so a Worker that asked for one on a
code environment would be refused before it ran.
The routes, and what they do not certify
Two properties are worth knowing before you build against them.
No session state crosses this boundary.
sealed_state_ref is derived from the workspace and the profile id and is never accepted from a caller, so the capture body has no field a byte could travel in. Control records consent, custody metadata and the door check. It does not read the state back, and it does not certify the bytes.
Revocation is a fence, not a flag. Read the response’s state, not its HTTP status. revoked means control observed every holder stop. revoking means the record is unallocatable, the address is destroyed and the fence has been applied — and at least one lease has not yet been observed to stop, because a bumped fencing token is not evidence that a holder halted. Calling revoke again is safe, and it is also how you ask whether it has landed.
Four things ADR-0098 asks for are not here yet, and none of them is implied by the routes answering: a control lease’s purpose is not persisted, so capture verifies the door is open but not the sign on it; allocation does not re-read revocation state at the moment a lease is created; no scheduled sweep expires stale profiles, so expiry is enforced by the Doctor and on read; and no revocation signal reaches orchestration, which is what would turn revoking into revoked promptly rather than eventually.
What the Doctor tells you
GET /workers-doctor?worker_id=… checks every profile a Worker’s revision references, and an unhealthy one is a fail and never a warn:
Signing in as part of a run
Where a login has to happen inside a live run — a step nobody could pre-seed — the mechanism is a control lease withpurpose: "assisted_login". A person takes the environment for a bounded window and authenticates themselves. That is the same door described in Take over a browser, and it is gated on CHANGE_APPLY for exactly this reason: it is the point at which a human types a password into an environment that then holds an authenticated session.