-
-
Notifications
You must be signed in to change notification settings - Fork 12
feat: Add HTTP proxy support via undici #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Node.js native fetch doesn't respect HTTP_PROXY/HTTPS_PROXY environment variables. This adds automatic proxy detection and configuration using undici's ProxyAgent. When HTTP_PROXY, HTTPS_PROXY, http_proxy, or https_proxy environment variables are set, requests are automatically routed through the proxy. The proxyTls option is set to allow connections through proxies that intercept HTTPS traffic (common in corporate environments), while maintaining full TLS verification for the upstream Linear API connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds HTTP proxy support to Linearis by integrating undici's ProxyAgent to intercept and route requests through proxies configured via standard environment variables (HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy). This enables the CLI to work in corporate networks, Docker containers, and CI/CD environments that require proxy configuration.
Changes:
- Added automatic proxy detection and configuration using undici's
setGlobalDispatcher()at application startup - Added undici as a runtime dependency to enable proxy functionality
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/main.ts | Implements proxy detection from environment variables and configures undici's global dispatcher with ProxyAgent before any HTTP requests are made |
| package.json | Adds undici ^7.0.0 as a runtime dependency for proxy support |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/main.ts
Outdated
| if (proxyUrl) { | ||
| setGlobalDispatcher( | ||
| new ProxyAgent({ | ||
| uri: proxyUrl, | ||
| proxyTls: { rejectUnauthorized: false }, | ||
| }) | ||
| ); |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting rejectUnauthorized: false for proxyTls disables TLS certificate verification for the connection to the proxy itself. This creates a security vulnerability where attackers could intercept traffic between the application and the proxy using a man-in-the-middle attack.
While the PR description mentions this allows connections through proxies that intercept HTTPS traffic, disabling certificate verification is a dangerous default. Consider either:
- Requiring users to explicitly opt-in via an environment variable (e.g.,
LINEARIS_PROXY_INSECURE=true) - Removing this option entirely and letting users configure their system's certificate store if needed
- At minimum, add a warning when this insecure mode is active
| if (proxyUrl) { | |
| setGlobalDispatcher( | |
| new ProxyAgent({ | |
| uri: proxyUrl, | |
| proxyTls: { rejectUnauthorized: false }, | |
| }) | |
| ); | |
| const proxyInsecure = | |
| process.env.LINEARIS_PROXY_INSECURE === "1" || | |
| process.env.LINEARIS_PROXY_INSECURE === "true"; | |
| if (proxyUrl) { | |
| const proxyOptions: { uri: string; proxyTls?: { rejectUnauthorized: boolean } } = { | |
| uri: proxyUrl, | |
| }; | |
| if (proxyInsecure) { | |
| proxyOptions.proxyTls = { rejectUnauthorized: false }; | |
| // Warn users that they have explicitly opted into insecure proxy TLS behavior. | |
| // This disables TLS certificate verification between the application and the proxy. | |
| console.warn( | |
| "[linearis] Warning: LINEARIS_PROXY_INSECURE is enabled; TLS certificate verification for proxy connections is disabled." | |
| ); | |
| } | |
| setGlobalDispatcher(new ProxyAgent(proxyOptions)); |
src/main.ts
Outdated
| // Proxy support: Node.js native fetch doesn't respect HTTP_PROXY env vars. | ||
| // This configures undici's global dispatcher to route through the proxy. | ||
| import { ProxyAgent, setGlobalDispatcher } from "undici"; | ||
| const proxyUrl = | ||
| process.env.HTTPS_PROXY || | ||
| process.env.HTTP_PROXY || | ||
| process.env.https_proxy || | ||
| process.env.http_proxy; | ||
| if (proxyUrl) { | ||
| setGlobalDispatcher( | ||
| new ProxyAgent({ | ||
| uri: proxyUrl, | ||
| proxyTls: { rejectUnauthorized: false }, | ||
| }) | ||
| ); | ||
| } |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new proxy configuration logic lacks test coverage. Since the codebase has comprehensive vitest unit tests (as seen in tests/unit/), this critical infrastructure change should include tests to verify:
- Proxy URL detection from different environment variables
- Correct priority order (HTTPS_PROXY > HTTP_PROXY > https_proxy > http_proxy)
- Behavior when no proxy is configured
- ProxyAgent initialization with correct parameters
Consider adding a test file like tests/unit/proxy-config.test.ts to ensure this functionality works correctly across different environments.
src/main.ts
Outdated
| // Proxy support: Node.js native fetch doesn't respect HTTP_PROXY env vars. | ||
| // This configures undici's global dispatcher to route through the proxy. | ||
| import { ProxyAgent, setGlobalDispatcher } from "undici"; | ||
| const proxyUrl = | ||
| process.env.HTTPS_PROXY || | ||
| process.env.HTTP_PROXY || | ||
| process.env.https_proxy || | ||
| process.env.http_proxy; | ||
| if (proxyUrl) { | ||
| setGlobalDispatcher( | ||
| new ProxyAgent({ | ||
| uri: proxyUrl, | ||
| proxyTls: { rejectUnauthorized: false }, | ||
| }) | ||
| ); | ||
| } |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new proxy support feature is not documented. Users need to know:
- That HTTP_PROXY/HTTPS_PROXY environment variables are now supported
- The priority order of the variables (HTTPS_PROXY > HTTP_PROXY > https_proxy > http_proxy)
- The format for proxy URLs (especially if authentication is needed: http://user:pass@proxy:8080)
- Any security implications of the implementation
Consider adding a "Proxy Configuration" section to the README.md that documents this feature, similar to the existing "Authentication" section.
src/main.ts
Outdated
| process.env.http_proxy; | ||
| if (proxyUrl) { | ||
| setGlobalDispatcher( | ||
| new ProxyAgent({ | ||
| uri: proxyUrl, | ||
| proxyTls: { rejectUnauthorized: false }, |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The proxy configuration does not respect the NO_PROXY environment variable. This means that all requests, including localhost or internal network requests, will be routed through the proxy when one is configured.
While the PR description mentions this as a known limitation, routing requests to api.linear.app through a proxy is the intended behavior. However, if the codebase makes any requests to localhost or internal services, those would incorrectly go through the proxy as well.
Consider adding NO_PROXY support to exclude certain domains from proxy routing, particularly for common patterns like localhost, 127.0.0.1, and *.local.
| process.env.http_proxy; | |
| if (proxyUrl) { | |
| setGlobalDispatcher( | |
| new ProxyAgent({ | |
| uri: proxyUrl, | |
| proxyTls: { rejectUnauthorized: false }, | |
| process.env.http_proxy; | |
| const noProxyEnv = process.env.NO_PROXY || process.env.no_proxy; | |
| const defaultNoProxy = "localhost,127.0.0.1,::1,.local"; | |
| const noProxy = noProxyEnv | |
| ? `${noProxyEnv},${defaultNoProxy}` | |
| : defaultNoProxy; | |
| if (proxyUrl) { | |
| setGlobalDispatcher( | |
| new ProxyAgent({ | |
| uri: proxyUrl, | |
| proxyTls: { rejectUnauthorized: false }, | |
| noProxy, |
1. Security: Make insecure proxy TLS opt-in via LINEARIS_PROXY_INSECURE - Secure by default (TLS verification enabled) - Users must explicitly set LINEARIS_PROXY_INSECURE=1 to disable - Warning printed when insecure mode is active 2. NO_PROXY support: Respect NO_PROXY/no_proxy environment variables - Allows excluding hosts from proxy routing 3. Tests: Add comprehensive unit tests for proxy detection - Test proxy URL detection and priority order - Test NO_PROXY detection - Test insecure mode opt-in 4. Documentation: Add Proxy Configuration section to README - Document all supported environment variables - Explain priority order - Provide usage examples - Document security implications of insecure mode 5. Refactor: Extract proxy logic to src/utils/proxy.ts - Separates concerns for better testability - Exports detectProxyConfig() and configureProxy() functions
Problem
Node.js native
fetch()doesn't respectHTTP_PROXY/HTTPS_PROXYenvironment variables. This causes Linearis to fail in environments that require proxy configuration, such as:Solution
This PR adds automatic proxy detection and configuration using undici's
ProxyAgent. When any of the standard proxy environment variables are set (HTTP_PROXY,HTTPS_PROXY,http_proxy,https_proxy), requests are automatically routed through the proxy.Implementation Details
setGlobalDispatcher()to configure the proxy before any requests are madeproxyTls: { rejectUnauthorized: false }option allows connections through proxies that intercept HTTPS traffic (common in corporate environments)api.linear.appretains full TLS verificationChanges
src/main.ts: Added proxy detection and configuration at startuppackage.json: Addedundicias a dependencyTesting
Tested in an environment with HTTP_PROXY configured:
Limitations
NO_PROXYexclusions (could be added in a follow-up)http://user:pass@proxy:8080)