Skip to content

fix(openscience): stamp queued usage with its account so a flush can't bill the wrong one#130

Merged
Aayam Bansal (aayambansal) merged 1 commit into
mainfrom
fix/usage-queue-account-safety
Jul 7, 2026
Merged

fix(openscience): stamp queued usage with its account so a flush can't bill the wrong one#130
Aayam Bansal (aayambansal) merged 1 commit into
mainfrom
fix/usage-queue-account-safety

Conversation

@aayambansal

Copy link
Copy Markdown
Member

Audit finding #14 (High, billing). Queued usage rows carried no account identity, so flushPendingUsage sent every row under whatever session was active at startup. If usage was queued under account A (e.g. while the session file was transiently unreadable) and account B later logged in, the startup flush billed B for A's usage — and dropUsageQueue only runs on an explicit logout, not a silent account swap.

  • Each queued row is now stamped with a stable account tag (user_id, else a short SHA-256 of the api_key — never the raw key, which must not sit in the queue file).
  • On flush, a row tagged for a different account is kept in the queue rather than sent (it flushes when that account is active again); legacy/untagged rows remain best-effort under the current account (backward-compatible).

Tests

test/openscience/usage-queue-account.test.ts covers the pure shouldFlushForAccount decision (same account → flush, different → refuse, accountless → best-effort). Full backend suite (949) green.

…t bill the wrong one

Queued usage rows carried no account identity, so flushPendingUsage sent
every row under whatever session was active at startup. If usage was queued
under account A (or while the session was transiently unreadable) and account
B later logged in, the flush billed B for A's usage. dropUsageQueue only runs
on explicit logout, not a silent account swap.

Stamp each queued row with a stable account tag (user_id, else a short hash of
the api_key — never the raw key). On flush, a row tagged for a DIFFERENT
account is kept in the queue rather than sent (it flushes when that account is
active); legacy/untagged rows stay best-effort. Pure shouldFlushForAccount
helper is unit-tested. (#14)
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openscience Ready Ready Preview, Comment Jul 7, 2026 4:19am

Request Review

@aayambansal Aayam Bansal (aayambansal) merged commit 9f54034 into main Jul 7, 2026
11 checks passed
@aayambansal Aayam Bansal (aayambansal) deleted the fix/usage-queue-account-safety branch July 7, 2026 04:20
* api_key (never the raw key, which must not sit in the queue file). */
function accountTag(session: OpenScienceSession): string {
if (session.user_id) return session.user_id
return "k:" + createHash("sha256").update(session.api_key).digest("hex").slice(0, 16)
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