Skip to content

fix(config): start when proxy settings hold values the schema never constrained - #2967

Merged
lidge-jun merged 2 commits into
devfrom
codex/carry-2947-proxy-config
Aug 30, 2026
Merged

fix(config): start when proxy settings hold values the schema never constrained#2967
lidge-jun merged 2 commits into
devfrom
codex/carry-2947-proxy-config

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

Carries #2947 by @luvs01, plus one repair commit. A proxy or noProxy value the schema never
constrained crashed startup instead of being handled.

Opened as a maintainer PR because pushing the repair to the contributor branch reset its
review-readiness checklist and returned it to draft; that attestation belongs to the author. The
cherry-pick preserves @luvs01's authorship.

Carries #2947. Close it as carried once this lands.

The repair

Starting gracefully is right. Doing it silently is not: as originally written, an explicitly configured
but invalid proxy became direct outbound traffic with no signal, and invalid noProxy entries
were dropped so destinations the operator meant to bypass would traverse the proxy. That is a
fail-open network-policy change an operator has no way to notice.

Each discarded value now emits a privacy-safe warning, once per process, naming what was dropped and
what the effective behavior is. The raw value is never logged — proxy URLs can embed credentials, and
the test asserts it never appears in the output.

Verification

Based on dev@dca16949b.

  • bun test tests/proxy-env.test.ts tests/config.test.ts174 pass, 0 fail
  • Red-proven: the new assertion fails on the pre-repair head (15 pass, 1 fail) and passes after.
  • bun run privacy:scan → pass
  • bun x tsc --noEmit → clean

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.

luvs01 and others added 2 commits August 30, 2026 11:24
…onstrained

The top-level config schema ends in `.passthrough()` and declares neither `proxy`
nor `noProxy`, so whatever is on disk reaches `applyProxyEnv` verbatim. It called
string-only methods on those values, and it runs at every process entry point that
makes outbound provider requests. A number, null, or object therefore did not
degrade proxy behaviour -- it threw before the server could start.

Four shapes were confirmed against the current code:

    noProxy: ["ok", 42]    TypeError: entry.trim is not a function
    noProxy: ["ok", null]  TypeError: null is not an object
    noProxy: [{a: 1}]      TypeError: null is not an object
    proxy:   42            TypeError: value.match is not a function

Ignore unusable values instead of throwing: they cannot express a routing intent,
and refusing to start is a worse answer than starting without them. Array
filtering is per-element so one bad entry no longer discards the operator's
usable hosts, and loopback exclusions stay intact in every case.
Malformed proxy settings previously degraded startup silently, allowing direct egress or unexpected proxy traversal without an operator signal. Emit privacy-safe warnings once per process for discarded proxy values, noProxy values, and invalid noProxy elements while preserving graceful fallback behavior.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 30, 2026 02:25
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-30T02:29:17.591395Z 010c1f7 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 23 minutes.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 931fbfe7-daf0-45c8-948e-45b08c3ae044

📥 Commits

Reviewing files that changed from the base of the PR and between dca1694 and 010c1f7.

📒 Files selected for processing (2)
  • src/config.ts
  • tests/proxy-env.test.ts

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

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 010c1f7030

ℹ️ 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".

Comment thread src/config.ts
Comment on lines +3165 to +3167
if (!proxy) {
if (rawProxy !== undefined) warnProxyConfigDiscardOnce("proxy");
return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Apply bypasses when falling back to an inherited proxy

When proxy is malformed or references an unset environment variable but HTTP_PROXY/HTTPS_PROXY is inherited, this early return leaves that inherited proxy authoritative without processing an otherwise valid config.noProxy or adding the promised loopback exclusions. Requests to an internal provider or localhost can consequently traverse the inherited proxy with their authorization headers despite the configured bypass; this becomes newly reachable because the commit changes this case from a startup failure to continued operation. Skip assigning the malformed proxy, but continue through the NO_PROXY merge whenever an inherited proxy is effective.

AGENTS.md reference: AGENTS.md:L330-L332

Useful? React with 👍 / 👎.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 71 / 80

설명

이 PR은 config.jsonproxy / noProxy가 스키마에 없는 값으로 들어왔을 때 프로세스가 기동 중에 죽던 문제를 고칩니다. 지금 dev(HEAD dca16949b)의 applyProxyEnv(src/config.ts)는 최상위 스키마가 .passthrough()로 끝나 proxy/noProxy를 검증하지 않은 채 그대로 받습니다. 예전 코드는 resolveEnvValue(config.proxy)와 배열/문자열 가정 아래 문자열 메서드를 바로 호출해서, 숫자·객체 같은 값이 오면 예외가 나고, 이 함수는 outbound를 쓰는 진입점마다 돌므로 기동 크래시가 됩니다.

수정은 타입을 먼저 가립니다. proxy는 문자열일 때만 resolveEnvValue하고, 아니면 프록시 env를 건드리지 않습니다. noProxy는 배열이면 문자열 원소만 남기고, 문자열이면 resolve 후 split, 그 외는 빈 목록으로 두어 루프백 우회는 유지합니다. 기여자 #2947이 “조용히 무시하고 기동”까지 가져간 뒤, 메인테이너 수리가 침묵 fail-open을 막습니다. 잘못된 proxy를 버리면 사실상 직접(direct) egress가 되고, 잘못된 noProxy 원소를 버리면 우회하려던 목적지가 프록시를 탈 수 있는데, 운영자가 알 수 없었습니다. 그래서 프로세스당 한 번씩 프라이버시 안전 경고를 남기고, 원문 값(자격 증명이 섞일 수 있는 프록시 URL)은 로그에 넣지 않습니다. 테스트가 센티널 문자열이 경고에 안 나오는지도 잠갔습니다.

기반은 dev@dca16949b이고 #2947을 체리픽으로 실어 메인테이너 PR로 연 경위(#2947은 드래프트)가 본문에 있습니다. proxy-env·config 테스트 174 통과, privacy scan·tsc 깨끗, 수리 전 헤드에서 새 단언이 빨간 것도 적혀 있습니다. types.ts/config.ts 대분할 캠페인과 겹치는 “config.ts 수정”이긴 하지만, 이번 범위는 applyProxyEnv 한 함수와 경고 헬퍼·테스트뿐이라 대형 분할 PR을 무효화하는 겹침은 아닙니다. 독립 기동 안정성 픽으로 보면 됩니다.

라인 - 문제

src/config.ts warnProxyConfigDiscardOnce - 종류별(proxy / noProxy / noProxyElements)로 프로세스 생애 한 번만 경고합니다. 테스트·핫 리로드처럼 같은 프로세스에서 설정을 여러 번 바꾸는 경로가 있으면 두 번째 폐기부터는 조용해집니다. 기동 한 번 모델에서는 충분하고, 장기 프로세스에서 설정 재적용이 있으면 리셋 지점이 필요할 수 있습니다.

src/config.ts applyProxyEnv - rawProxy !== undefined이면 문자열인데 resolve 실패(빈/미해결 env)여도 “discarded” 경고가 납니다. 운영자가 env 참조를 일부러 비워 둔 경우와 객체 쓰레기 값이 같은 문장으로 보일 수 있습니다. 문구를 더 쪼갤지는 취향입니다.

src/config.ts - 스키마에 proxy/noProxy를 여전히 안 올리고 passthrough + 런타임 가드만 둡니다. 기동은 살지만, 잘못된 타입이 설정 UI/문서와 어긋난 채 디스크에 남을 수 있습니다. 스키마에 느슨한 유니온을 넣을지, 런타임만 둘지 선택이 남습니다.

tests/proxy-env.test.ts - 원문 미노출·비문자열·배열 혼합 원소 보존을 잘 잠갔습니다. config.test.ts까지 돌렸다는 검증 메모와 맞습니다.

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

  • 랜딩 후 #2947을 landed-via-maintainer로 닫을지.
  • proxy/noProxy를 스키마에 공식적으로 넣을지, passthrough + 경고로 둘지.
  • resolve 실패(빈 문자열/미해결 env)와 타입 오류 경고를 문장으로 나눌지.
  • 설정 핫 리로드가 있는 진입점이면 경고 Set을 리셋할지.

너의 추천

dev에 병합하세요. 기동 크래시를 없애고, 침묵 direct egress를 경고로 드러내며, 자격 증명을 로그에 안 남기는 수리가 들어 있습니다. 병합 후 #2947에 Landed via #2967 at <commit>와 라벨을 달고 닫으면 됩니다. 대형 config 분할을 기다릴 이유는 없고, 이 함수 단위로 먼저 넣는 편이 안전합니다.

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

@lidge-jun
lidge-jun merged commit eeedbb6 into dev Aug 30, 2026
24 checks passed
@lidge-jun
lidge-jun deleted the codex/carry-2947-proxy-config branch August 30, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants