Skip to main content
Enterprise environments often require applications to operate behind corporate proxies and use custom certificate authorities (CAs) for SSL/TLS validation. Node.js provides built-in support for these requirements through environment variables and command-line flags, eliminating the need for third-party proxy libraries in many cases. This guide covers how to configure Node.js applications to work in enterprise network environments:
  • Configuring proxies via the NODE_USE_ENV_PROXY environment variable or the --use-env-proxy flag
  • Adding certificate authorities from the system store via the NODE_USE_SYSTEM_CA environment variable or the --use-system-ca flag

Proxy configuration

In many enterprise environments, internet access to external services may need to be routed through HTTP/HTTPS proxies for security and monitoring. This requires applications to be aware of and use these proxies when making network requests. Proxy settings are often provided via environment variables such as HTTP_PROXY, HTTPS_PROXY, and NO_PROXY. Node.js supports these when NODE_USE_ENV_PROXY or --use-env-proxy is enabled. This works with node:http and node:https (v22.21.0 or v24.5.0+) methods as well as fetch() (v22.21.0 or v24.0.0+).
# The proxy settings might be configured in the system by your IT department
# and shared across different tools.
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
export NO_PROXY=localhost,127.0.0.1,.company.com

# To enable it for Node.js applications.
export NODE_USE_ENV_PROXY=1
node app.js
Once enabled, http, https, and fetch() requests use the configured proxies by default, unless an agent is overridden or the target matches NO_PROXY.

Configure the proxy programmatically

To configure the proxy programmatically, override the agents. This is currently supported by https.request() and other methods built upon it such as https.get().

Per-request agent override

To override the agent on a per-request basis, use the agent option for http.request()/https.request() and similar methods:
import https from 'node:https';

// Creating a custom agent with custom proxy support.
const agent = new https.Agent({
  proxyEnv: { HTTPS_PROXY: 'http://proxy.company.com:8080' },
});

https.request(
  {
    hostname: 'www.external.com',
    port: 443,
    path: '/',
    agent,
  },
  res => {
    // This request will be proxied through proxy.company.com:8080 using the HTTP protocol.
  }
);

Global agent override

To override the agent globally, reset http.globalAgent and https.globalAgent:
Global agents do not affect fetch().
import http from 'node:http';
import https from 'node:https';

http.globalAgent = new http.Agent({
  proxyEnv: { HTTP_PROXY: 'http://proxy.company.com:8080' },
});
https.globalAgent = new https.Agent({
  proxyEnv: { HTTPS_PROXY: 'http://proxy.company.com:8080' },
});

// Subsequent requests will all use the configured proxies, unless they override the agent option.
http.request('http://external.com', res => {
  /* ... */
});
https.request('https://external.com', res => {
  /* ... */
});

Using proxies with authentication

If the proxy requires authentication, include credentials in the proxy URL:
export HTTPS_PROXY=http://username:password@proxy.company.com:8080
Avoid committing credentials in env files. Prefer a secret manager and programmatic configuration.

Proxy bypass configuration

The NO_PROXY variable supports the following patterns:
PatternDescription
*Bypass proxy for all hosts
company.comExact host name match
.company.comDomain suffix match (matches sub.company.com)
*.company.comWildcard domain match
192.168.1.100Exact IP address match
192.168.1.1-192.168.1.100IP address range
company.com:8080Hostname with specific port
If a target matches NO_PROXY, the request bypasses the proxy.

Certificate authority configuration

By default, Node.js uses Mozilla’s bundled root CAs and does not consult the OS store. In many enterprise environments, internal CAs are installed in the OS store and are expected to be trusted when connecting to internal services. Connections to certificates signed by those CAs can fail validation with errors such as:
Error: self signed certificate in certificate chain
From Node.js v22.15.0, v23.9.0, v24.0.0 and above, Node.js can be configured to trust these custom CAs using the system’s certificate store.

Adding CA certificates from the system store

Enable system CA trust using one of the following methods:
NODE_USE_SYSTEM_CA=1 node app.js
When enabled, Node.js loads system CAs and uses them in addition to its bundled CAs for TLS validation. Node.js reads certificates from different locations depending on the platform:

Windows

Windows Certificate Store (via Windows Crypto API)

macOS

macOS Keychain

Linux

OpenSSL defaults, typically via SSL_CERT_FILE/SSL_CERT_DIR, or paths like /etc/ssl/cert.pem and /etc/ssl/certs/ depending on the OpenSSL build
Node.js follows a policy similar to that of Chromium. See the Node.js documentation for more details.

Adding additional CA certificates

To add specific CA certificates without relying on the system store:
export NODE_EXTRA_CA_CERTS=/path/to/company-ca-bundle.pem
node app.js
The file should contain one or more PEM-encoded certificates.

Combining options

You can combine NODE_USE_SYSTEM_CA with NODE_EXTRA_CA_CERTS:
export NODE_USE_SYSTEM_CA=1
export NODE_EXTRA_CA_CERTS=/path/to/additional-cas.pem
node app.js
With both enabled, Node.js trusts bundled CAs, system CAs, and the additional certificates specified by NODE_EXTRA_CA_CERTS.

Configure CA certificates programmatically

Configure global CA certificates

Use tls.getCACertificates() and tls.setDefaultCACertificates() to configure global CA certificates. For example, to add system certificates into the default store:
import https from 'node:https';
import tls from 'node:tls';
const currentCerts = tls.getCACertificates('default');
const systemCerts = tls.getCACertificates('system');
tls.setDefaultCACertificates([...currentCerts, ...systemCerts]);

// Subsequent requests use system certificates during verification.
https.get('https://internal.company.com', res => {
  /* ... */
});
fetch('https://internal.company.com').then(res => {
  /* ... */
});

Configure CA certificates for individual requests

To override CA certificates per request, use the ca option. This is currently only supported by tls.connect()/https.request() and methods built upon them such as https.get().
import https from 'node:https';
const specialCerts = ['-----BEGIN CERTIFICATE-----\n...'];
https.get(
  {
    hostname: 'internal.company.com',
    port: 443,
    path: '/',
    method: 'GET',
    // The `ca` option replaces defaults; concatenate bundled certs if needed.
    ca: specialCerts,
  },
  res => {
    /* ... */
  }
);

Build docs developers (and LLMs) love