Skip to content

Feature: OpenCodex-scoped noProxy configuration for provider outbound traffic #1215

Closed

Description

@ShannwYang

Problem

OpenCodex currently supports a process-wide outbound proxy, mirrored into
HTTP_PROXY / HTTPS_PROXY, while proxy bypasses must come from the parent
process environment through NO_PROXY.

This is awkward for desktop-managed or auto-started OpenCodex instances:

  • setting a user/session-level NO_PROXY affects unrelated applications;
  • shell-only exports may not reach launchd, Desktop, or auto-started processes;
  • provider endpoints that are more reliable direct than through a local tunnel
    currently require either launcher-specific environment wiring or a source
    patch.

Proposal

Add an optional OpenCodex-scoped configuration field:

{
  "proxy": "http://127.0.0.1:7897",
  "noProxy": [
    "api.example-provider.com"
  ]
}

At startup, applyProxyEnv() would merge config.noProxy with:

  1. any inherited NO_PROXY / no_proxy entries;
  2. the existing loopback defaults (localhost, 127.0.0.1, ::1, [::1]).

The merged value would be assigned only to the OpenCodex process environment.
It must not mutate the user/session environment.

Expected behavior

  • proxy remains the default route for provider outbound traffic.
  • Hosts matching noProxy bypass the proxy.
  • Other applications remain unaffected.
  • Existing environment-based NO_PROXY behavior remains backward compatible.
  • Matching should use the same hostname/suffix semantics already used by
    OpenCodex's outbound policy.

Why a global noProxy list first

A provider-level proxy object would be more flexible, but it would also affect
catalog fetches, OAuth, sidecars, redirects, and provider-specific transports.
A process-scoped bypass list is a smaller extension of the current
proxy/NO_PROXY architecture and solves the desktop/autostart use case
without changing provider schemas.

Suggested implementation surface

  • OcxConfig: add noProxy?: string[]
  • config parsing/validation and diagnostics
  • applyProxyEnv(config): normalize, deduplicate, and merge entries
  • documentation and tests covering inherited values, loopback defaults,
    suffix matching, and no leakage to the parent/user environment

Activity

  1. github-actions commented on Aug 7, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: unknown.

  2. github-actions commented on Aug 7, 2026

    @github-actions
    Contributor

    Maintainer decision respected

    A maintainer has reopened this issue. The automated closure has been deactivated.

  3. reopened this on Aug 7, 2026
  4. Ingwannu commented on Aug 10, 2026

    @Ingwannu
    Owner

    Confirmed on current dev: this is a real configuration gap. applyProxyEnv() currently merges only inherited NO_PROXY / no_proxy with the loopback defaults, and both the server and ocx ensure / ocx sync paths use that process environment.

    A scoped noProxy field is a reasonable direction, but it is also part of the credential-destination boundary because direct private-network routing is validated against NO_PROXY. A focused implementation must therefore:

    • validate and normalize only documented host/domain/IP bypass entries; reject URLs, credentials, control characters, and ambiguous wildcard forms;
    • merge inherited values without changing the user/session environment and apply the same result to server startup and out-of-process catalog sync;
    • preserve loopback defaults and deterministic, case-insensitive de-duplication without changing matching semantics;
    • keep allowPrivateNetwork as a separate explicit requirement: adding noProxy must not by itself authorize a provider or redirect to a private destination;
    • test inherited upper/lowercase variables, service/autostart execution, redirects, IPv4/IPv6, domain suffixes, private destinations, and unchanged behavior when the field is absent.

    Keeping this open for a focused config/transport PR under those boundaries.

  5. added
    enhancementNew feature or request
    proxyHTTP proxy, routing, reverse-proxy / management auth
    on Aug 15, 2026
  6. lidge-jun commented on Aug 19, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 58 / 80

    현재 dev의 applyProxyEnv()는 프로세스 전역 proxy만 HTTP_PROXY/HTTPS_PROXY에 미러하고, 우회 목록은 상속된 NO_PROXY/no_proxy와 루프백 기본값(localhost, 127.0.0.1, ::1, [::1])만 합칩니다. src/config.ts 해당 함수는 config.noProxy를 읽지 않고, config.proxy가 없으면 즉시 return 합니다. 서버 기동과 ocx ensure/ocx sync가 같은 함수를 쓰므로 데스크톱 자동시작과 CLI 동기화가 같은 공백을 공유합니다.

    이슈가 원하는 것은 OpenCodex 범위의 noProxy: string[]입니다. 사용자 세션의 NO_PROXY를 바꾸지 않고, 프로바이더 아웃바운드만 특정 호스트를 직접 가게 하자는 요청입니다. 데스크톱/launchd/서비스는 셸 export를 못 받을 수 있어서, 부모 환경에만 의존하는 지금 구조가 어색합니다.

    매칭 코드는 이미 src/lib/provider-outbound.ts의 noProxyMatches()에 있습니다. 이 함수도 process.env.NO_PROXY만 봅니다. allowPrivateNetwork와 프록시가 같이 켜지면 사설망 목적지는 NO_PROXY에 호스트를 넣으라는 오류를 냅니다. 그래서 noProxy는 단순 UX가 아니라 자격 증명 목적지 경계입니다. 설정 우회가 사설망으로 키를 보내면 프록시 터널을 건너뜁니다.

    Windows/서비스 위생 측면에서 범위는 프로세스 env로 제한해야 합니다. 사용자/세션 환경을 바꾸면 다른 앱에 새고, 반대로 설정만 넣고 applyProxyEnv를 안 타면 카탈로그 fetch와 추론 경로가 갈라집니다. 프로바이더별 프록시 객체는 카탈로그, OAuth, 사이드카까지 건드리므로 이슈가 말한 전역 리스트가 더 작은 확장입니다.

    해결방안은 OcxConfig에 noProxy?: string[]를 두고 applyProxyEnv에서 상속값·루프백·설정값을 정규화·중복 제거한 뒤 process.env.NO_PROXY에만 쓰는 것입니다. 부모 환경은 읽기만 하고, 매칭은 기존 noProxyMatches 의미와 같게 유지합니다. 패치는 추측하지 않으며, 현재 트리에 설정 필드 noProxy는 없습니다.

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

  7. lidge-jun commented on Aug 26, 2026

    @lidge-jun
    Owner

    Shipped on dev as 01b5da9f5 (#2661).

    noProxy accepts either a comma-separated string or an array — a deviation from the string[] you asked for, recorded deliberately: the sibling proxy field is a string and NO_PROXY syntax is comma-separated, so both forms are what people will actually reach for. They normalize identically.

    Entries are merged into the existing NO_PROXY handling rather than replacing it: an inherited value is preserved, loopback stays excluded unconditionally, and dedupe is case-insensitive while keeping your original casing in the emitted value. Documented in the configuration reference next to proxy.

    One behaviour worth knowing: noProxy without proxy is a no-op by design. Writing NO_PROXY for a process that proxies nothing would leak OpenCodex config into unrelated child processes.

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

    enhancementNew feature or requestproxyHTTP proxy, routing, reverse-proxy / management auth

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions