Skip to content

fix(auth): quarantine invalid xAI OAuth state into its source store, not the active profile store - #90156

Open
johnmwhitman wants to merge 1 commit into
NousResearch:mainfrom
johnmwhitman:fix/xai-quarantine-source-store
Open

fix(auth): quarantine invalid xAI OAuth state into its source store, not the active profile store#90156
johnmwhitman wants to merge 1 commit into
NousResearch:mainfrom
johnmwhitman:fix/xai-quarantine-source-store

Conversation

@johnmwhitman

Copy link
Copy Markdown

Problem

When a terminal xAI OAuth refresh failure fires in a profile-mode process, the quarantine path loads the provider state — which may have been resolved from the global-root store via the #18594 read-only fallback — but then persists the emptied/quarantined state into the active profile's store.

That write creates a shadowing providers.xai-oauth stub in the profile store (the #74339 shape). From then on the profile reads its own empty stub forever instead of falling back to the root grant: the lane looks permanently logged-out even after the root grant is repaired or re-issued.

Observed in a production multi-profile deployment (10 profile homes sharing one root grant): every terminal refresh failure left another profile blinded, and re-granting at root did not recover the affected profiles until the stubs were manually deleted.

Fix

Resolve where the state actually came from with _load_provider_state_with_source, and persist the quarantined state back to that source store (the global root when root-resolved) via _persist_provider_state_to_store. Only fall back to the active store when the state was genuinely profile-local. This mirrors the write-through discipline the success path already has (#43589 / #74339).

Test

tests/test_xai_quarantine_source_store.py: hermetic HERMES_HOME profile layout, profile store empty, root store holds the grant → force a terminal refresh failure → assert the quarantine landed in the root store and no providers.xai-oauth stub appears in the profile store. Verified red-on-revert against the unpatched tree.

Relationship to #81383

Companion fix: #81383 serializes refreshes across profiles (preventing the rotation race that causes many of these terminal failures — independently confirmed there). This PR fixes the quarantine-side stub that each failure leaves behind. They compose; neither depends on the other.

…not the active profile store

When a terminal xAI OAuth refresh failure fires in a profile-mode process,
the quarantine path loads provider state (which may resolve from the
global-root store via the NousResearch#18594 fallback) but then persists the emptied
state into the ACTIVE profile's store. That creates a shadowing
providers.xai-oauth stub in the profile store which permanently hides the
root grant from that profile (the NousResearch#74339 shape) — the profile reads its
own empty stub forever instead of falling back to root.

Fix: resolve where the state actually came from with
_load_provider_state_with_source and persist the quarantined state back to
that source store (root when root-resolved) via
_persist_provider_state_to_store; only fall back to the active store when
the state was genuinely profile-local.

Regression test: profile store empty + root store holds the grant ->
terminal refresh failure -> quarantine lands in ROOT, and no
providers.xai-oauth stub appears in the profile store. Verified
red-on-revert against the unpatched tree.

Companion to NousResearch#81383 (cross-profile refresh serialization) — that PR fixes
the rotation race; this fixes the quarantine-side stub that the race's
failures leave behind.
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard provider/xai xAI (Grok) area/auth Authentication, OAuth, credential pools sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades P3 Low — cosmetic, nice to have labels Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have provider/xai xAI (Grok) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants