Authorization and worker upgrade
September 11, 2026 ยท View on GitHub
This upgrade adds owner approval for OAuth authorization-code connections and durable authorization for queued work. It requires a coordinated worker cutover. Back up the database and source repositories before applying migrations.
Say to your agent: "Plan my GBrain upgrade, preserve my connections, and
show me which queued jobs need review before services restart." Your agent
uses gbrain jobs authorize-legacy to preview selected work for review.
Runtime and outbound requests
Use Bun 1.3.11 or newer. CI covers 1.3.11 and the build runtime, 1.3.13. Compiled distributions include their Bun runtime.
URL reachability checks, HTTP integration checks, and remote image loading use
direct connections to validated destinations. If they return
PROXY_NOT_SUPPORTED, remove HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and their
lowercase variants from the service environment, then restart GBrain. A
NO_PROXY exception does not enable these requests. This requirement concerns
these guarded URL operations; configure provider connections separately.
Remote images have a 2 MiB decoded limit; local images retain the 10 MiB limit. HTTP checks read response headers only. Redirects share the original deadline; HTTPS cannot redirect to HTTP. Checks carrying configured headers, credentials, or bodies stay on the original origin through redirects.
Connecting an OAuth client
An authorization request opens the existing admin login and then an approval page. Review the client, redirect destination, requested scopes, administrative capabilities, and source before approving. The page preserves the pending request through password or magic-link login. Authorization grants require S256 PKCE for both public and confidential clients.
Pending requests expire after ten minutes and are held only in server memory. After expiry, server restart, a policy change, or an uncertain approval result, restart the connection from the client. Repeated clicks cannot produce another code. At most 1,000 requests can be pending; retry when capacity is available.
Existing access tokens, refresh tokens, and unexpired authorization codes for active clients remain valid. There is no session purge or retroactive approval requirement. Review existing clients in Admin โ Agents, narrow their grants where appropriate, and revoke clients that should no longer connect. Revoking a client invalidates its outstanding grants and prevents its queued work from starting. Rotating or expiring an individual OAuth credential does not cancel work already accepted for that client. Revoking or deleting a legacy bearer token prevents work accepted under that token from starting.
Generic remote background jobs
submit_job accepts four generic filesystem jobs for the authenticated source:
| Name | Caller data | Execution |
|---|---|---|
sync | Absent, empty, or boolean pull / legacy noPull; never both | Registered root, configured concurrency, no embedding, extraction, or embed backfill |
import | Absent or empty | Registered root, authenticated source, no embedding |
lint | Absent or empty | Inspect the registered root |
lint-fix | Absent or empty | Fix files inside the registered root |
The source must be active, have a valid filesystem configuration (kind absent
or null), and have an existing registered directory. Connector and unknown
source kinds require their dedicated operations. A path, source override,
GitHub-item parameter, or unknown field is rejected.
Pull defaults on only for a source covering the entire Git worktree. Nested
sources default off and cannot explicitly enable pull. sync requires an
existing Git worktree; use import for an ordinary non-Git directory.
Generic background submission requires a durable authenticated principal. Stdio agents should use the local CLI or a dedicated authorized operation. Local application maintenance retains its existing job and budget restrictions.
gbrain remote ping previously submitted an autopilot-cycle job and now
receives the generic-job denial. Run the existing maintenance workflow on the
brain host, or use dedicated authorized operations such as sync_brain and
connector_sync. gbrain remote doctor remains available with its required
scope.
Execution rechecks the original authorization against current principal and source policy. Revocation, narrowed permissions, incompatible bindings, archiving, or a changed source root stops execution. Retry, replay, and coalescing preserve the original authority. Cancel jobs through the existing job controls when their work is no longer wanted.
Delegated tools exclude file_list, file_url, and every localOnly operation.
Update existing bindings referencing removed tools before resubmission. Remote
tool bindings must be nonempty. Internally, an explicit empty tool list means
no tools; only an absent trusted-local binding uses the default registry.
Queue cutover
-
Pause HTTP ingress, schedules, producers, and automatic upgraders so no new work enters. Let active work drain, then stop supervisors, workers, reapers, and every other process sharing the database. Back up the stopped database, repositories, service configuration, and compatible application version. Keep services stopped throughout review and migration.
-
Install the same new application version everywhere without running post-upgrade helpers or package lifecycle scripts. For a published binary installation, use
gbrain upgrade --swap-only. For a Bun package installation, replacevX.Y.Z.Wbelow with the exact release being installed:bun install --global --ignore-scripts github:garrytan/gbrain#vX.Y.Z.WFor a linked source checkout, update that checkout to the chosen release through its normal Git workflow, then run
bun install --ignore-scripts. Do not usegbrain upgrade --swap-onlyfor this source/package cutover: its underlying Bun installation can still run postinstall. Plaingbrain upgrade,gbrain post-upgrade, andgbrain apply-migrations --yescan run pending setup phases that start autopilot or perform other maintenance.Verify the installed version, then apply only schema migrations:
gbrain --version gbrain apply-migrations --force-schema --yes--force-schemaruns pending schema migrations and returns before setup orchestrators. It does not approve queued work or bypass the drain check. The nullablesubmission_authoritycolumn leaves historical rows untrusted. Protocol checks reject old producer inserts and worker claims. Do not run old workers, reapers, or supervisors against this queue. If active historical work blocks migration and the new CLI cannot inspect or cancel it, restore compatible pre-upgrade application and database state, resolve that work locally, and repeat the cutover. -
Inspect outstanding jobs with local job controls. Preview only explicitly selected legacy rows whose
submission_authorityis SQL NULL:gbrain jobs authorize-legacy --ids 101,102 --jsonReview the payloads, schedules, attempts, and transitive dependency effects. The command does not authorize or mutate work without the apply flags. Non-NULL authority is never rewritten by this command, including future versions, malformed objects, and JSON
null. Use matching application and database versions to interpret that work, or explicitly cancel it locally. -
Apply exactly the reviewed snapshot digest:
gbrain jobs authorize-legacy --ids 101,102 --expect <snapshot_digest> --yes --jsonA changed snapshot or dependency graph refuses approval; preview and review again. Only selected SQL-NULL rows receive application authority. IDs, schedules, attempts, and dependencies remain intact. Dependencies require their own explicit review.
-
Explicitly authorize or cancel every nonterminal legacy job before restarting services. Worker startup refuses unresolved work. Historical terminal rows remain unchanged; review them explicitly before a later local replay. Remote replay cannot authorize legacy rows.
-
Start the matching application, producers, and workers and inspect job diagnostics for bounded authorization denials. Resume normal post-upgrade setup and automatic-upgrade schedules only after the queue review is complete and every process uses the matching version.
For rollback, stop all services and restore compatible application and database state together. An older worker must never run against the enforced queue.
For installations using automatic upgrades, pause the automatic upgrade schedule before this cutover and keep it paused until every worker runs the matching version. If the new binary has already migrated the database, stop all old processes immediately and continue with the local queue review above. Keep preview output and backup contents private; they can contain job payloads.
Files and documents
Frontmatter accepts data-only YAML and JSON, preserving existing scalar types.
Unsupported language selectors and malformed documents return errors, including
in import summaries. An import with per-file failures exits nonzero and reports
status: "partial" in JSON; its checkpoint retains completed files for retry.
No bulk reserialization, reindex, or content migration is needed; document
bodies remain opaque to serialization.
Filesystem jobs validate registered canonical roots and reject escaping paths
and symlink targets. POSIX final files are opened with O_NOFOLLOW and accessed
through that descriptor. Platforms without O_NOFOLLOW support refuse remote
file access. Cooperating writers share root and source locks.
Local filesystem writers and source ancestors remain trusted; these checks do
not provide an OS sandbox against hostile directory replacement.