Skip to content

fix(codex): restore caller token state in Windows shims - #3909

Closed
luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:agent/windows-shim-token-isolation-20260907
Closed

fix(codex): restore caller token state in Windows shims#3909
luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:agent/windows-shim-token-isolation-20260907

Conversation

@luvs01

@luvs01 luvs01 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

A Windows Codex shim can load OPENCODEX_API_AUTH_TOKEN from the service token file and leave it in the CMD or PowerShell session that invoked the shim. Later commands in that session then inherit a credential that the caller did not supply.

Scope the CMD wrapper with setlocal, and save/restore the caller's PowerShell token state in an outer try/finally. Codex still receives the token; an explicitly supplied caller value remains unchanged. Preserve the existing CMD batch handoff and the Codex exit code, including when ensure returns a nonzero status. PowerShell cleanup also runs when ensure or Codex throws.

The change applies to newly generated Windows wrappers. Existing healthy Windows wrappers are not automatically rewritten; the English, Japanese, Korean, Russian, and Simplified Chinese lifecycle pages document the required ocx codex-shim uninstall followed by ocx codex-shim install. Existing wrapper replacement/rollback ownership rules remain in force.

Verification

Head 06829fa566c5e9d688a934fd31d481227450828b, based on dev aeefb3ab5433c69f7621695413ec1f77a05ed54f. Tree: 48e666e6f42ca0308d0d4ceffda4512628d5c710.

  • bun test tests/codex-integration/codex-shim.test.ts --timeout 60000: 83 passed, 8 skipped on this head with the project-pinned Bun 1.4.0 on Windows.
  • Ten runtime regressions cover CMD, Windows PowerShell 5.1, PowerShell 7, missing/empty/explicit caller state, bypass, nonzero ensure, Codex exit-code propagation, and exceptions from both ensure and Codex.
  • Removing the original production fix reproduced four same-shell token failures; restoring its verified source passed the regression set. The shim source and test file are unchanged by this rebase.
  • Typecheck, privacy, and diff checks passed after rebasing. The complete documentation build passed again: 425 pages.
  • Independent read-only security/behavior review found no blocking issue, including CMD batch handoff and PowerShell restoration.
  • The earlier local changed-mode run hit the runner's 900-second limit (exit 124) without a selection summary. Its owned runner and workers were confirmed absent. It is not reported as a pass.
  • Previous-head full CI passed all 26 jobs on 08787869ede5e5d2fa93a43c34a0ee2839c16e01.

Full CI for this head passed all 26 jobs on this exact head. Contributor readiness is based on this full CI plus the local checks described above. At the readiness check, the branch was two commits behind dev (within the repository's ten-commit allowance), with no unresolved review threads. Maintainer approval and upstream-required CI remain separate merge requirements.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

  • All CI tests are green on my local testing.
  • I pushed my PR to the latest dev commit.
  • I resolved all correct Codex and CodeRabbit findings.
  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes

    • Windows CMD and PowerShell shims now restore the caller’s OPENCODEX_API_AUTH_TOKEN after execution.
    • Token handling remains correct when setup or Codex execution fails.
  • Documentation

    • Added guidance in supported languages explaining token inheritance and restoration.
    • Existing Windows shims must be recreated with ocx codex-shim uninstall followed by ocx codex-shim install to receive the updated behavior.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: c11eefa5-93b7-466b-bd10-03e3259ef664

📥 Commits

Reviewing files that changed from the base of the PR and between 1e188b7 and 0878786.

📒 Files selected for processing (7)
  • docs-site/src/content/docs/ja/reference/cli/lifecycle.md
  • docs-site/src/content/docs/ko/reference/cli/lifecycle.md
  • docs-site/src/content/docs/reference/cli/lifecycle.md
  • docs-site/src/content/docs/ru/reference/cli/lifecycle.md
  • docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md
  • src/codex/shim.ts
  • tests/codex-integration/codex-shim.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

Windows CMD shims now isolate environment changes. PowerShell shims restore the caller's token state after success or failure. Integration tests cover token states and shells. CLI lifecycle documentation was updated in five languages.

Changes

Windows token restoration

Layer / File(s) Summary
Shim behavior and integration coverage
src/codex/shim.ts, tests/codex-integration/codex-shim.test.ts
At src/codex/shim.ts:1072, CMD uses setlocal. At src/codex/shim.ts:1119-1159, PowerShell captures and restores OPENCODEX_API_AUTH_TOKEN and preserves the Codex exit code. Tests at tests/codex-integration/codex-shim.test.ts:1299-1379 cover cmd, powershell, and pwsh, including failure paths.
CLI lifecycle documentation
docs-site/src/content/docs/reference/cli/lifecycle.md, docs-site/src/content/docs/ja/reference/cli/lifecycle.md, docs-site/src/content/docs/ko/reference/cli/lifecycle.md, docs-site/src/content/docs/ru/reference/cli/lifecycle.md, docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md
The documentation notes token restoration, child-process inheritance, and the uninstall/install steps required to recreate existing Windows shims.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 08787

New Windows shims restore the caller token after execution while preserving the service token for Codex during execution. The changed shell and failure behavior is covered, with no current merge-blocking risk identified.

Sequence Diagram(s)

sequenceDiagram
  participant CallerShell
  participant WindowsShim
  participant ensure
  participant Codex
  CallerShell->>WindowsShim: Invoke shim with caller token state
  WindowsShim->>ensure: Load token and run ensure
  WindowsShim->>Codex: Launch Codex with file token
  Codex-->>WindowsShim: Return exit code
  WindowsShim-->>CallerShell: Restore prior token state and exit
Loading

Suggested reviewers: lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (5 skipped: 5 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: restoring the caller's token state in Windows shims.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

Hygiene

Deterministic PR hygiene checks passed.

@luvs01

luvs01 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 64 / 80

설명

이 PR은 Windows에서 ocx codex-shim이 만든 CMD/PowerShell 래퍼가 서비스 토큰 파일에서 OPENCODEX_API_AUTH_TOKEN을 읽어 Codex에 넘긴 뒤, 호출한 셸 세션에 토큰을 그대로 남겨 두는 문제를 고친다. 지금 dev HEAD(f802f7112, 2.47.0, #3892 pinned effort 흡수 직후)의 src/codex/shim.ts를 보면, CMD 쪽에는 ensure 구간만 감싸는 setlocal/endlocal이 있고(번 런타임 env용), 토큰 자체는 배치가 끝난 뒤에도 호출자 환경에 남을 수 있다. PowerShell은 토큰을 $env:에 넣은 뒤 복구가 없다. 같은 창에서 이어지는 명령이 호출자가 주지 않은 자격 증명을 물려받는 실제 세션 누출이라, 범위가 작은 보안 수정으로 가치가 높다.

고치는 방식은 단순하다. buildWindowsCodexShim 생성 문자열 맨 앞(마커 직후)에 최상위 setlocal을 넣어 배치 전체의 env 변경을 호출자로부터 격리하고, buildWindowsPowerShellCodexShim은 시작 시 $hadApiAuthToken/$priorApiAuthToken을 저장한 뒤 바깥 try/finally에서 호출자 상태를 되돌린다. Codex 자식은 실행 중에 토큰을 상속하고, 호출자가 이미 넣은 값은 그대로 유지되며, ensure나 Codex가 예외를 던져도 finally가 돈다. 종료 코드는 $codexExitCode에 담아 복구 후에 exit한다. 수명은 새로 생성되는 Windows 래퍼에만 적용되고, 이미 설치된 정상 래퍼는 자동 재작성하지 않는다. 그래서 EN/JA/KO/RU/ZH lifecycle 문서에 ocx codex-shim uninstallinstall 재설치가 필요하다고 적어 두었다.

테스트(tests/codex-integration/codex-shim.test.ts)는 Windows 전용으로 cmd / Windows PowerShell 5.1 / pwsh를 돌리고, 호출자 토큰이 없음·빈 문자열·명시 토큰(+bypass), ensure 비정상 종료, Codex 종료 코드 37 전파, ensure/Codex throw 시 복구까지 회귀로 묶어 두었다. 작성자 서술에 따르면 수정 전후를 뒤집으면 같은 셸 토큰 회귀가 깨지고, 되돌리면 통과한다. typecheck·privacy:scan·docs 빌드는 통과했고, test:changed는 러너 900초 한도(exit 124)로 전체 요약까지는 못 갔다. PR은 아직 draft이고 준비 체크리스트는 2/4(CI green·ready for review 미체크)다. types/config 분할 캠페인과는 무관한 shim·docs·테스트 축이라 close-don't-rebase 대상은 아니다.

라인 / 경로 관찰

src/codex/shim.ts / buildWindowsCodexShim - 최상위 setlocal 추가와 기존 :ensure_ocx 안의 setlocal/endlocal(번 런타임 스냅샷)이 중첩된다. 안쪽 endlocal은 토큰이 이미 켜진 바깥 스냅샷으로 돌아가므로 Codex 실행 구간에도 토큰이 유지되는 구조로 보인다. 다만 생성 배치를 읽을 때 “ensure용 setlocal”과 “토큰 격리용 setlocal”이 한 파일에 같이 있어, 주석 한 줄이 있으면 이후 기여자가 바깥 setlocal을 지우지 않을 가능성이 높다.

src/codex/shim.ts / buildWindowsPowerShellCodexShim - finally에서 호출자 복구 후 exit $codexExitCode 패턴은 종료 코드 보존에 맞다. ensure 경로가 throw가 아니라 $LASTEXITCODE만 남기는 실패면(현재 HEAD와 같이 ensure 실패를 삼키는 동작) Codex까지 진행하는 기존 계약을 유지하는 쪽으로 보인다. 회귀 테스트가 그 계약을 고정해 두었는지만 랜딩 전에 한 번 더 확인하면 좋다.

tests/codex-integration/codex-shim.test.ts / throw 픽스처 - 예외 경로 테스트가 buildWindowsPowerShellCodexShim(realPath, ensurePath, "unused.ts", "process")처럼 bunPath/cliPath 자리에 ensure 스크립트를 끼워 넣는다. Windows에서 통과했다는 서술이 있으니 동작은 맞는 듯하지만, 인자 의미가 읽기 어렵고 이후 시그니처 변경 때 조용히 깨질 수 있다. bun/cli를 진짜 경로로 두고 ensure 실패를 주입하는 편이 더 안전하다.

tests/.../codex-shim.test.ts / CMD 행렬 - CMD는 호출자 토큰 undefined와 명시 토큰만 돌리고, PowerShell만 빈 문자열("") presence를 본다. CMD에서 “변수가 존재하지만 빈 값” 케이스가 빠졌는지는 경미한 공백이다.

문서 / 운영 - 5개 언어 lifecycle note는 누출 복구와 재설치 절차를 같이 설명한다. 보안 수정인데 기존 Windows 설치 사용자는 uninstall/install 전까지 옛 래퍼를 쓰게 되므로, 릴리스 노트·changelog에 한 줄 더 강조할지는 운영 판단이다.

PR 상태 - draft, mergeable이나 mergeStateStatus BLOCKED(체크리스트/게이트), 작성자 로컬 Windows 83 pass·8 skip 서술은 설득력 있다. 전체 test:changed 미완과 CI 완료 대기는 랜딩 전 조건으로 남는다.

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

  • draft 체크리스트·필수 CI가 초록이 되는 즉시 dev에 넣을지, 아니면 릴리스 노트에 Windows shim 재설치를 명시한 뒤 다음 패치 열차에 묶을지
  • 이미 설치된 정상 Windows 래퍼를 자동으로 재작성하지 않는 현재 ownership 규칙을 이번 보안 수정에도 그대로 둘지(문서+재설치 안내만으로 충분한지)
  • PowerShell 예외 픽스처의 bunPath/cliPath 치환을 랜딩 전 정리 요구로 볼지, 후속 청소로 미룰지

너의 추천
보안 가치가 분명하고 범위도 shim 생성·테스트·lifecycle 문서에 잘 묶여 있으므로, CI가 이 head에서 초록이고 체크리스트 4/4가 되면 우선 랜딩하는 쪽을 추천한다. 랜딩 전엔 (1) 중첩 setlocal이 ensure endlocal 이후에도 토큰을 Codex에 넘기는지 Windows에서 한 번 더 스모크하고, (2) 예외 테스트 픽스처 인자 의미를 읽기 쉽게 다듬을지 짧게 결정하며, (3) 릴리스 노트에 codex-shim uninstallinstall을 넣어 기존 Windows 사용자 누출 창을 줄인다. types/config 분할과 무관하니 닫지 말고 이 축으로 유지한다.

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

@github-actions
github-actions Bot marked this pull request as ready for review September 7, 2026 13:50
@github-actions
github-actions Bot marked this pull request as draft September 7, 2026 14:46
@Ingwannu

Ingwannu commented Sep 7, 2026

Copy link
Copy Markdown
Owner

I independently verified that the linked contributor workflow run 34127296217 completed successfully with head_sha 0878786, matching this PR. That is real exact-head CI evidence, distinct from the recorded local changed-test timeout and from upstream-required checks.

Against the freshly fetched dev aeefb3a, this head is 23 commits behind; there are no intervening dev changes to src/codex/shim.ts in that comparison. Please refresh the base and re-attest the corrected head using the readiness gate. Keep the documented existing-installation reinstall requirement and the caller-state/exit-code cases intact. I have not executed Windows tests locally or completed final security approval, so this comment is not an approval or authorization to merge.

@luvs01
luvs01 force-pushed the agent/windows-shim-token-isolation-20260907 branch from 0878786 to 06829fa Compare September 7, 2026 15:43
@github-actions
github-actions Bot marked this pull request as ready for review September 7, 2026 16:12

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up review of the rebased 06829fa: the linked full workflow 34139742297 is verified at this exact head, with 26 successful jobs. I inspected the generated CMD/PowerShell changes and the runtime fixtures: outer CMD setlocal preserves the token during nested ensure; PowerShell finally restores prior state on exceptions, and the child exit code is captured before cleanup. Missing/empty/explicit caller state, bypass, nonzero ensure and thrown ensure/Codex cases are covered. I found no source-visible blocker in that scoped change. Existing installed wrappers still need the documented recreation; this patch does not silently rewrite them.

@lidge-jun The contributor completed the requested rebase and exact-head CI. Current dev 60bcb90 is now another 37 commits ahead, but neither src/codex/shim.ts nor its test file changed on dev in that interval. Rather than asking for repeated version-only rebases, the remaining integration step is to validate the exact current-base merge candidate and required upstream checks. I am not treating contributor CI as that integration result or authorizing an immediate merge. No local Windows execution, runtime configuration write, or daemon restart was performed during this review.

@lidge-jun

Copy link
Copy Markdown
Owner

Delivered independently via #3956 as 4d4629024854784fa6f8c788f2145ee5c3a9bd16 on dev. Original source 06829fa566c5e9d688a934fd31d481227450828b preserved, with actual landing Co-authored-by attribution to luvs01 verified.

The carry retains the production patch and strengthens explicit-token-with-ensure and PowerShell failure/presence/exit-code oracles. Current candidate d6f9eca6999500b953de82afd0710f16c8941d0a passed PR CI34178467225 (19 success,2 skip) and full dispatch34178464441 (26 success,0 skip), including Windows6 shards and macOS control. The earlier routing-fixture failure remains historical; separate #3974 and #3975 repairs landed before this final candidate.

Actual landing tree, scoped diff and fetched dev ancestry were verified under the shared merge lock. The separately landed PID fixture is an explicitly recorded candidate-to-destination difference; whole combined-tree execution is not claimed here. Closing the original as carried, not directly merged. Thank you for the original implementation.

@lidge-jun lidge-jun closed this Sep 8, 2026
@lidge-jun lidge-jun added the landed-via-maintainer Original PR closed after landing via a maintainer merge train label Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working landed-via-maintainer Original PR closed after landing via a maintainer merge train review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants