v0.1.0-draft AI Drafted

JFrog Hardening Guide

DevOps Last updated: 2025-12-14

Artifact management security for repository permissions, Xray policies, and access tokens

Overview

JFrog Artifactory is a universal binary repository supporting 40+ package formats across CI/CD pipelines. CVE-2024-6915 (CVSS 9.3) cache corruption vulnerability and research finding 70 cases of anonymous write permissions demonstrate artifact poisoning risks. As the central artifact repository, compromise enables supply chain attacks through dependency confusion and malicious package injection.

Intended Audience

  • Security engineers hardening artifact repositories
  • DevOps engineers configuring Artifactory
  • GRC professionals assessing supply chain security
  • Platform teams managing binary repositories

How to Use This Guide

  • L1 (Baseline): Essential controls for all organizations
  • L2 (Hardened): Enhanced controls for security-sensitive environments
  • L3 (Maximum Security): Strictest controls for regulated industries

Scope

This guide covers JFrog Artifactory security configurations including authentication, repository permissions, Xray integration, and artifact integrity controls.


Table of Contents

  1. Authentication & Access Controls
  2. Repository Security
  3. Artifact Integrity
  4. Xray Security Scanning
  5. Monitoring & Detection
  6. Compliance Quick Reference

1. Authentication & Access Controls

1.1 Enforce SSO with MFA

Profile Level: L1 (Baseline) NIST 800-53: IA-2(1)

Description

Require SAML SSO with MFA for all Artifactory access.

ClickOps Implementation

Step 1: Configure SAML SSO

  1. Navigate to: Administration → Security → Settings → SSO
  2. Configure:
    • IdP Login URL: Your IdP endpoint
    • IdP Certificate: Upload certificate
    • Service Provider ID: Artifactory URL

Step 2: Disable Local Authentication

  1. Navigate to: Administration → Security → Settings
  2. Disable: Allow anonymous access
  3. Configure: Require SSO for all users

Step 3: Configure Access Tokens

  1. Navigate to: Administration → Identity and Access → Access Tokens
  2. Configure token policies:
    • Expiration: 90 days maximum
    • Scopes: Minimum required

Code Implementation

Code Pack: Terraform
hth-jfrog-1.01-enforce-sso-with-mfa.tf View source on GitHub ↗
# Configure SAML SSO for centralized authentication with MFA enforcement
resource "artifactory_saml_settings" "sso" {
  enable                       = true
  login_url                    = var.saml_idp_url
  certificate                  = var.saml_idp_certificate
  service_provider_name        = var.saml_service_provider_id
  allow_user_to_access_profile = false
  auto_redirect                = true
  no_auto_user_creation        = false
  use_encrypted_assertion      = true
}

# Disable anonymous access to force authenticated sessions
resource "artifactory_general_security" "disable_anonymous" {
  enable_anonymous_access = false
}

1.2 Implement Permission Targets

Profile Level: L1 (Baseline) NIST 800-53: AC-3, AC-6

Description

Configure granular permissions for repository access.

Rationale

Why This Matters:

  • Research found 70 cases of anonymous write permissions
  • Write access enables artifact poisoning
  • Dependency confusion attacks require upload capability

Attack Scenario: Dependency confusion attack uploads malicious package to internal repository; cache poisoning replaces legitimate artifacts.

ClickOps Implementation

Step 1: Create Permission Targets

  1. Navigate to: Administration → Identity and Access → Permissions
  2. Create permission targets:

Production-Read:

  • Repositories: libs-release-local
  • Actions: Read, Annotate
  • Groups: All developers

Production-Write:

  • Repositories: libs-release-local
  • Actions: Deploy, Delete
  • Groups: Release managers only

Build-Upload:

  • Repositories: libs-snapshot-local
  • Actions: Deploy
  • Groups: CI/CD service accounts

Step 2: Disable Anonymous Access

  1. Navigate to: Administration → Security → Settings
  2. Disable: Allow anonymous access
  3. Audit all repositories for anonymous permissions

Step 3: Restrict Admin Access

  1. Limit admin role to 2-3 users
  2. Create separate roles for different functions
  3. Audit admin access quarterly

Code Implementation

Code Pack: Terraform
hth-jfrog-1.02-implement-permission-targets.tf View source on GitHub ↗
# Production-Read: Read-only access for developers to release repositories
resource "artifactory_permission_target" "production_read" {
  name = "hth-production-read"

  repo {
    repositories = [var.release_repo_key]
    actions {
      groups {
        name        = var.release_readers_group
        permissions = ["read", "annotate"]
      }
    }
  }
}

# Production-Write: Deploy access restricted to release managers
resource "artifactory_permission_target" "production_write" {
  name = "hth-production-write"

  repo {
    repositories = [var.release_repo_key]
    actions {
      groups {
        name        = var.release_writers_group
        permissions = ["read", "annotate", "deploy", "delete"]
      }
    }
  }
}

# Build-Upload: CI/CD service accounts can deploy to snapshot repos only
resource "artifactory_permission_target" "build_upload" {
  name = "hth-build-upload"

  repo {
    repositories = [var.snapshot_repo_key]
    actions {
      groups {
        name        = var.ci_cd_group
        permissions = ["read", "deploy"]
      }
    }
  }
}

# L3: Strict read-only for all non-admin users on release repos
resource "artifactory_permission_target" "strict_readonly" {
  count = var.profile_level >= 3 ? 1 : 0

  name = "hth-strict-readonly"

  repo {
    repositories = [var.release_repo_key]
    actions {
      groups {
        name        = var.release_readers_group
        permissions = ["read"]
      }
    }
  }
}

1.3 Secure API Keys and Tokens

Profile Level: L1 (Baseline) NIST 800-53: IA-5

Description

Manage API keys and access tokens securely.

ClickOps Implementation

Step 1: Audit Existing Keys

  1. Navigate to: Administration → Identity and Access → Access Tokens
  2. Review all active tokens
  3. Revoke unused tokens

Step 2: Create Scoped Tokens

See the CLI pack below for scoped token creation commands.

Step 3: Rotate Tokens

Token Type Rotation Frequency
CI/CD tokens Quarterly
User API keys Semi-annually
Admin tokens Quarterly

Code Implementation

Code Pack: Terraform
hth-jfrog-1.03-secure-api-keys-and-tokens.tf View source on GitHub ↗
# Create a scoped access token for CI/CD pipelines with limited expiry
resource "artifactory_scoped_token" "ci_cd_token" {
  scopes      = ["applied-permissions/groups:${var.ci_cd_group}"]
  expires_in  = var.token_expiry_seconds
  description = "HTH: Scoped CI/CD token with ${var.token_expiry_seconds / 86400}-day expiry"
}

# L2: Create a shorter-lived admin token with tighter rotation
resource "artifactory_scoped_token" "admin_token" {
  count = var.profile_level >= 2 ? 1 : 0

  scopes      = ["applied-permissions/admin"]
  expires_in  = 2592000 # 30 days
  description = "HTH: Short-lived admin token (30-day expiry, L2+)"
}
Code Pack: CLI Script
hth-jfrog-1.03-secure-api-keys-and-tokens.sh View source on GitHub ↗
# Create scoped token via CLI
jf rt access-token-create \
  --groups readers \
  --scope applied-permissions/groups:readers \
  --expiry 7776000  # 90 days

2. Repository Security

2.1 Configure Repository Layout Security

Profile Level: L1 (Baseline) NIST 800-53: CM-7

Description

Harden repository configurations to prevent unauthorized access.

ClickOps Implementation

Step 1: Review Repository Settings

  1. Navigate to: Administration → Repositories
  2. For each repository, verify:
    • Anonymous access: Disabled
    • Include/Exclude patterns: Configured
    • Allow content browsing: Restricted

Step 2: Configure Virtual Repository Security

  1. For virtual repositories, configure resolution order:
    • Internal repositories first
    • Remote repositories second
  2. This prevents dependency confusion

Step 3: Disable Unused Features

  1. Disable: File listing for remote repositories
  2. Disable: Properties search (if not needed)

Code Implementation

Code Pack: Terraform
hth-jfrog-2.01-configure-repository-layout-security.tf View source on GitHub ↗
# Harden local Maven release repository with restricted settings
resource "artifactory_local_maven_repository" "release" {
  key                   = var.release_repo_key
  description           = "HTH: Hardened release repository - handles releases only"
  handle_releases       = true
  handle_snapshots      = false
  suppress_pom_consistency_checks = false
  xray_index            = true
  property_sets         = ["artifactory"]
}

# Harden local Maven snapshot repository
resource "artifactory_local_maven_repository" "snapshot" {
  key                   = var.snapshot_repo_key
  description           = "HTH: Hardened snapshot repository - handles snapshots only"
  handle_releases       = false
  handle_snapshots      = true
  suppress_pom_consistency_checks = false
  xray_index            = true
  max_unique_snapshots  = 5
}

2.2 Remote Repository Security

Profile Level: L1 (Baseline) NIST 800-53: SC-7

Description

Secure remote repository (proxy) configurations.

ClickOps Implementation

Step 1: Configure Remote Repository Settings

  1. Navigate to: Repositories → Remote
  2. For each remote repository:
    • Hard fail: Enable for security artifacts
    • Store artifacts locally: Enable
    • Block mismatching MIME types: Enable

Step 2: Configure Exclude Patterns

See the CLI pack below for recommended exclude patterns.

Step 3: Enable Checksum Validation

  1. Configure: Checksum policy: Fail (L2)
  2. Validate checksums for all downloaded artifacts

Code Implementation

Code Pack: Terraform
hth-jfrog-2.02-remote-repository-security.tf View source on GitHub ↗
# Harden remote Maven repository proxy with security controls
resource "artifactory_remote_maven_repository" "secure_remote" {
  key                            = var.remote_repo_key
  url                            = var.remote_repo_url
  description                    = "HTH: Hardened remote repository proxy"
  store_artifacts_locally        = true
  hard_fail                      = true
  block_mismatching_mime_types   = true
  excludes_pattern               = var.blocked_remote_extensions
  xray_index                     = true
  content_synchronisation {
    enabled = false
  }
}

# L2: Enforce strict checksum validation on remote repositories
resource "artifactory_remote_maven_repository" "strict_checksum_remote" {
  count = var.profile_level >= 2 ? 1 : 0

  key                            = "${var.remote_repo_key}-strict"
  url                            = var.remote_repo_url
  description                    = "HTH: Strict checksum remote repository (L2+)"
  store_artifacts_locally        = true
  hard_fail                      = true
  block_mismatching_mime_types   = true
  excludes_pattern               = var.blocked_remote_extensions
  xray_index                     = true
  remote_repo_checksum_policy_type = "fail"
  content_synchronisation {
    enabled = false
  }
}

2.3 Prevent Dependency Confusion

Profile Level: L1 (Baseline) NIST 800-53: SI-7

Description

Configure Artifactory to prevent dependency confusion attacks.

Implementation

Step 1: Configure Virtual Repository Priority

See the CLI pack below for virtual repository configuration.

Step 2: Reserve Internal Package Names

  1. Create placeholder packages in remote proxies
  2. Block external packages with internal names

Step 3: Enable Priority Resolution

  1. Navigate to: Virtual Repository → Advanced
  2. Configure: Priority Resolution: Enabled
  3. Set internal repositories higher priority

Code Implementation

Code Pack: Terraform
hth-jfrog-2.03-prevent-dependency-confusion.tf View source on GitHub ↗
# Virtual repository with internal repos resolved first to prevent
# dependency confusion attacks. Internal repositories take priority
# over external/remote repositories in the resolution order.
resource "artifactory_virtual_maven_repository" "secure_virtual" {
  key                                        = var.virtual_repo_key
  description                                = "HTH: Virtual repo with priority resolution to prevent dependency confusion"
  repositories                               = concat(var.internal_repo_keys, var.external_repo_keys)
  default_deployment_repo                    = var.internal_repo_keys[0]
  artifactory_requests_can_retrieve_remote_artifacts = true
  force_maven_authentication                 = true
}

# L2: Disable remote artifact retrieval through virtual repos
# to further isolate internal from external dependencies
resource "artifactory_virtual_maven_repository" "isolated_virtual" {
  count = var.profile_level >= 2 ? 1 : 0

  key                                        = "${var.virtual_repo_key}-isolated"
  description                                = "HTH: Isolated virtual repo - no remote retrieval (L2+)"
  repositories                               = var.internal_repo_keys
  default_deployment_repo                    = var.internal_repo_keys[0]
  artifactory_requests_can_retrieve_remote_artifacts = false
  force_maven_authentication                 = true
}
Code Pack: CLI Script
hth-jfrog-2.03-prevent-dependency-confusion.yml View source on GitHub ↗
# Virtual repository configuration
virtual_repository:
  repositories:
    - internal-libs     # First priority (internal)
    - remote-maven     # Second priority (external)
  default_deployment_repo: internal-libs

3. Artifact Integrity

3.1 Enable Artifact Signing

Profile Level: L2 (Hardened) NIST 800-53: SI-7

Description

Require artifact signing for production deployments.

Implementation

Step 1: Configure GPG Signing

See the CLI pack below for signing and verification commands.

Step 2: Verify Signatures on Download

See the CLI pack below for download verification commands.

Step 3: Enforce Signing Policy

  1. Use Xray policies to block unsigned artifacts
  2. Document signing requirements

Code Implementation

Code Pack: Terraform
hth-jfrog-3.01-enable-artifact-signing.tf View source on GitHub ↗
# Configure GPG signing key for artifact verification (L2+)
resource "artifactory_keypair" "gpg_signing" {
  count = var.profile_level >= 2 ? 1 : 0

  pair_name   = "hth-artifact-signing"
  pair_type   = "GPG"
  alias       = "hth-gpg"
  public_key  = var.gpg_public_key
  passphrase  = ""
}

# Associate signing key with release repository for signature enforcement
resource "artifactory_local_maven_repository" "signed_release" {
  count = var.profile_level >= 2 ? 1 : 0

  key                   = "${var.release_repo_key}-signed"
  description           = "HTH: Signed release repository with GPG verification (L2+)"
  handle_releases       = true
  handle_snapshots      = false
  xray_index            = true
  primary_keypair_ref   = artifactory_keypair.gpg_signing[0].pair_name
}
Code Pack: CLI Script
hth-jfrog-3.01-enable-artifact-signing.sh View source on GitHub ↗
# Sign artifact during deployment
jf rt upload --gpg-key=/path/to/key.asc artifact.jar libs-release-local/

# Verify artifact signature
jf rt download libs-release-local/artifact.jar --gpg-key=/path/to/public.asc

3.2 Immutable Artifacts

Profile Level: L2 (Hardened) NIST 800-53: SI-7

Description

Make release artifacts immutable to prevent tampering.

ClickOps Implementation

Step 1: Configure Repository Settings

  1. Navigate to: Repository → Advanced
  2. Enable: Handle releases (for release repos)
  3. Disable: Handle snapshots (for release repos)
  4. Enable: Suppress POM consistency checks: No

Step 2: Create Immutable Policy

  1. Use release repository for production artifacts
  2. Block re-deployment of existing versions
  3. Delete permissions restricted to admins

Code Implementation

Code Pack: Terraform
hth-jfrog-3.02-immutable-artifacts.tf View source on GitHub ↗
# Immutable release repository: block re-deployment of existing versions (L2+)
# Once an artifact version is published, it cannot be overwritten.
resource "artifactory_local_maven_repository" "immutable_release" {
  count = var.profile_level >= 2 ? 1 : 0

  key                             = "${var.release_repo_key}-immutable"
  description                     = "HTH: Immutable release repository - no redeployment (L2+)"
  handle_releases                 = true
  handle_snapshots                = false
  suppress_pom_consistency_checks = false
  xray_index                      = true

  # Block re-deployment to enforce immutability
  # Users cannot overwrite existing artifact versions
}

# L3: Restrict delete permissions to prevent artifact removal
resource "artifactory_permission_target" "immutable_no_delete" {
  count = var.profile_level >= 3 ? 1 : 0

  name = "hth-immutable-no-delete"

  repo {
    repositories = ["${var.release_repo_key}-immutable"]
    actions {
      groups {
        name        = var.release_readers_group
        permissions = ["read"]
      }
      groups {
        name        = var.release_writers_group
        permissions = ["read", "annotate", "deploy"]
      }
    }
  }
}

4. Xray Security Scanning

4.1 Configure Xray Policies

Profile Level: L1 (Baseline) NIST 800-53: RA-5

Description

Configure JFrog Xray for vulnerability and license scanning.

ClickOps Implementation

Step 1: Create Security Policy

  1. Navigate to: Xray → Policies → New Policy
  2. Configure:
    • Type: Security
    • Rules:
      • Critical CVE: Block download
      • High CVE: Warn
    • Actions: Block release, notify

Step 2: Create Watch

  1. Navigate to: Xray → Watches → New Watch
  2. Configure:
    • Resources: Production repositories
    • Policy: Security policy created above

Step 3: Enable Automatic Scanning

  1. Enable scanning on upload
  2. Configure periodic rescanning
  3. Set up notifications

4.2 CVE Remediation Workflow

Profile Level: L1 (Baseline)

Implementation

Step 1: Monitor CVE Alerts

  1. Configure Xray notifications
  2. Integrate with ticketing system
  3. Assign remediation owners

Step 2: Block Vulnerable Artifacts

See the CLI pack below for Xray policy configuration.

Code Implementation

Code Pack: CLI Script
hth-jfrog-4.02-cve-remediation-workflow.yml View source on GitHub ↗
# Xray policy - Block critical vulnerabilities
policy:
  name: block-critical-cves
  type: security
  rules:
    - name: critical-cve-block
      criteria:
        min_severity: critical
      actions:
        block_download:
          active: true
        fail_build: true

5. Monitoring & Detection

5.1 Audit Logging

Profile Level: L1 (Baseline) NIST 800-53: AU-2, AU-3

Description

Configure comprehensive audit logging.

ClickOps Implementation

Step 1: Enable Audit Log

  1. Navigate to: Administration → Security → Settings
  2. Enable: Audit log
  3. Configure retention

Step 2: Export to SIEM

  1. Configure log shipping to SIEM
  2. Parse Artifactory access logs

Detection Queries

See the DB pack below for SIEM detection queries.

Code Implementation

Code Pack: Terraform
hth-jfrog-5.01-audit-logging.tf View source on GitHub ↗
# Webhook for forwarding deployment events to SIEM
resource "artifactory_webhook" "deploy_events" {
  count = var.audit_webhook_url != "" ? 1 : 0

  key         = "hth-deploy-audit"
  description = "HTH: Forward artifact deploy events to SIEM"
  event_types = ["deployed", "deleted", "moved", "copied"]
  url         = var.audit_webhook_url
  enabled     = true

  criteria {
    any_local  = true
    any_remote = false
  }
}

# L2: Webhook for permission and access control change events
resource "artifactory_webhook" "access_events" {
  count = var.profile_level >= 2 && var.audit_webhook_url != "" ? 1 : 0

  key         = "hth-access-audit"
  description = "HTH: Forward access control events to SIEM (L2+)"
  event_types = ["deployed", "deleted", "moved", "copied", "downloaded"]
  url         = var.audit_webhook_url
  enabled     = true

  criteria {
    any_local  = true
    any_remote = true
  }
}

# L3: Comprehensive download audit for all repository access
resource "artifactory_webhook" "download_audit" {
  count = var.profile_level >= 3 && var.audit_webhook_url != "" ? 1 : 0

  key         = "hth-download-audit"
  description = "HTH: Audit all artifact downloads (L3)"
  event_types = ["downloaded"]
  url         = var.audit_webhook_url
  enabled     = true

  criteria {
    any_local  = true
    any_remote = true
  }
}

6. Compliance Quick Reference

SOC 2 Mapping

Control ID Artifactory Control Guide Section
CC6.1 SSO enforcement 1.1
CC6.2 Permission targets 1.2
CC8.1 Artifact integrity 3.1

Supply Chain Security (SLSA)

Level Requirements Artifactory Controls
SLSA 1 Build provenance Build info capture
SLSA 2 Signed provenance GPG signing
SLSA 3 Security controls Xray scanning, access control

Appendix A: Edition Compatibility

Control OSS Pro Enterprise
SSO (SAML)
Access Tokens Basic
Xray Add-on
Audit Log Basic
HA/DR

Appendix B: References

Official JFrog Documentation:

API & Developer Resources:

Compliance Frameworks:

Security Incidents:

  • CVE-2024-6915 (CVSS 9.3): Cache poisoning vulnerability in JFrog Artifactory allowing attackers to corrupt cached artifacts in the software supply chain. Affects versions below 7.90.6 and corresponding LTS releases. Cloud environments were patched automatically; on-premise instances require manual upgrade.

Changelog

Date Version Maturity Changes Author
2025-12-14 0.1.0 draft Initial JFrog Artifactory hardening guide Claude Code (Opus 4.5)