Introduction
When it comes to ensuring the security and compliance of your software artifacts, JFrog Xray provides powerful scanning capabilities. However, it's important to understand the distinction between scanning an individual artifact and scanning a build to get a complete picture of potential vulnerabilities, especially those lurking within dependencies.
In this article we clearly explain the difference between scanning an artifact and scanning a build in JFrog Xray.
Resolution
Scanning an Artifact
When scanning an artifact in JFrog Xray, the process involves checking the artifact’s checksums against Xray’s vulnerability database. This approach identifies vulnerabilities that exist within the artifact itself or within the dependencies that are directly packaged into the artifact. However, this method might not provide a complete picture, especially for complex projects with external dependencies.
Key Point: The artifact scan only detects vulnerabilities in what is directly included in the artifact. If any external dependencies were part of the build process but not packaged into the artifact, those will not be included in the scan.
Scanning a Build
For a more comprehensive vulnerability scan, you can publish the entire build to Artifactory. When a build is published, Artifactory doesn’t just store the artifacts themselves but also extracts and stores detailed metadata about the build, including information on all the dependencies used during the build process.
This metadata is linked to the build and allows Xray to perform a scan that includes not just the artifacts, but all the dependencies as well. This provides a complete view of potential vulnerabilities across the entire build pipeline, making sure no vulnerable dependencies are missed.
Key Point: Scanning a build provides a more holistic view by including all dependencies (even those not directly packaged into the artifact), ensuring that any vulnerability affecting the final product is identified.
Publishing a Build to Artifactory with JFrog CLI (NPM Example)
To easily publish your build to Artifactory and include all relevant dependencies, follow these steps using JFrog CLI for an NPM project:
Navigate to the project directory:
cd /path/to/project
Configure the JFrog CLI to work with Artifactory:
jf c add
1. Configure Npm to resolve dependencies and deploy artifacts from and to Artifactory
jf npm-config
Make sure to mention that the resolve repo and deploy repo should be included in the indexed resources before installing the project
2. Install dependencies and capture build info:
jf npm install --build-name=my-npm-build --build-number=1
Why Providing Build Name and Build Number is Important
Providing a build name and build number when using tools like JFrog Artifactory or Xray is crucial for effective tracking, auditing, and debugging. These parameters serve as unique identifiers that help distinguish one build from another, especially in CI/CD pipelines where artifacts may be built frequently. Using a consistent build name and build number allows you to:
- Track Versions and Dependencies: Knowing the exact build associated with a deployment helps trace specific versions and dependencies back to their sources.
- Audit and Security Compliance: These identifiers allow you to link scans and compliance checks to individual builds, ensuring that each release complies with necessary security policies.
- Debug and Rollback: In case of issues, identifying the exact build makes debugging easier and helps teams rollback to previous stable versions if needed.
Setting Build Name and Number as Environment Variables
To set these parameters in the environment, you can define the following environment variables before running your build:
export JFROG_CLI_BUILD_NAME=<build_name> export JFROG_CLI_BUILD_NUMBER=<build_number>
This configuration allows the CLI to pick up the build name and number automatically without explicitly specifying them each time, making automation and CI/CD workflows smoother.
What This Means in Practice: With the build name and number as environment variables, all relevant CLI commands run in the same session will automatically associate with the specified build. This simplifies the process for developers, especially when integrating with CI/CD pipelines, as each build can have a unique identifier tied directly to its environment, ensuring consistent tracking across the deployment lifecycle.
3. Add environment variables to the build info:
jf rt bce my-npm-build 1
4. Include Git information in the build info:
jf rt bag my-npm-build 1
5. Pack and publish the npm package, while recording it in the build info:
jf npm publish --build-name=my-npm-build --build-number=1
6. Publish the build information to Artifactory:
jf rt bp my-npm-build 1
7. For more examples with other package managers, check out our project example repository on GitHub.
There may be situations where the client (e.g., jfrog-cli, Docker clients, or other package managers) retrieves only the metadata of a binary instead of the binary itself. This situation can arise due to caching mechanisms, particularly in local and remote repository configurations. Clearing the client’s and repository’s cache ensures that the actual binary is downloaded rather than just the metadata, allowing it to be properly scanned by Xray.