Skip to content

fix: don't clobber or leak a sibling account's session/usage data - #300

Merged
janekbaraniewski merged 5 commits into
janekbaraniewski:mainfrom
achappell:fix/cross-account-session-clobbering
Aug 31, 2026
Merged

fix: don't clobber or leak a sibling account's session/usage data#300
janekbaraniewski merged 5 commits into
janekbaraniewski:mainfrom
achappell:fix/cross-account-session-clobbering

Conversation

@achappell

Copy link
Copy Markdown
Contributor

Summary

Split out of #250 per review feedback — this is a standalone correctness fix, independent of the OpenCode quota display work.

Found while adding a second OpenCode account (work + personal, different browsers) on the same machine — two independent instances of the same bug class showed up:

  • opencode/perplexity session clobbering: Fetch() refreshed the stored browser session from the live browser cookie on every poll (shared.LoadOrRefreshBrowserSession). With two accounts sharing the same fixed cookie domain but different source browsers, whichever account polled last would silently overwrite the other's stored session. Both providers now read the stored session directly from credentials.json (config.LoadSession) instead of refreshing it.
  • telemetry provider-scope leak: the provider-scope fallback in applyCanonicalUsageViewWithDB kicked in whenever an account had no account-scoped telemetry, without checking whether the account was the only one mapped to that provider. Two sibling accounts sharing a provider ID (e.g. two opencode accounts) meant one account's local usage/message/token data could leak onto the other. The fallback is now gated on the source-provider set mapping to exactly one account.

Testing

  • go build ./..., gofmt -l, go vet all clean on the touched packages.
  • go test ./internal/providers/opencode/... ./internal/providers/perplexity/... ./internal/telemetry/... — all green.
  • New regression test: TestApplyCanonicalUsageView_DoesNotLeakProviderScopeAcrossSiblingAccounts.
  • Existing TestFetch_ConsoleEnrichmentAutoDiscoversWorkspaceID updated to stub the seam that's actually on the call path now (loadStoredSession instead of the now-unused loadBrowserSession).

Found while adding a second OpenCode account (work + personal, different
browsers) on the same machine — two independent instances of the same bug
class:

- opencode/perplexity: Fetch() refreshed the stored browser session from
  the live browser cookie on every poll (LoadOrRefreshBrowserSession).
  With two accounts sharing the same fixed cookie domain but different
  source browsers, whichever account polled last would overwrite the
  other's stored session. Both providers now read the stored session
  directly from credentials.json instead.

- telemetry: the provider-scope fallback in applyCanonicalUsageViewWithDB
  kicked in whenever an account had no account-scoped telemetry, without
  checking whether the account was the only one mapped to that provider.
  Two sibling accounts sharing a provider ID (e.g. two opencode accounts)
  meant one account's local telemetry could leak onto the other. The
  fallback is now gated on the source-provider set mapping to exactly one
  account.
achappell and others added 3 commits August 5, 2026 18:28
Resolve the perplexity conflict by keeping the stored-session fix while
preserving a stubbable seam: main added a test that stubs
loadBrowserSession, which this branch removed. Replace it with
loadStoredSession = config.LoadSession, mirroring the opencode fix in
this same branch, and retarget the test stub at it.

Also drop opencode's loadBrowserSession seam, which this branch left
dead once enrichFromConsole stopped calling it, and point that package's
TestMain at loadStoredSession so the protection covers the seam that is
actually on the call path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PNSGtKppEApHmGH9hD4BN1
@janekbaraniewski
janekbaraniewski merged commit 740e91c into janekbaraniewski:main Aug 31, 2026
17 checks passed
janekbaraniewski added a commit to tttboy123/openusage that referenced this pull request Aug 31, 2026
Two semantic conflicts, both from changes that landed while this branch
was open.

codex/telemetry_usage.go: this branch moved the inline session_meta and
turn_context handling into applyTelemetrySessionMeta /
applyTelemetryTurnContext, while janekbaraniewski#315 added the base_instructions
provenance fallback and a per-event model override to the inline code.
Ported janekbaraniewski#315's semantics into the helpers -- FirstNonEmpty(Model, ModelID,
ProvenanceModel()) for session meta, FirstNonEmpty(Model, ModelID) for
turn context -- and kept the per-event override, derived after the
zero-delta early return rather than before it so it is not computed for
turns that are discarded.

telemetry/usage_view.go: each side added a parameter to
loadUsageViewForProviderWithSources -- windowKey here, and
allowProviderFallback from janekbaraniewski#300's sibling-account leak fix. Kept both;
janekbaraniewski#300's guard in the function body merged cleanly.

Verified both upstream behaviours still hold:
TestParseTelemetrySessionFile_UsesProvenanceModelFallback and
TestApplyCanonicalUsageView_DoesNotLeakProviderScopeAcrossSiblingAccounts
both pass alongside this branch's own regression tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PNSGtKppEApHmGH9hD4BN1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants