Skip to content

[Bug]: an account change does not scrub uploaded file_id references it classifies as non-portable #4710

Closed

Description

@lidge-jun

Client or integration

Codex CLI

Area

Proxy and routing

Summary

src/server/responses/account-change-state.ts detects file_id/file_ids in a request (:85-109, :133-144) and classifies that state as non-portable across an account change (:208-218).

scrubUnportableConversationStateInPlace() then removes only previous_response_id and conversation (:152-171). A request whose only account-bound state is an uploaded file reference returns scrubbed === false and is replayed unchanged against the new account, which may not be able to read that file.

Existing tests exercise the classifier, or bodies that also contain previous_response_id; the file-only path is not covered. The gap predates 2.56.0, but it leaves the advertised safety fix of 2b43c14c03 incomplete.

Reproduction

  1. Send a pooled request that references an uploaded file by file_id and carries no previous_response_id and no provider conversation id.
  2. Cause routing to change the serving account for that turn.
  3. The request is forwarded unchanged; the new account receives a reference this module already declared account-bound.

Suggested fix: fail closed or retain the issuing account when uploaded-file references are present. If dropping them is the chosen contract, remove every detected reference explicitly and cover the file-only case through applyAccountChangeConversationStateScrub().

Version

2.56.0 (e4a8539)

Operating system

macOS 15.5

Logs or error output

(upstream may answer with an inaccessible-file error for the rotated account)

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. added
    proxyHTTP proxy, routing, reverse-proxy / management auth
    on Sep 15, 2026
  2. lidge-jun commented on Sep 15, 2026

    @lidge-jun
    OwnerAuthor

    리뷰 · 우선순위 72 / 80

    이 이슈는 계정 변경 스크럽이 업로드 file_id를 ‘이식 불가’로 분류해 놓고도 실제로 지우지 않는 구멍이다. 현재 dev HEAD 51d577c3f(패키지 2.57.0)의 src/server/responses/account-change-state.ts를 보면 collectFileIds(약 85–109행)가 file_id/file_ids를 모으고, 비이식 판정(약 208–218행대 canPortConversationState 경로)에 그 결과가 들어간다. 그런데 scrubUnportableConversationStateInPlace(152–171행)는 previous_response_id와 conversation만 지운다. 주석도 ‘continuation state naming server-side objects’로 그 둘만 소유한다고 적혀 있다.

    그래서 본문에 업로드 파일 참조만 있고 previous_response_id가 없으면 scrubbed === false가 되어 applyAccountChangeConversationStateScrub가 조기 반환한다. 분류기는 이미 account-bound라고 했는데 요청은 새 계정으로 그대로 나간다. #4641/2b43c14c0이 광고한 계정 변경 안전 계약이 파일 전용 경로에서는 반만 닫힌 상태다. 기존 테스트는 분류기나 previous_response_id가 같이 있는 몸을 위주로 보이며, file-only 경로는 빠져 있다는 이슈 설명이 tip 코드와 맞다.

    수정 방향은 두 갈래다. (1) 파일 참조가 있으면 fail-closed로 발행 계정을 유지하거나 요청을 거절한다. (2) 드롭이 계약이면 감지한 모든 file_id/file_ids를 명시적으로 제거하고 applyAccountChangeConversationStateScrub에 file-only 회귀 테스트를 붙인다. encrypted reasoning/compaction을 건드리지 말라는 기존 주석(#2247 계약)은 유지해야 한다.

    라인 src/server/responses/account-change-state.ts 85–109 - collectFileIds가 파일 참조를 모은다.
    라인 src/server/responses/account-change-state.ts 152–171 - 스크럽이 previous_response_id/conversation만 삭제하고 file_id는 손대지 않는다.
    라인 src/server/responses/account-change-state.ts applyAccountChangeConversationStateScrub - scrubbed === false면 경고·로그 없이 본문 그대로 통과.
    경로 테스트 - file-only account-change 케이스가 빠져 계약이 CI에 고정되지 않았다.

    메인테이너의 판단이 필요한 지점

    너의 추천
    받아라. 기본 추천은 감지된 file 참조를 명시적으로 제거하고 file-only 회귀 테스트를 applyAccountChangeConversationStateScrub에 붙이는 쪽이다. fail-closed가 더 안전하면 그 계약을 주석·구조 문서에 먼저 고정하라. types/config 스플릿과 무관하다.

    이 댓글은 grok-bot이 작성했습니다

  3. lidge-jun commented on Sep 16, 2026

    @lidge-jun
    OwnerAuthor

    Landed via #4777 at 44392b5 (on tip 9fc7e9b with #4764/#4765). dev is not the default branch so GitHub did not auto-close from the PR's Closes line.

    이 댓글은 grok-bot이 작성했습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingproxyHTTP proxy, routing, reverse-proxy / management auth

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions