fix(platform): revoke the gateway key on every session teardown - #3194
Closed
Israeltheminer wants to merge 1 commit into
Closed
fix(platform): revoke the gateway key on every session teardown#3194Israeltheminer wants to merge 1 commit into
Israeltheminer wants to merge 1 commit into
Conversation
A sandbox session mints an LLM gateway virtual key and hands its value into the container. revokeVirtualKey had one caller where 0.4 had four, so the TTL expiry sweep, admin destroy, phantom heal and the task-agent lane all tore sessions down and left the key live. The mint body states the invariant twice: the gateway has no native TTL, and reset_duration '1M' is safe BECAUSE teardown revokes the key long before any reset matters. It did not. So each abandoned key is a permanent bearer credential with a self-refilling monthly allowance against the org's own provider keys, one per expired, deadline-failed or destroyed session. All teardown edges now go through one seam, domains/sandbox/gateway-keys.ts. The token flip IS the election: UPDATE ... WHERE revoked_at_ms IS NULL RETURNING hands each live key to exactly one caller, so a watchdog sweeping twice or a destroy racing the expiry revokes once. An exec-scoped teardown narrows to that turn's key, so a sibling turn on the same standing session keeps its own credential. Best-effort per key, as 0.4 was: an unreachable gateway must never wedge a teardown. But the failure logs at console.error naming the key id, because that key stays spendable and only an operator can delete it by hand.
This was referenced Sep 3, 2026
Collaborator
Author
|
Superseded by the rebuilt branch — main restructured the harness runner into a |
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.
A sandbox session's LLM-gateway virtual key outlived the session. The gateway
has no native TTL on a virtual key, and
mintVirtualKeygives every key areset_duration: '1M'budget window on the assumption that teardown deletesit long before any reset matters. A key that survives teardown is therefore a
permanent bearer credential with a self-refilling monthly allowance against
the organization's own provider keys.
Rebase of #3148 onto current main, plus unit coverage the original lacked.
One seam, every teardown edge
revokeSessionGatewayKeysis the 0.5 twin of 0.4'snode_only/sandbox/session_teardown.tsplus the revoke half ofsession_admin_actions.destroySandbox. All four edges route through it — TTLexpiry, admin destroy, phantom heal, and a deadline-failed agent run — so
they cannot drift apart.
The election is the token flip.
UPDATE … WHERE revoked_at_ms IS NULL RETURNING llm_gateway_key_idhands each live key to exactly one caller, so awatchdog sweeping the same session twice, or a destroy racing the expiry
sweep, revokes once.
revokeVirtualKeyalso treats a 404 as success, so evena genuine double DELETE cannot fail a teardown.
Exec scope matters. Without
execIdthe whole session is reclaimed. Withone — a deadline-failed task-agent run — only that exec's minted key is
taken, so a sibling turn still running on the same
pa-<agentId>sessionkeeps its credential.
The unit coverage is new
The original PR proved this only through
integration-check.ts. That checkneeds
SANDBOX_LLM_GATEWAY_ADMIN_PASSWORD, and without it every revoke failsauthentication — so the check exercised its own fail-open lane and proved
nothing until that was fixed. Meanwhile a 487-line new module had no test in
CI at all.
gateway-keys.test.tscovers the glue, where the consequences are as sharpas in the SQL:
never throws when the gateway fails,keeps revoking the remaining keys after one failsleaves the session row alone for an exec-scoped teardownThe first is the one that matters most: an unreachable gateway wedging a
teardown is worse than a leaked key, so the failure is counted and logged —
at
console.error, notwarn, because the key stays spendable and only anoperator can delete it by hand.
The SQL election itself stays the harness's job; a mocked
sqlcannot provea race.
Gate
typecheck0 errors,oxlint --type-awareclean,oxfmt --checkclean,sandbox + tasks suites 24 passed (5 files).