fix(pairing): preserve narrowed token scopes on upgrade#79206
Conversation
|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. from source inspection, though not from a live run in this review. Current main returns only pending scopes for non-empty approvals, matching the related report's observed token-scope replacement path. Real behavior proof Next step before merge Security Review detailsBest possible solution: Land the narrow generic device-pairing fix after real gateway or device-pairing proof and green auth-node checks confirm that narrowed tokens stay narrowed while newly approved scope deltas are appended. Do we have a high-confidence way to reproduce the issue? Yes from source inspection, though not from a live run in this review. Current main returns only pending scopes for non-empty approvals, matching the related report's observed token-scope replacement path. Is this the best way to solve the issue? Yes, the PR direction is the narrowest maintainable fix because it changes generic paired-device token scope resolution instead of adding an MCP-specific bypass. Merge should wait for real behavior proof and failed-check review. Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against df069f7b0222. |
cf7583c to
ac45a8e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ac45a8e524
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| params.existingToken && approvedBaseline.length > 0 | ||
| ? pendingScopes.filter((scope) => !approvedBaseline.includes(scope)) | ||
| : pendingScopes; |
There was a problem hiding this comment.
Ignore revoked token scopes when computing upgrade scopes
When approving a scope-bearing repair/upgrade, this branch treats any existing token as a merge base, including entries with revokedAtMs set. In that case, approving a narrow new request can silently reintroduce previously revoked scopes because mergeScopes(params.existingToken?.scopes, requestedScopeDelta) reuses the revoked scope list. This only occurs when the device has a revoked token record and then submits another pairing request, but in that flow it can undo revocation intent and mint a broader token than requested.
Useful? React with 👍 / 👎.
e0e59aa to
bf4e1aa
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bf4e1aa44a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| return resolveRoleScopedDeviceTokenScopes( | ||
| params.role, | ||
| mergeScopes(params.existingToken?.scopes, requestedScopeDelta), |
There was a problem hiding this comment.
Exclude revoked scopes when merging upgrade token scopes
When an upgrade request is approved for a device whose existing role token is marked revoked (revokedAtMs set), this merge still uses existingToken.scopes as input, so previously revoked scopes are reintroduced into the newly minted token. In the upgrade flow this can silently undo a prior revocation/down-scope decision and grant a broader token than the current request intended; revoked tokens should be treated as having no reusable scope base here.
Useful? React with 👍 / 👎.
4e4730c to
7115a52
Compare
7115a52 to
3b32af7
Compare
* fix(pairing): preserve narrowed token scopes on upgrade * fix(pairing): require pending scopes for approval * fix(pairing): type approval scope merge
* fix(pairing): preserve narrowed token scopes on upgrade * fix(pairing): require pending scopes for approval * fix(pairing): type approval scope merge
* fix(pairing): preserve narrowed token scopes on upgrade * fix(pairing): require pending scopes for approval * fix(pairing): type approval scope merge
* fix(pairing): preserve narrowed token scopes on upgrade * fix(pairing): require pending scopes for approval * fix(pairing): type approval scope merge
* fix(pairing): preserve narrowed token scopes on upgrade * fix(pairing): require pending scopes for approval * fix(pairing): type approval scope merge
* fix(pairing): preserve narrowed token scopes on upgrade * fix(pairing): require pending scopes for approval * fix(pairing): type approval scope merge
Summary
Verification
git diff --check origin/main..HEADpnpm test src/infra/device-pairing.test.ts— 48 passednode -e 'console.log(process.platform, process.version)'—darwin v25.9.0Real behavior proof
pnpm test src/infra/device-pairing.test.tsTest Files 1 passed (1); Tests 48 passed (48)Security Impact
Risks and Mitigations
Linked Issue
Closes #79246