Artifactory Configuration

Artifactory Integration Guide

Complete guide for integrating Socket Registry Firewall with JFrog Artifactory. Supports auto-discovery of repositories and four deployment topologies.

Overview

Socket Registry Firewall integrates with Artifactory to protect package ingestion and distribution. The firewall can automatically discover and sync repository configurations from Artifactory, eliminating manual route configuration.

Supported Artifactory repository types:

Artifactory Package TypeFirewall RegistryFirewall URL PathNotes
npmnpm/artifactory/api/npm/<repo>
pypipypi/artifactory/api/pypi/<repo>
mavenmaven/artifactory/<repo>Direct path — no /api/ prefix
gradlemaven/artifactory/<repo>Maven layout; see cooldown for non-Maven-Central hosts
cargocargo/artifactory/<repo>Direct path
gemsrubygems/artifactory/api/gems/<repo>
nuget (v2)nuget/artifactory/api/nuget/<repo>
nuget (v3)nuget/artifactory/api/nuget/v3/<repo>Used for repository keys containing v3
gogo/artifactory/api/go/<repo>Requires a virtual repository in front
condaconda/artifactory/<repo>Direct path; experimental — scanned as PyPI
huggingfacemlhuggingface/artifactory/api/huggingfaceml/<repo>Requires version 2.0.9 or higher

Important: Artifactory smart remotes require the per-ecosystem path shown above. Using a different path triggers Artifactory's warning: "Smart repository detected. URL format missing /api/<package_name>/"

📝 HuggingFace repositories are discovered from Artifactory only. Nexus auto-discovery does not route HuggingFace repositories.

📝 OpenVSX is not auto-discovered from Artifactory or Nexus. Define an OpenVSX route manually under path_routing.routes.

Package types Socket does not scan natively (Docker, Helm, generic, and others) can still be protected with External Registry Cooldown, which blocks recently published packages based on their publish date.


Deployment Topologies

1. Direct Deployment (Baseline — No Firewall)

Standard Artifactory setup with no security scanning. Remote repositories connect straight to the public registries. Use it as the "before" picture when comparing against the topologies below.

Developer / CI  --->  Artifactory  --->  Public Registry
                      (caching)          (npmjs.org, pypi.org)
EcosystemArtifactory Remote URLNotes
npmhttps://registry.npmjs.org
PyPIhttps://files.pythonhosted.orgPyPI Registry URL: https://pypi.org
Mavenhttps://repo1.maven.org/maven2/
Gradlehttps://plugins.gradle.org/m2/
Cargohttps://index.crates.io/Git Registry URL: https://index.crates.io/
RubyGemshttps://rubygems.org/
NuGet v3https://api.nuget.org/v3/index.jsonV3 Feed URL: same value
NuGet v2https://www.nuget.org/
Gohttps://proxy.golang.org/Needs a virtual repository in front
Condahttps://repo.anaconda.com/pkgs/main/

2. Upstream Deployment (Most Common)

Artifactory remote repositories pull packages through the firewall. Developers and CI use Artifactory directly.

Developer / CI  --->  Artifactory  --->  Socket Firewall  --->  Public Registry
                      (caching)                                   (npmjs.org, pypi.org)

Benefits:

  • Single enforcement point
  • No developer config changes needed
  • Artifactory caches packages (most installs don't hit firewall)
  • Centralized security for entire organization

Use when:

  • You already have Artifactory deployed
  • Developers are already configured to use Artifactory
  • You want to protect package ingestion from public registries

See Upstream Deployment Setup →


3. Downstream Deployment

Developers and CI point at the firewall, which proxies to Artifactory (which may or may not have its own upstream).

Developer / CI  --->  Socket Firewall  --->  Artifactory  --->  Public/Internal Registry

Benefits:

  • Protect developer workstations directly
  • Works with Artifactory virtual repos or local repos
  • Can layer on top of existing Artifactory setup

Use when:

  • You want to protect specific teams or projects
  • You have Artifactory hosting internal packages
  • You want an additional security layer beyond Artifactory

See Downstream Deployment Setup →


4. Middle Deployment (Multi-Tier)

Firewall sits between two Artifactory instances (e.g., On-Premise → Production, Regional → Central).

On-Premise Artifactory  --->  Socket Firewall  --->  Artifactory Production
(Virtual Repo)                                       (Remote Repo)

Benefits:

  • Scan packages flowing between internal registries
  • Supports Artifactory virtual repos aggregating remote repos
  • Protects multi-tier Artifactory topologies

Use when:

  • You have multiple Artifactory instances (On-Premise/Prod, Regional/Central)
  • Packages flow between Artifactory instances
  • You need to scan internal package distribution

See Middle Deployment Setup →


Auto-Discovery Configuration

Socket Firewall can automatically discover all Artifactory remote repositories and create firewall routes without manual configuration.

Basic Auto-Discovery

path_routing:
  enabled: true
  domain: socket-firewall.company.com
  
  private_registry:
    api_url: https://artifactory.company.com/artifactory
    api_key: your-artifactory-api-key  # Or use env var ARTIFACTORY_API_KEY
    mode: artifactory
    interval: 5m  # Auto-sync every 5 minutes

Routes are discovered from Artifactory and updated automatically. No need to manually define each route!

Advanced Auto-Discovery

path_routing:
  enabled: true
  domain: socket-firewall.company.com
  
  private_registry:
    api_url: https://artifactory.company.com/artifactory
    api_key: your-artifactory-api-key    # Token auth (takes precedence)
    mode: artifactory
    # OR use basic auth with separate fields:
    username: admin                      # Basic auth username
    password: secret                     # Basic auth password
    interval: 5m                         # Sync interval (30s, 5m, 1h, etc.)
    ignore_ssl_errors: true              # Disable verification of SSL when connecting to the Private Registry
    include_pattern: "^(npm|pypi|maven)-.*"      # Only npm/pypi/maven repos
    exclude_pattern: "(tmp|test|snapshot)-.*"     # Exclude temp/test repos
    supported_ecosystems_only: true      # Skip unsupported package types (default: true)
    include_virtual: false               # Include VIRTUAL repos (default: false)

Leave include_virtual at false unless clients route through a virtual repository directly — the member repositories behind a virtual aggregator are discovered individually, and each keeps its own host allowlist and cooldown checks. See include_virtual and supported_ecosystems_only in the Configuration Reference.

How Auto-Discovery Works

  1. Firewall calls Artifactory REST API: GET /api/repositories
  2. Filters for the repository types it routes: REMOTE, LOCAL, FEDERATED, and DISTRIBUTION. VIRTUAL repositories are included only when include_virtual: true
  3. Parses repository list and extracts:
    • Repository key (name)
    • Package type (npm, pypi, maven, etc.)
    • Repository type (REMOTE, LOCAL, FEDERATED, DISTRIBUTION, or VIRTUAL)
  4. For REMOTE repositories, checks the remote URL against the known public registry hosts for that ecosystem. A repository proxying any other host gets a cooldown route when External Registry Cooldown is enabled, and no route otherwise
  5. Creates firewall routes for each discovered repository — both the ecosystem API path (/artifactory/api/{package-type}/{repo-key}) and the direct path (/artifactory/{repo-key}), so Artifactory smart remotes work with either URL form
  6. Generates nginx configuration with discovered routes
  7. Repeats on interval, adding/removing routes as repositories change

Service Account Permissions for Auto-Discovery

Auto-discovery calls the Artifactory REST API to list repositories. The service account used for authentication needs read-only access to the repository listing endpoint.

API endpoint used: GET /api/repositories

This endpoint returns the key, package type, repository type, and URL of every repository the authenticated user can see. No write operations are performed — the firewall only reads repository metadata to generate routes.

Minimum-Privilege Setup (Recommended)

Create a dedicated service account with the minimum permissions required:

  1. Create a group in Artifactory:

    • Go to Administration → Identity & Access → Groups → New Group
    • Group Name: socket-firewall-discovery
    • Auto Join: No
  2. Create a permission target:

    • Go to Administration → Identity & Access → Permissions → New Permission
    • Name: socket-firewall-read
    • Resources → Repositories: Select Any Repository (or only the repositories you want the firewall to discover)
    • Groups: Add socket-firewall-discovery with Read permission only
    • Do not grant Deploy, Annotate, Delete, or Manage
    • Save
  3. Create a local user:

    • Go to Administration → Identity & Access → Users → New User
    • Username: socket-firewall
    • Status: Enabled
    • Groups: Add to socket-firewall-discovery
    • Save
  4. Generate an API key (preferred over password):

    • Log in as the new user
    • Go to Edit Profile → API Key → Generate
    • Use this key as api_key in socket.yml

    Alternatively, generate an Access Token (Artifactory 7.x+):

    • Go to Administration → Identity & Access → Access Tokens → Generate Token
    • Token Scope: User socket-firewall
    • Use the token as api_key in socket.yml

Artifactory Permission Reference

PermissionPurposeRequired?
ReadRead/list repositories and their metadataYes
DeployUpload artifactsNo — not needed
AnnotateAdd/modify properties on artifactsNo — not needed
DeleteDelete artifacts or repositoriesNo — not needed
ManageAdminister permissions and settingsNo — not needed

Note (Artifactory Cloud / SaaS): If you use Artifactory Cloud (JFrog Platform), the same permissions apply. Use a scoped Access Token with read-only permissions. Navigate to Administration → Identity & Access → Access Tokens to generate one.

Verifying Permissions

Test that the service account can list repositories:

# Using API key
curl -H "X-JFrog-Art-Api: your-api-key" \
  https://artifactory.company.com/artifactory/api/repositories

# Using basic auth (username:password)
curl -u "socket-firewall:password" \
  https://artifactory.company.com/artifactory/api/repositories

# Using Access Token (Artifactory 7.x+)
curl -H "Authorization: Bearer your-access-token" \
  https://artifactory.company.com/artifactory/api/repositories

# Expected: JSON array of repository objects
# [{"key": "npm-remote", "type": "REMOTE", "packageType": "npm", "url": "..."}, ...]

If the response is 401 Unauthorized, the API key or token is invalid. If it returns 403 Forbidden, the user lacks the Read permission on repositories. If it returns an empty list, the permission target may be scoped too narrowly — ensure it includes the repositories you want to discover.


Upstream Deployment Setup

Protect package ingestion by pointing Artifactory remote repos at the firewall.

Step 1: Deploy Socket Firewall

socket.yml:

socket:
  api_url: https://api.socket.dev

ports:
  http: 8080
  https: 8443

# Upstream topology - Artifactory -> firewall -> public registry

path_routing:
  enabled: true
  domain: socket-firewall.internal.company.com
  config_mode: upstream
  
  private_registry:
    api_url: https://artifactory.company.com/artifactory
    api_key: ${ARTIFACTORY_API_KEY}
    mode: artifactory  # Auto-discovery
    interval: 5m
    exclude_pattern: "(tmp|test)-.*"

nginx:
  worker_processes: 4
  worker_connections: 8192

docker-compose.yml:

services:
  socket-firewall:
    image: socketdev/socket-registry-firewall:latest
    ports:
      - "8080:8080"
      - "8443:8443"
    environment:
      - SOCKET_SECURITY_API_TOKEN=${SOCKET_SECURITY_API_TOKEN}
      - ARTIFACTORY_API_KEY=${ARTIFACTORY_API_KEY}
    volumes:
      - ./socket.yml:/app/socket.yml:ro
      - ./ssl:/etc/nginx/ssl
    restart: unless-stopped

Start:

docker compose up -d
curl -k https://socket-firewall.internal.company.com:8443/health

Step 2: Configure Artifactory Remote Repositories

In Administration → Repositories → Remote, edit each remote repository and replace the public registry URL with the firewall URL for that ecosystem. Substitute your own repository key for the example keys.

Important: Each ecosystem has its own path form. Artifactory reports "Smart repository detected. URL format missing /api/<package_name>/" when the URL uses the wrong form, and several ecosystems fail outright.

EcosystemFirewall URLOther settings that matter
npmhttps://socket-firewall:8443/artifactory/api/npm/npm-remoteRepository Layout: npm-default
PyPIhttps://socket-firewall:8443/artifactory/api/pypi/pypi-remotePyPI Registry URL: the same firewall URL; Repository Suffix: simple; Repository Layout: simple-default
Mavenhttps://socket-firewall:8443/artifactory/maven-central-remoteRepository Layout: maven-2-default; Handle Releases: Yes; Handle Snapshots: Yes; Suppress POM Consistency Checks: Yes
Gradlehttps://socket-firewall:8443/artifactory/gradle-plugins-remoteRepository Layout: maven-2-default; Handle Releases: Yes; Handle Snapshots: Yes
Cargohttps://socket-firewall:8443/artifactory/cargo-remoteGit Registry URL: the same firewall URL; Repository Layout: cargo-default; Anonymous Access: Yes
RubyGemshttps://socket-firewall:8443/artifactory/api/gems/gems-remoteRepository Layout: simple-default
NuGet v3https://socket-firewall:8443/artifactory/api/nuget/v3/nuget-v3-remoteV3 Feed URL: the same firewall URL; Feed Context Path: api/v2; Download Context Path: api/v2/package; Repository Layout: nuget-default
NuGet v2https://socket-firewall:8443/artifactory/api/nuget/nuget-v2-remoteFeed Context Path: api/v2; Download Context Path: api/v2/package; Repository Layout: nuget-default
Gohttps://socket-firewall:8443/artifactory/api/go/go-remoteVCS Git Provider: GITHUB; Repository Layout: go-default; requires a virtual repository wrapping the remote
Condahttps://socket-firewall:8443/artifactory/conda-main-remoteRepository Layout: simple-default
HuggingFacehttps://socket-firewall:8443/artifactory/api/huggingfaceml/hf-remoteRequires firewall version 2.0.9 or higher

Note: Maven, Gradle, Cargo, and Conda use the direct path (/artifactory/<repo>). Every other ecosystem uses the /api/<type>/ prefix.

Step 3: Common Settings for All Remotes

Apply these to every remote repository that points at the firewall:

SettingValueReason
Allow Any Host AuthYesRequired for Artifactory smart remote authentication
Store Artifacts LocallyYesCaches scanned packages so repeat installs skip the firewall
Verify SSL CertificateYes (No for testing)Add the firewall's CA to Artifactory's trust store in production rather than disabling verification

Step 4: Test

Test npm:

# Developers use Artifactory as normal
npm config set registry https://artifactory.company.com/artifactory/api/npm/npm-remote/
npm install lodash

# Check firewall logs
docker compose logs socket-firewall | grep lodash

Test PyPI:

pip config set global.index-url https://artifactory.company.com/artifactory/api/pypi/pypi-remote/simple
pip install requests

docker compose logs socket-firewall | grep requests

Step 5: Verify Auto-Discovery

Check that the firewall discovered your Artifactory repositories:

# View discovered routes
docker compose exec socket-firewall cat /app/discovered-routes.yml

# Check logs for discovery events
docker compose logs socket-firewall | grep "Discovered.*repositories"

Downstream Deployment Setup

Developers point at the firewall, which proxies to Artifactory.

Step 1: Define Routes

socket.yml:

socket:
  api_url: https://api.socket.dev

ports:
  http: 8080
  https: 8443

# Downstream topology (default) - client -> firewall -> Artifactory

path_routing:
  enabled: true
  domain: firewall.company.com
  config_mode: downstream
  
  routes:
    # Point to Artifactory virtual or remote repos
    - path: /npm
      upstream: https://artifactory.company.com/artifactory/api/npm/npm-virtual
      registry: npm
      
    - path: /pypi
      upstream: https://artifactory.company.com/artifactory/api/pypi/pypi-virtual
      registry: pypi
      
    - path: /maven
      upstream: https://artifactory.company.com/artifactory/maven-central-virtual
      registry: maven
      
    - path: /gradle
      upstream: https://artifactory.company.com/artifactory/gradle-plugins-virtual
      registry: maven
      
    - path: /cargo
      upstream: https://artifactory.company.com/artifactory/cargo-virtual
      registry: cargo
      
    - path: /rubygems
      upstream: https://artifactory.company.com/artifactory/api/gems/gems-virtual
      registry: rubygems
      
    - path: /nuget
      upstream: https://artifactory.company.com/artifactory/api/nuget/v3/nuget-v3-virtual
      registry: nuget
      
    - path: /go
      upstream: https://artifactory.company.com/artifactory/api/go/go-virtual
      registry: go
      
    - path: /conda
      upstream: https://artifactory.company.com/artifactory/conda-virtual
      registry: conda

Step 2: Upstream URL Patterns

Each route's upstream must use the Artifactory path form for its ecosystem:

EcosystemRoute upstream FormatExample
npm/artifactory/api/npm/<repo>/artifactory/api/npm/npm-virtual
PyPI/artifactory/api/pypi/<repo>/artifactory/api/pypi/pypi-virtual
Maven/artifactory/<repo>/artifactory/maven-central-virtual
Gradle/artifactory/<repo>/artifactory/gradle-plugins-virtual
Cargo/artifactory/<repo>/artifactory/cargo-virtual
RubyGems/artifactory/api/gems/<repo>/artifactory/api/gems/gems-virtual
NuGet v3/artifactory/api/nuget/v3/<repo>/artifactory/api/nuget/v3/nuget-v3-virtual
NuGet v2/artifactory/api/nuget/<repo>/artifactory/api/nuget/nuget-v2-virtual
Go/artifactory/api/go/<repo>/artifactory/api/go/go-virtual
Conda/artifactory/<repo>/artifactory/conda-virtual

Note: Maven, Gradle, Cargo, and Conda use direct paths. Every other ecosystem needs the /api/<type>/ prefix.

Step 3: Client Configuration

Developers point at the firewall instead of Artifactory:

# npm
npm config set registry https://firewall.company.com/npm/

# PyPI
pip config set global.index-url https://firewall.company.com/pypi/simple

# Maven (settings.xml)
# <mirror>
#   <id>firewall</id>
#   <url>https://firewall.company.com/maven/</url>
#   <mirrorOf>central</mirrorOf>
# </mirror>

# Cargo (.cargo/config.toml)
# [registries.firewall]
# index = "https://firewall.company.com/cargo/"

# Go
export GOPROXY=https://firewall.company.com/go/,direct

# RubyGems
gem sources --add https://firewall.company.com/rubygems/ --remove https://rubygems.org/

# NuGet
dotnet nuget add source https://firewall.company.com/nuget/ -n firewall

# Conda
conda config --set custom_channels.main https://firewall.company.com/conda/

Middle Deployment Setup

Firewall sits between two Artifactory instances: the on-premise instance's remote repositories point through the firewall at the upstream (cloud) instance, which connects to the public registries.

On-Prem Artifactory  --->  Socket Firewall  --->  Cloud Artifactory  --->  Public Registry

Step 1: Configure the Firewall for Middle Topology

Point auto-discovery at the upstream (cloud) Artifactory instance.

socket.yml:

socket:
  api_url: https://api.socket.dev

ports:
  http: 8080
  https: 8443

# Middle topology - Artifactory -> firewall -> Artifactory

path_routing:
  enabled: true
  domain: socket-firewall.internal.company.com
  config_mode: middle
  
  private_registry:
    api_url: https://artifactory-prod.company.com/artifactory
    api_key: ${ARTIFACTORY_API_KEY}
    mode: artifactory  # Auto-discovery from the upstream Artifactory
    interval: 5m

nginx:
  worker_processes: 4
  worker_connections: 8192

With config_mode: middle, auto-discovery applies mode: proxy to the ecosystems that rewrite URLs inside package metadata — pypi, conda, npm, and nuget. Every other discovered ecosystem uses mode: rewrite. To define routes by hand instead, set mode: proxy per route:

path_routing:
  routes:
    - path: /pypi
      upstream: https://artifactory-prod.company.com/artifactory/api/pypi/pypi-remote
      registry: pypi
      mode: proxy

Why mode: proxy matters:

  • The upstream Artifactory returns relative URLs like ../../packages/xyz/file.tar.gz
  • mode: proxy passes these URLs through unchanged
  • The on-premise Artifactory resolves relative URLs against its own base path
  • mode: rewrite would rewrite them to firewall paths, which the on-premise instance cannot resolve

Step 2: Configure On-Premise Remote Repositories

Point each on-premise remote repository at the firewall, using the same per-ecosystem URL forms and common settings as Step 2 and Step 3 of the upstream setup. The repository key in the URL is the key of the matching repository on the upstream instance.

Go additionally requires a virtual repository wrapping the remote on both Artifactory instances.

Step 3: Create Virtual Repositories On-Premise

For each ecosystem, create an on-premise virtual repository that aggregates the firewall-facing remote (external packages, scanned) plus any local repositories (internal packages). Developers point at these virtual repositories.

EcosystemVirtual RepoIncludes RemoteIncludes Local
npmnpm-virtualnpm-remotenpm-local
PyPIpypi-virtualpypi-remotepypi-local
Mavenmaven-virtualmaven-central-remotemaven-local
Gogo-virtualgo-remotego-local

Step 4: Test the Chain

# From the on-premise Artifactory, check firewall connectivity
curl -k https://socket-firewall.internal.company.com:8443/health

# Install through the on-premise virtual repo
npm config set registry https://artifactory.company.com/artifactory/api/npm/npm-virtual/
npm install lodash

# Confirm the firewall scanned it
docker compose logs socket-firewall | grep lodash

Troubleshooting

Artifactory Can't Reach Firewall

Symptom: Artifactory shows connection errors when fetching packages

Check:

# From Artifactory server, test connectivity
curl -k https://socket-firewall.internal.company.com:8443/health

# Check DNS resolution
nslookup socket-firewall.internal.company.com

# Check firewall from Artifactory
ping socket-firewall.internal.company.com

Solution:

  • Verify DNS record points to firewall host
  • Ensure firewall ports (8080/8443) are accessible from Artifactory
  • Check firewall rules/security groups

SSL Certificate Errors

Symptom: Artifactory logs show SSL verification errors

Option 1 - Trust firewall cert in Artifactory:

# Copy firewall cert to Artifactory server
scp ssl/fullchain.pem artifactory-server:/tmp/socket-firewall.crt

# Add to Artifactory's Java trust store
keytool -import -alias socket-firewall \
  -keystore $JAVA_HOME/lib/security/cacerts \
  -file /tmp/socket-firewall.crt \
  -storepass changeit

# Restart Artifactory

Option 2 - Disable SSL verification (testing only):

  • In Artifactory remote repo settings, uncheck "Verify SSL Certificate"

Auto-Discovery Not Finding Repositories

Check Artifactory API access:

# Test API connectivity
curl -H "X-JFrog-Art-Api: your-api-key" \
  https://artifactory.company.com/artifactory/api/repositories

# Should return JSON list of repositories

Check firewall logs:

docker compose logs socket-firewall | grep -i discovery
docker compose logs socket-firewall | grep -i artifactory

Common issues:

  • API key lacks permissions (needs "Read" on repositories)
  • api_url incorrect (should end with /artifactory, not include /api)
  • Network connectivity from firewall to Artifactory
  • The repository is VIRTUAL and include_virtual is false (the default) — its member repositories are discovered instead
  • A REMOTE repository proxies a host that is not a known public registry for its ecosystem (a private Artifactory, an internal mirror, or a service such as Google AOSS). Such repositories get a cooldown route when External Registry Cooldown is enabled and no route otherwise. Gradle repositories are checked against the Maven hosts, so a Gradle remote proxying plugins.gradle.org needs a cooldown entry
  • Set log_level: debug to confirm — skipped repositories are reported only at debug level

See the supported_ecosystems_only and include_virtual sections of the Configuration Reference for the full matrix of what gets a route.

Virtual Repo Doubled URLs

Symptom: Artifactory virtual repos return URLs like /artifactory/api/pypi/pypi-virtual/artifactory/api/pypi/pypi-remote/packages/...

Solution: Use config_mode: middle and mode: proxy:

path_routing:
  config_mode: middle
  routes:
    - path: /pypi
      upstream: https://artifactory.company.com/artifactory/api/pypi/pypi-remote
      registry: pypi
      mode: proxy  # Critical - prevents URL rewriting

Package Downloads Failing

Check firewall is blocking correctly:

# Try to install known malicious package
npm install some-malicious-package

# Check firewall logs for block
docker compose logs socket-firewall | grep -i block

Check firewall is allowing correct packages:

# Install known safe package
npm install lodash

# Should succeed - check logs
docker compose logs socket-firewall | grep lodash

Private npm Packages Return 404 While Public Packages Install

Symptom: the client reports a 404 against the public registry, such as GET https://registry.npmjs.org/@scope/private-pkg/-/private-pkg-1.0.0.tgz: Not Found, together with "No authorization header was set for the request".

Cause: the download URL reached the client without being rewritten, so the client contacted the public registry directly instead of the firewall — and without your credentials.

Check that the metadata the firewall returns points back at the firewall:

curl -s -H "Authorization: Basic $SOCKET_AUTH_B64" \
  'https://firewall.company.com/npm/@scope%2fprivate-pkg' \
  | grep -o '"tarball":"[^"]*"' | head -3

Every tarball URL should name your firewall host. Public packages mask this condition: their un-rewritten downloads still succeed, but they reach the client unscanned — so treat a public-registry URL here as a problem even when installs appear to work.

Tarball URL rewriting across all npm metadata content types and encodings requires version 2.0.12 or higher.


Best Practices

Repository Naming

Use consistent naming in Artifactory to simplify filtering:

  • npm-public - Public npm registry
  • npm-internal - Internal npm packages
  • pypi-public - Public PyPI registry
  • pypi-internal - Internal Python packages

Then use filters:

include_pattern: ".*-public"  # Only protect public-facing repos
exclude_pattern: ".*-internal"  # Don't scan internal packages

Caching Strategy

Artifactory caching + Firewall caching = Maximum efficiency:

  1. Artifactory caches packages after first fetch
  2. Firewall caches verdicts, refreshing every 10 minutes for downloads and every hour for metadata checks by default; a stale verdict can still be served for up to 24 hours if the Socket API is unreachable
  3. Subsequent installs hit Artifactory cache (never reach firewall)
  4. New packages hit firewall once, then cached by both

Result: Minimal latency overhead after initial fetch

📝 See Configuration Reference for the full set of cache TTL options.

Monitoring

Monitor both Artifactory and Firewall:

Artifactory:

  • Monitor remote repository health
  • Check artifact download counts
  • Review failed download requests

Firewall:

  • Monitor block events (malicious packages)
  • Check API error rates
  • Review cache hit rates

Splunk integration (recommended):

splunk:
  enabled: true
  hec_url: https://splunk.company.com:8088/services/collector/event
  hec_token: ${SPLUNK_HEC_TOKEN}
  index: security
  source: socket-firewall-artifactory

Webhook integration (any HTTP endpoint):

webhook:
  enabled: true
  url: https://siem.company.com/api/events
  auth_header: "Bearer ${WEBHOOK_TOKEN}"
  on_block: true
  on_warn: true
  # Optional: batch events as NDJSON instead of one POST per event
  batch_enabled: true
  batch_size: 524288    # flush at 512KB
  batch_period: 5       # or every 5 seconds

See Delivery Modes for how batching affects delivery guarantees.

Prometheus metrics:

The firewall always serves GET /metrics on a dedicated port (metrics_port, default 9145). This listener is exempt from the bearer_token client auth gate, so restrict access to it at the network layer with nginx allow/deny rules or a Kubernetes NetworkPolicy. For these topologies the most useful families are the upstream-latency and firewall-overhead histograms, the circuit-breaker state gauges, socket_redis_available, and the cache hit and stale-serve counters.

The /metrics exemption from the client auth gate requires version 2.0.7 or higher.

High Availability

For production deployments:

  1. Multiple firewall instances with shared Redis cache:

    services:
      socket-firewall-1:
        # ... firewall config
      socket-firewall-2:
        # ... firewall config
      redis:
        # ... shared Redis
  2. Load balancer in front of firewall instances

  3. Artifactory remote repo points to load balancer VIP

Security Hardening

  1. Use proper TLS certificates (not self-signed in production)
  2. Rotate API keys regularly
  3. Limit Artifactory API key permissions to read-only repositories
  4. Use fail_open: false in production for maximum security
  5. Monitor and alert on block events

External Registry Cooldown for Unsupported Repos

Artifactory often hosts repositories whose package types Socket does not scan natively (Docker, Helm, generic, and others). External registry cooldown covers these repositories by blocking packages published more recently than a configurable window.

Cooldown in local mode requires Redis. In API mode Redis is used for caching when available. See External Registry Cooldown for the mode options.

How it works with auto-discovery:

  1. Auto-discovery detects all Artifactory repositories, including unsupported package types
  2. Supported repositories get Socket API-checked routes as normal
  3. Unsupported repositories are matched against the configured cooldown registries
  4. Matched repositories get cooldown-checked routes
  5. Unmatched unsupported repositories are skipped — no route is generated

Matching runs by Artifactory repository key first, then by remote URL (normalized, trailing slashes stripped).

Configuration

redis:
  enabled: true
  host: redis
  port: 6379

path_routing:
  enabled: true
  domain: socket-firewall.company.com
  
  private_registry:
    api_url: https://artifactory.company.com/artifactory
    api_key: ${ARTIFACTORY_API_KEY}
    mode: artifactory
    interval: 5m
    supported_ecosystems_only: true   # Supported repos get Socket API checks

external_registry_cooldown:
  enabled: true
  cooldown_period: 7d                 # Block packages published within 7 days
  
  # Match by repository key or remote URL
  registries:
    - name: gradle-plugins-remote
      url: https://plugins.gradle.org/m2/
      ecosystem: maven
    - name: docker-hub-remote
      url: https://registry-1.docker.io
      ecosystem: docker
  
  # Or auto-discover the unsupported repos from Artifactory
  private_registry:
    enabled: true
    source: auto                      # Detect from path_routing.mode
    include_unsupported_only: true    # Only repos skipped by supported_ecosystems_only

A Gradle remote proxying https://plugins.gradle.org/m2/ is checked against the Maven registry hosts, so it needs an entry like the one above to be routed.

Docker and OCI Repositories

Docker/OCI cooldown requires version 2.0.9 or higher.

Docker repositories get cooldown-checked routes on both path forms Artifactory serves: /artifactory/api/docker/<repo> (used by Docker clients and smart remotes) and /artifactory/<repo>. Configure them like any other cooldown registry with ecosystem: dockeroci is accepted as an alias and behaves identically, and PURLs are always emitted as pkg:docker/....

RequestBehavior
Tag-referenced manifest (.../v2/<image>/manifests/<tag>)Gated — a tag pull inside the cooldown window is blocked with 403 before any layer downloads
Digest-referenced manifest (manifests/sha256:...)Passes through
Blobs and layersPasses through
/v2/ ping, _catalog, tags/listPasses through

Image names with multiple path segments (myorg/team/app) are supported.

Publish-Date Fallback

When the ecosystem lookup cannot determine a publish date, the firewall can read the artifact's created timestamp from Artifactory instead. It searches both the repository and its <repo>-cache variant and takes the earliest match, and it works on Artifactory OSS — no Pro license needed.

external_registry_cooldown:
  enabled: true
  fallback: external      # Query Artifactory first, ecosystem lookup second
  # Or: fallback: artifactory  # Ecosystem lookup first, Artifactory second

The fallback reuses the path_routing.private_registry credentials, so there is no extra authentication to configure. See Publish-Date Fallback for all fallback modes.


Reference

Artifactory Remote Repository Configuration

SettingValue
Repository Keynpm-remote, pypi-remote, etc.
Package Typenpm, pypi, maven, etc.
URLThe firewall URL for the ecosystem — see Step 2
Allow Any Host AuthYes
Verify SSL CertificateYes (No only when using self-signed certificates in testing)
Store Artifacts LocallyYes (recommended)

Firewall Configuration Summary

Topologyconfig_moderoute modeURL RewritingAuto-Discovery
DirectN/AN/AN/AN/A
UpstreamupstreamrewriteYesYes
Downstream(default)rewriteYesOptional
Middlemiddleproxy*No*Yes

* In middle, auto-discovery applies proxy to pypi, conda, npm, and nuget routes; other ecosystems use rewrite. Both the API path and the direct path are generated in every config_mode.

Supported Package Types

Artifactory Package TypeFirewall RegistryNotes
npmnpmFull support
pypipypiFull support
mavenmavenFull support
gradlemavenMaven layout
cargocargoFull support
gemsrubygemsFull support
nugetnugetFull support (v2 and v3 paths)
gogoFull support
condacondaExperimental - treated as PyPI
huggingfacemlhuggingfaceRequires version 2.0.9 or higher
dockercooldownVia external registry cooldown
helmcooldownVia external registry cooldown
genericcooldownVia external registry cooldown
(other)cooldownVia external registry cooldown


Did this page help you?