Configure Artifactory for PTC
Configure JFrog Artifactory repositories, anonymous access, and the package-reroute endpoint for Package Traffic Controller (PTC).
JFrog Artifactory Configuration
This section covers the JFrog Artifactory side of the PTC setup: creating repositories, registering each package type with Package Reroute through the REST API, optionally enabling Curation, configuring anonymous access, and verifying the redirect endpoint. Artifactory must be fully configured before ZIA rules are activated (see Deployment Sequence).
Complete the following procedures in order (after Prerequisites):
- Step 1: Create a Remote Repository
- Step 2: Create a Virtual Repository (optional)
- Step 3: Register repositories with Package Reroute (mandatory)
- Step 4: Enable JFrog Curation (optional)
- Step 5: Configure Anonymous Access
- Step 6: Verify the Redirect Endpoint
Repository Architecture
PTC requires the following repository structure:
Remote Repository (proxy + cache layer; Curation optional)
└── Public Registry (upstream source)- Remote Repository: Proxies and caches packages from the upstream public registry. JFrog Curation policies apply at this layer only when Curation is enabled for that remote. For PTC, the remote must allow anonymous Read/Deploy/Cache (per package type) so the virtual can proxy upstream without end-user credentials—and the virtual
repo_keyneeds anonymous Read as the client entry point. See Step 5: Configure Anonymous Access; scope permissions to those repos only. - Virtual Repository (not mandatory): Package Reroute
repo_keyis the top-level repository that receives rerouted traffic — when a virtual exists, this is the virtual (for examplenpm-reroute). The anonymous client hits the virtual first, so the anonymous user needs Read on that virtual. The remote still needs its own anonymous Read/Deploy/Cache rights so the virtual can proxy and cache—configure both in permission targets, not one or the other. There is no separate “virtual is anonymous” product switch; Allow Anonymous Access plus permissions on the virtual and on the backing remote define behavior. Verify with an unauthenticated request against the virtual key you set in Package Reroute.
The Package Reroute repo_key can point to either a remote repository or a virtual repository that includes a remote.
Step 1: Create a Remote Repository
The steps below use npm and registry.npmjs.org as a worked example. For each other package type you support, create a remote repository of the matching package type with that ecosystem’s public registry URL, then wire it into a virtual repository and map each type in the Package Reroute Config API the same way.
To create a remote repository for PTC:
- Navigate to Administration > Repositories > Remote.
- Click New Remote Repository.
- Package Type: Select
npm. - Repository Key: Enter a descriptive name, for example
npm-remote-registry. - URL:
https://registry.npmjs.org - Click Create.
The remote repository is created and ready to include in a virtual repository or map in the Package Reroute Config API.
Step 2: Create a Virtual Repository (optional)
Create a virtual repository that includes the remote repository.
To create a virtual repository for PTC:
- Navigate to Administration > Repositories > Virtual.
- Click New Virtual Repository.
- Package Type: Select
npm. - Repository Key: Enter a descriptive name, for example
npm-virtual-registry. - Repositories: Add
npm-remote-registryto the included repositories. - Click Create.
The virtual repository aggregates the remote and is the typical repo_key target for Package Reroute.
Step 3: Register repositories with Package Reroute (mandatory)
After repositories exist, you must map each package type you enable to an Artifactory repo_key using the Update Registry Configuration API. PTC does not work until this step completes—the Router /package-reroute path needs a configured target repository for each registry type. The API validates that the repository exists before accepting the configuration.
Supported type values for GA are npm, pypi, docker, and huggingfaceml. Repeat the call for every ecosystem you roll out.
To register npm with Package Reroute:
- Choose the repository key that receives rerouted npm traffic—typically the virtual from Step 2 (for example
npm-virtual-registry) or the remote from Step 1 if you have no virtual. - Call
PUT /artifactory/api/package-reroute/config/npmwith that key in the request body. - Confirm the response returns HTTP 200 and the same
repo_key. - Optionally call Get Registry Configuration or Get Full Configuration to verify the mapping.
curl -X PUT "https://<YOUR_ARTIFACTORY_URL>/artifactory/api/package-reroute/config/npm" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"repo_key": "npm-virtual-registry"}'Where:
<YOUR_ARTIFACTORY_URL>: Your JFrog Platform hostname (for exampleacme.jfrog.io)<token>: Admin JWT or use Basic authentication per Package Reroute Config APIrepo_key: The virtual or remote repository key from Step 1 or Step 2
Package Reroute is configured for npm. Repeat PUT /artifactory/api/package-reroute/config/{type} for each additional package type (for example pypi, docker, huggingfaceml) before you enable ZIA rules for those ecosystems.
Resolution Order Best Practice: If a virtual repository contains multiple remote repositories and you use Curation, ensure the curated remote repository is last in the resolution order so curation policies can apply to packages resolved through that virtual.
Step 4: Enable JFrog Curation (optional)
You can skip this step and still use PTC for redirect, proxy, and cache. Enable Curation when you want the JFrog Catalog to evaluate requests (allow/block, CVS, audit) on the configured remotes.
JFrog Curation acts as the perimeter defense for your repositories when turned on. It checks each package request against organizational policies using the JFrog Catalog before allowing the download.
To enable Curation on the remote repository:
- Navigate to Administration > Curation > Curated Repositories and connect the remote repository to Curation.
- Enable Curation for
npm-remote-registry. - Enable the Compliant Version Selection (CVS) flag on the same remote repository. CVS allows Curation to automatically serve the nearest compliant version of a package when the requested version is blocked by policy, maintaining developer flow without manual intervention. See Compliant Version Selection.
Curation is enabled on the remote repository used by PTC.
To configure initial Curation policies:
Recommended initial approach: Start with blocking malicious packages and use dry-run mode for everything else.
- Navigate to Curation > Policies (see Create Policies).
- Create a Block Malicious Packages policy:
- Condition: Malicious package detected
- Action: Block
- Scope: All curated repositories
- Create additional policies in dry-run mode for:
- License compliance (e.g., block GPL-licensed packages)
- Package maturity (e.g., minimum age of 14 days to protect against zero-day attacks)
- CVE severity thresholds
- Monitor the Curation audit log to understand the impact before switching policies from dry-run to blocking.
Policies are in place; monitor audit results before enforcing blocks in production.
"Everybody starts with dry run first of all... do a dry run. So you don't stop anybody at the beginning but implement your policies." — Customer recommendation, RBC session
Step 5: Configure Anonymous Access
PTC currently operates with anonymous access. Redirected requests from Zscaler arrive without end-user Artifactory credentials, so the anonymous principal must be allowed to complete installs through the repository you set as repo_key in Package Reroute.
To configure anonymous access for PTC:
- Navigate to Administration > Security > Settings.
- Enable Allow Anonymous Access (platform setting).
- Assign permissions to the anonymous user for both the virtual (if exists) and the remote
- Virtual (
repo_keyin Package Reroute): Grant Read (minimum) so unauthenticated clients can enter the repository they are redirected into. Ifrepo_keypoints at a remote only (unusual), apply the same idea to that repository key instead. - Remote(s) included in that virtual (from Step 1): Grant Read plus Deploy/Cache (and any other actions required for that package type) so Artifactory can proxy and cache from the public registry on behalf of anonymous.
- Virtual (
- Use permission targets limited to those keys (for example
npm-virtualandnpm-remote-registry), not broad anonymous access across the whole instance. - Verify: From a context with no Artifactory token, exercise the same URL path clients use after redirect (the virtual API URL for your package type) and confirm install or metadata fetch succeeds.
Anonymous users can complete installs through the configured virtual or remote repo_key.
Recommendation: Keep anonymous permission targets scoped to the specific virtual and remote repositories used by PTC, rather than opening anonymous access on unrelated repos.
For more details on configuring anonymous access in JFrog Artifactory, see:
- Allow Anonymous Access
- Anonymous Users — includes how to restrict anonymous access to API-only use and block anonymous users from accessing the Artifactory UI
Restricting anonymous PTC traffic to Zscaler egress
JFrog Cloud (SaaS) only — MyJFrog IP/CIDR allowlist
The MyJFrog portal IP/CIDR allowlist is a JFrog Cloud control. It does not apply to typical self-hosted Artifactory deployments; on self-hosted, use your own firewall, reverse proxy, WAF, or network policy to limit which source IPs can reach Artifactory’s HTTPS endpoint (for example allow Zscaler egress ranges your ZIA admin provides). For cloud security options and UI locations, see JFrog’s documentation: Configure cloud security.
For JFrog Cloud, adding Zscaler’s public egress ranges to the allowlist helps ensure anonymous PTC traffic is only accepted from paths that traverse Zscaler (tighten further with your network design as needed):
- Only requests from allowlisted source addresses can reach the instance (per MyJFrog rules).
- Direct anonymous access from arbitrary networks can be blocked when combined with your IP policy.
- Reduces exposure from enabling anonymous repository access for the redirect flow.
MyJFrog setup (cloud):
- Log in to my.jfrog.com.
- Open the Security area of the portal for your JFrog Cloud subscription. In current layouts, the IP/CIDR allowlist (or IP allowlist) is configured from Security, not from a separate “select Artifactory instance” screen—if you only see subscription or environment choices first, pick the one that contains your
*.jfrog.iotenant, then go to Security. - In Security, locate the allowlist control and add Zscaler egress ranges in CIDR notation (e.g.,
100.101.128.0/17). Obtain your organization’s ranges from the Zscaler Admin Portal or your Zscaler team. - Save or apply the change.
Tab names and menu paths change between portal releases; use JFrog’s Configure cloud security for authoritative steps and screenshots if the UI does not match the list above.
Step 6: Verify the Redirect Endpoint
The /package-reroute entry point on the JFrog Router is where Zscaler-redirected client traffic lands. It is product-defined and not customer-configurable. You can validate it before ZIA is enabled by calling Artifactory directly with the same query shape Zscaler will append (url= original registry URL, percent-encoded).
To verify the package-reroute redirect endpoint:
Build https://<hostname>/package-reroute?url=<percent-encoded-upstream-url> using your Artifactory hostname. Percent-encode the value of url (for https://registry.npmjs.org/express use https%3A%2F%2Fregistry.npmjs.org%2Fexpress). Example (fictional tenant acme.jfrog.io):
curl -v "https://<YOUR_ARTIFACTORY_URL>/package-reroute?url=https%3A%2F%2Fregistry.npmjs.org%2Fexpress"Where:
<YOUR_ARTIFACTORY_URL>: Your JFrog Platform hostname (for exampleacme.jfrog.io)
Use your own hostname; the Router path is /package-reroute unless your JFrog release notes specify otherwise. If an encoded url still fails in your shell, try single-quoting the full URL or passing --data-urlencode via curl -G with a base URL that has no query string yet—see curl documentation for your platform.
Expected (correct behavior): HTTP 302 or 307 with a Location header pointing to an Artifactory URL (typically under /artifactory/ and your configured npm virtual / API layout for the express package—not still on registry.npmjs.org). Do not use curl -L here if you only want to inspect this first hop.
If something looks wrong:
- 401 / 403: Anonymous or Router access may not be configured yet—complete Step 5: Configure Anonymous Access and permission targets, then retry.
- 404 / wrong path: Confirm ZIA’s redirect URL uses
/package-rerouteon your Artifactory host and that you completed Step 3: Register repositories with Package Reroute. Use Get Full Configuration (GET /artifactory/api/package-reroute/config) or Get Registry Configuration to confirmrepo_keyfornpmis set—that API does not return or change the Router redirect path. See the Package Reroute Config API overview. - Very long
url=values: Some clients require URL-encoding theurlquery parameter; if the bare string fails, encode the registry URL portion.
A successful test returns HTTP 302 or 307 with a Location header pointing at your Artifactory repository path.
Package reroute logs (Artifactory)
When traffic follows PTC, JFrog Artifactory records each package reroute event in system logs. The product implementation surfaces in logs as PackageRerouteResource (Java class). These entries are useful for security operations, support, and consumption analysis: you can confirm that installs went through Artifactory, which registry type was involved, what public URL the client originally requested, where Artifactory sent the client next, and which client stack made the call.
Where to view them
- In the JFrog Platform UI, open Administration.
- Go to Monitoring → Artifactory Logs (path names can vary slightly by release; the goal is the Artifactory log viewer under administration / monitoring).
- Select
artifactory-service.log(or download it for offline search).
You can pause, refresh, or download the log file depending on UI options. Large files are normal on busy instances.
Example line (npm)
2026-04-28T08:48:37.574Z [jfrt ] [INFO ] [5133f38050b3a8fab28558dbac15d947] [.p.r.PackageRerouteResource:99] [7.0.0.1-8081-exec-13] - Reroute: method=GET [email protected] registry=npm original=https://registry.npmjs.org/mcp-remote target=https://jfrogrepo24.jfrog.io/artifactory/api/npm/npm-virtual/mcp-remote userAgent=npm/11.12.1 node/v25.9.0 darwin arm64 workspaces/falseWhat each part means (customer-facing)
| Fragment | Meaning |
|---|---|
| Leading timestamp | Request time in UTC (ISO-8601). |
[jfrt ] / [INFO ] | Artifactory service tag and log level. |
| Bracketed hex id | Trace / correlation identifier for that request (useful when matching to other log lines or support cases). |
[.p.r.PackageRerouteResource:…] | Package reroute code path (technical name: reroute / package reroute). |
method=GET | HTTP method used for the reroute-related request (most package metadata and tarball flows use GET). |
user=… | Identity associated with the request as Artifactory logs it—for example a corporate email. In Zscaler-integrated environments this often corresponds to the user behind the intercepted client, which helps teams attribute activity to a person or account. Exact values depend on your identity, SSO, and anonymous-access configuration. |
registry=… | Package ecosystem for this reroute (for example npm, pypi, docker—aligned with how Package Reroute is configured). |
original=… | Upstream URL the client intended (the public registry URL before Artifactory’s reroute logic applied—for example https://registry.npmjs.org/...). |
target=… | Artifactory URL the client is sent toward after reroute (typically your virtual npm API path under /artifactory/api/npm/<repo>/...). |
userAgent=… | Package manager and runtime fingerprint (for example npm version, Node version, OS, architecture). Helps reproduce issues and spot outdated or unexpected clients. |
Scoped packages and paths with special characters appear URL-encoded in log lines (for example %2f for / in scoped npm names), which is normal.
Why this matters for customers
- Audit and forensics: Prove that a given install attempt flowed through your governed Artifactory path, not only direct-to-registry.
- Triage: Compare
originalvstargetwhen a redirect or repository mapping looks wrong. - Client hygiene: Use
userAgentto identify old npm/pip/Docker clients after policy changes. - Ownership: Combine
user=with your Zscaler and IdP practices to align network identity with package consumption—keeping in mind that JFrog documents Artifactory behavior; Zscaler documents ZIA, groups, and SSL inspection. - Dependency installs: A
PackageRerouteResourceline usually reflects the top-level request; further dependency fetches may show as normal repository traffic—use Artifactory and Zscaler logs together if you need full-tree attribution.
Frequently Asked Questions
This section provides answers to frequently asked questions about configuring JFrog Artifactory for Package Traffic Controller (PTC).
FAQs
Q: Is the Package Reroute API call mandatory for PTC?
A: Yes. You must call PUT /artifactory/api/package-reroute/config/{type} for each package type you enable before ZIA redirects traffic. See Step 3: Register repositories with Package Reroute (mandatory).
Q: Can Package Reroute repo_key point to a remote or a virtual repository?
repo_key point to a remote or a virtual repository?A: Either. A virtual that includes the remote is the typical entry point; a remote-only repo_key is valid when you have no virtual. See Repository Architecture.
Q: Why does PTC require anonymous access on Artifactory?
A: Zscaler redirect requests arrive without end-user Artifactory credentials. The anonymous principal must have Read (and remote Deploy/Cache where required) on the repo_key repositories. See Step 5: Configure Anonymous Access.
Q: What HTTP response should I expect from /package-reroute?
/package-reroute?A: A successful test returns HTTP 302 or 307 with a Location header pointing at your Artifactory repository path—not the public registry hostname. See Step 6: Verify the Redirect Endpoint.
Related Topics
Updated 2 days ago
