# Zscaler Root Certificate On the corporate network Zscaler terminates TLS and re-signs traffic with its own root certificate. Every tool that ships its own certificate store — Node, Python, git, cargo — rejects those connections until the Zscaler root is trusted explicitly. Typical symptoms: `unable to get local issuer certificate`, `SELF_SIGNED_CERT_IN_CHAIN`, `SSL: CERTIFICATE_VERIFY_FAILED`, `server certificate verification failed`. ## The certificate The root certificate ships in this folder as `ZscalerRootCertificate-2048-SHA256.crt`. It is PEM-encoded — the `.crt` / `.cer` / `.pem` extension makes no difference, the tools below only care about the content. | Field | Value | |-------|-------| | Subject | `CN=Zscaler Root CA, O=Zscaler Inc.` | | Valid until | 2042-05-06 | | SHA-256 | `04:F6:1F:1D:13:AA:E1:D1:65:73:DC:2C:37:F7:96:FD:F4:AC:97:71:3A:69:59:EB:B1:1D:24:73:95:8B:1A:53` | Copy it to a permanent location outside any repository — the rest of this document assumes `C:\certs\ZscalerRootCertificate-2048-SHA256.crt`. Verify the copy before trusting it: ```bash openssl x509 -in C:/certs/ZscalerRootCertificate-2048-SHA256.crt -noout -fingerprint -sha256 ``` ## Environment variables Set these as **user** variables on Windows: 1. `Win + R` → `sysdm.cpl` → **Advanced → Environment Variables** 2. Under **User variables** → **New** 3. Enter the name and value from the table 4. OK → restart VS Code and every open terminal, otherwise the old value stays in effect | Variable | Used by | Value | |----------|---------|-------| | `NODE_EXTRA_CA_CERTS` | Node.js, npm, Electron, VS Code extensions | `C:\certs\ZscalerRootCertificate-2048-SHA256.crt` | | `REQUESTS_CA_BUNDLE` | Python `requests`, Poetry, pip | same path | | `SSL_CERT_FILE` | OpenSSL, Python `ssl` / `httpx` / `aiohttp` | same path | | `CURL_CA_BUNDLE` | curl | same path | | `CARGO_HTTP_CAINFO` | cargo, crates.io | same path | `SSL_CERT_FILE` covers most Python clients, but `requests` prefers `REQUESTS_CA_BUNDLE` — set both. ## Git Git reads none of those variables. Configure it directly, with **forward slashes** — git treats a backslash in a config value as an escape character: ```bash git config --global http.sslCAInfo "C:/certs/ZscalerRootCertificate-2048-SHA256.crt" ``` Never use `http.sslVerify=false` as a workaround — it disables verification for every remote, not just the ones behind Zscaler. ## Verifying the setup ```bash curl -sSI https://pypi.org | head -1 git ls-remote https://github.com/git/git HEAD node -e "require('https').get('https://registry.npmjs.org', r => console.log(r.statusCode))" poetry run python -c "import requests; print(requests.get('https://pypi.org', timeout=10).status_code)" ``` All four must succeed without a certificate error.