Configuration by Package Type

Set ZIA hostnames, URL filtering methods, and client trust for npm, PyPI, Docker/OCI, and Hugging Face when routing public registry traffic through JFrog Artifactory.

Ecosystem overview

ZIA URL categories, SSL inspection, Artifactory remote/virtual layout, and client trust differ per ecosystem. This page summarizes npm and Python (PyPI) in detail and points to other topics for Docker/OCI and Hugging Face. It does not replace scripts/README.md for OS-specific variables, client versions, and tests—use that README as the source of truth for workstation configuration.

Configure each ecosystem you enable:

ZIA: patterns for every ecosystem

  • Add the correct HTTPS hostnames for each client you intercept (reference table).

Important — Request method selection: The HTTP methods to include and exclude in the URL Filtering redirect rule differ per package ecosystem. Using the wrong methods (for example, redirecting POST) will break specific CLI commands. Configure methods exactly as specified in the npm and Python (PyPI) tables.


npm (Node.js)

Zscaler URL Category (npm)

SettingValue
URL to addregistry.npmjs.org (see reference table if you add more hosts)
Request MethodsGET and HEAD only
Excluded MethodsPOST (must NOT be selected)

Why POST must be excluded (npm)

The npm audit command sends POST requests to registry.npmjs.org. If POST requests are included in the URL Filtering redirect rule, npm audit is redirected to Artifactory, which will fail because:

  • npm audit expects a specific response format from the registry
  • npm expects an HTTP 307 redirect to properly forward a POST request (preserving the method and body)
  • Zscaler returns an HTTP 302 for POST requests, which causes the npm client to drop the POST body and fail

By excluding POST from the redirect rule, npm audit traffic passes through Zscaler directly to registry.npmjs.org without interception, allowing it to function normally.

Commands affected by method exclusion (npm)

CommandHTTP MethodRedirected?Notes
npm install <package>GETYesPrimary use case
npm view <package>GETYesPackage metadata
npm auditPOSTNoPasses through to public registry
npm publishPUTNoNot redirected
npm loginGETNoWeb login fails — see npm login and publish caveat

npm login and publish caveat

For users who need to log in and publish packages to the public npm registry (not Artifactory): npm publish works because PUT requests are not redirected. Default npm login (web login) fails because Zscaler intercepts a GET in the login flow.

Workarounds:

  • Option 1: Add a token directly in .npmrc using npm config set (local config only) — works
  • Option 2: Use legacy login: npm login --auth-type legacy — works
  • Avoid: Default npm login (web login) — fails

Anonymous access (npm)

Anonymous permissions and the Zscaler redirect (no end-user Artifactory token) are covered in Step 5: Configure Anonymous Access, Repository Architecture, and the Overview (public packages / private packages behavior). No extra npm-specific anonymous rules here.

Testing (npm)

To verify npm traffic through PTC:

  1. Redirect: Run npm install express --loglevel verbose (or another public package) with ZIA rules active. In the output, confirm GET requests go to your Artifactory hostname / npm virtual API path after the redirect, not only to the public registry.
  2. Artifactory: In the UI, confirm express (and deps) appear in the npm remote cache (e.g. npm-remote-registry).
  3. Curation (optional): Curation > Audit shows an Approved entry for the package when Curation is enabled.
  4. Blocked package (optional): npm install <blocked-package> should fail with a policy violation when blocking policies apply.
  5. POST passthrough: npm audit should still reach the public registry (POST not redirected).

npm installs through PTC are verified when GET traffic reaches Artifactory and npm audit still works.


Python (PyPI)

Zscaler URL Category (Python)

SettingValue
URLs to addpypi.org, files.pythonhosted.org (both are common; confirm in your traffic—reference table)
Request MethodsStart with GET and HEAD only on the redirect rule, same discipline as npm
Excluded MethodsPOST off the redirect unless you have explicitly validated a tool that must be redirected via POST (unusual for simple pip install / uv pip install)

pip, Poetry, and uv mostly use GET for Simple API metadata and artifact downloads, but ecosystem tools evolve—if a command fails after enabling the redirect, inspect method and host in Zscaler and adjust the rule or category.

Trust stores and clients (Python)

Use scripts/README.md for REQUESTS_CA_BUNDLE, UV_NATIVE_TLS, SSL_CERT_FILE, and version-specific notes for pip, Poetry, and uv. The Zscaler trust-store article linked from Prerequisites also applies.

Python 3.13+ and Zscaler Certificate Compatibility

Since Python 3.13, the ssl module enforces stricter certificate validation requirements (RFC 5280 compliance). If your organization's Zscaler deployment uses certificates issued before mid-2024, Python tools that rely on the Python ssl module will fail with TLS errors when running on Python 3.13 or later.

Impact by tool:

ToolPython 3.13+ with old Zscaler certificate
pip ≥ 24.2Works (via truststore — bypasses Python ssl)
uvWorks (Rust TLS — does not use Python ssl)
PoetryBroken (uses httpx → Python ssl)
TwineBroken (uses requests → Python ssl)
CondaBroken (uses requests → Python ssl)

Root cause: Python 3.13 enforces stricter certificate conformance, and older Zscaler root CA certificates may not meet these requirements. For more details, see the Zscaler community discussion on Python 3.13 certificate non-conformance.

Resolution: Contact your Zscaler administrator to deploy the updated Zscaler certificates (released mid-2024 and later), which comply with Python 3.13's stricter requirements. Once the updated certificate is deployed, all Python tools listed above should work correctly.

Configuring Artifactory to Support Poetry for PTC

Poetry (version 1.2.0 and later) is a supported PyPI client for PTC. Because Poetry uses the PyPI Simple API with JSON responses, the Artifactory PyPI remote repository used as the PTC repo_key must have JSON indexing enabled.

To enable JSON indexing on your PyPI repository:

  1. In the Administration module, navigate to Artifactory Settings > Packages Settings.
  2. Under PyPI, select the Enable simple json format checkbox.
  3. Click Save.

JSON indexing is enabled for Poetry and other JSON-aware PyPI clients using the PTC redirect path.

For full details on creating and configuring PyPI repositories and connecting Poetry to Artifactory, see PyPI Repositories in the JFrog documentation.

Anonymous access (PyPI)

Anonymous access configuration is the same across all package managers. See Step 5: Configure Anonymous Access.

Locks and reproducibility (Python)

As with npm, CI that does not traverse PTC may resolve artifacts differently than developer laptops. Align requirements.txt, Poetry, uv.lock, and pip-tools workflows across teams; watch for strict pip install --require-hashes or offline installs that assume direct PyPI URLs.

Testing (Python)

To verify PyPI traffic through PTC:

  1. With ZIA and Artifactory configured for PyPI, run a public install, for example pip install requests or uv pip install requests (use the same tool your teams standardize on).
  2. In Artifactory, confirm the package appears under your PyPI remote or virtual used for reroute.
  3. If Curation is enabled on that remote, check Curation > Audit for an expected decision.

PyPI installs through PTC are verified when packages appear in Artifactory and optional Curation audit entries look correct.


Docker / OCI, Hugging Face, and other types

Docker / OCI: Registry hostnames (Docker Hub, GHCR, etc.) belong in the URL category when those clients are in scope; container trust is not the host OS profile—see Docker and Virtual Environments and Docker’s Using Docker with Zscaler.

Docker / OCI — clients verified by JFrog

The table below is what JFrog has lab-verified for PTC. Other OCI tools are not implied supported unless your JFrog account team confirms them for your subscription and release.

LayerClientsStatus
Container enginesOrbStack, Rancher Desktop, ColimaVerified
Container enginesDocker DesktopArchitecturally equivalent to the verified engines above; not separately lab-verified—treat as supported in principle but validate end-to-end in your environment
CLI clients (on top of any engine above)docker, nerdctlVerified
Daemonless toolscraneVerified
Not supportedPodmanNot supported for PTC as documented here

Exact versions and future additions can change by release—confirm the live matrix with your JFrog account team if your standard is outside the table.

  • Hugging Face: Use Hugging Face Repositories for remote/virtual layout and credentials; add huggingface.co (and any CDN hosts your traces show) to ZIA when that traffic should be redirected. Xet must be disabled on workstations using PTC for Hugging Face (HF_HUB_DISABLE_XET=1). Limitations (gated models, Xet, large-asset behavior): Hugging Face models and registry limitations.



Docker and Virtual Environments

This chapter describes Docker-ecosystem setups aligned with the supported client matrix in Docker / OCI, Hugging Face, and other types. Podman and other engines not listed there are out of scope for this document unless JFrog announces support separately.

Docker containers do not automatically inherit the Zscaler CA certificate from the host workstation. When a container runs npm install (or any package install) and the traffic is intercepted by Zscaler via the host's ZCC, the container will encounter SSL errors because it does not trust the Zscaler certificate.

The certificate must be explicitly added to the container image. You can do this by either baking the CA into the image at build time (e.g., COPY a PEM file and set NODE_EXTRA_CA_CERTS, or install it into the OS trust store) or by mounting the certificate at runtime with matching environment variables.

Note: This is a well-known requirement for any corporate TLS-inspecting proxy, and Docker documents this use case directly. See Docker’s official guide Using Docker with Zscaler for detailed instructions on adding custom CA certificates to images, build contexts, and related configuration so that containers — not only the host — trust inspected traffic.
The patterns below are consistent with Docker’s documentation and tailored specifically for PTC (npm/Node and general OS trust).

Docker Configuration for npm (Node.js)

To ensure a Docker container running npm successfully works with the PTC rerouting solution, add the following to your Dockerfile:

StepDockerfile CommandDescription
1COPY zscaler.pem /zscaler.pemCopies the Zscaler CA certificate file into the container image
2ENV NODE_EXTRA_CA_CERTS=/zscaler.pemInstructs Node.js to trust the copied certificate for secure communication

Example Dockerfile:

FROM node:20
COPY zscaler.pem /zscaler.pem
ENV NODE_EXTRA_CA_CERTS=/zscaler.pem
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]

Where:

  • zscaler.pem: PEM file for the Zscaler root CA (same file used on the host workstation)

The zscaler.pem file must be present in the Docker build context (the same directory as the Dockerfile, or accessible via a path). This is the same PEM file used by the installation script on the host workstation.

Using docker run:

If you prefer to mount the certificate at runtime instead of baking it into the image, you can pass it as a volume mount and environment variable:

docker run \
  -v /opt/certs/package-route.pem:/zscaler.pem:ro \
  -e NODE_EXTRA_CA_CERTS=/zscaler.pem \
  your-image

Using docker-compose:

services:
  app:
    image: your-image
    volumes:
      - /opt/certs/package-route.pem:/zscaler.pem:ro
    environment:
      - NODE_EXTRA_CA_CERTS=/zscaler.pem

General Docker Certificate Installation

For containers that need to trust the Zscaler certificate at the OS level (not just for Node.js), copy the certificate into the container's system trust store and update it:

FROM debian:bookworm
COPY zscaler.pem /usr/local/share/ca-certificates/zscaler.crt
RUN apt-get update && \
    apt-get install -y ca-certificates && \
    update-ca-certificates

This approach is necessary for tools that rely on the system trust store rather than application-specific environment variables (e.g., curl, wget, Python requests without REQUESTS_CA_BUNDLE).

For multi-stage builds, ensure the certificate installation occurs in the final stage so it is present in the runtime image.

See again Using Docker with Zscaler for Docker’s full walkthrough (image CA installation, build context, and product-specific notes). Note: Containers that are already running generally still need the certificate and any required environment variables inside the container namespace; injecting trust only on the host is often insufficient for TLS from within the container. This guide focuses on build-time COPY / RUN update-ca-certificates and explicit runtime volume and environment-variable patterns.

For enterprise proxy and certificate topics beyond Zscaler, refer to Docker’s documentation for your edition (Engine / Desktop) as it applies to your environment.

Virtual Environments

Python virtual environments (venv, virtualenv) on the host workstation inherit the host's environment variables, including REQUESTS_CA_BUNDLE. If the installation script has already configured REQUESTS_CA_BUNDLE in the user's shell profile, pip installs inside virtual environments should work without additional configuration.

Some newer Python builds on macOS and Windows can use the operating system trust store for TLS; in those cases pip may work without REQUESTS_CA_BUNDLE. See scripts/README.md in the PTC repository for version-oriented guidance; always validate in your own image or pilot.

If pip installs inside a virtual environment fail with SSL errors, verify that the REQUESTS_CA_BUNDLE environment variable is set and points to a valid PEM file:

echo $REQUESTS_CA_BUNDLE
openssl x509 -in "$REQUESTS_CA_BUNDLE" -noout -issuer


Frequently Asked Questions

This section provides answers to frequently asked questions about per-package-type configuration for Package Traffic Controller (PTC).

FAQs
Q: Why must npm ZIA rules exclude POST requests?

A: npm audit sends POST to registry.npmjs.org. Redirecting POST breaks audit. Allow only GET and HEAD on the redirect rule. See Why POST must be excluded (npm).

Q: Which Docker container engines are verified for PTC?

A: JFrog has lab-verified OrbStack, Rancher Desktop, Colima, docker, nerdctl, and crane. Podman is not supported. See Docker / OCI — clients verified by JFrog.

Q: How do I make npm work inside Docker containers behind Zscaler?

A: Bake or mount the Zscaler CA and set NODE_EXTRA_CA_CERTS. Containers do not inherit the host trust store automatically. See Docker Configuration for npm (Node.js).

Q: Why is HF_HUB_DISABLE_XET=1 required for Hugging Face?

A: Hugging Face Xet is not supported through the PTC redirect flow. Set the variable on workstations using PTC for Hugging Face. See Limitations and Troubleshooting.

Related Topics