> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/software-supply-chain-assurance/use-scs/open-source-management/generate-sbom-for-artifacts.md).

# Generate and Manage Software Bill of Materials (SBOM)

A Software Bill of Materials (SBOM) is an exhaustive list of all components, libraries, and other dependencies utilized in a software application. The **SBOM Orchestration** step within Harness SCS facilitates the generation of SBOMs for your software artifacts and [code repositories](/software-supply-chain-assurance/use-scs/open-source-management/generate-sbom-for-repositories.md).

If you already possess an SBOM and wish to ingest it, go to the [Ingest SBOM](/software-supply-chain-assurance/use-scs/open-source-management/ingest-sbom-data.md) section.

{% hint style="info" %}
In the SBOM, dependency names may differ from their original source names, as SBOM tools sometimes list dependencies under a product or bundle name rather than the actual dependency name.
{% endhint %}

{% embed url="<https://youtu.be/k5TAO1RLJvY?si=y_mC2cq5YD8MziK->" %}

### SBOM Orchestration step configuration <a href="#sbom-orchestration-step-configuration" id="sbom-orchestration-step-configuration"></a>

<figure><img src="/files/T44XPZu7z0pVbcoOezgZ" alt=""><figcaption></figcaption></figure>

You can use **SBOM Orchestration** step to generate an SBOM in either the **Build** or **Deploy** stage of a Harness pipeline.

* In a **Build** stage, add the **SBOM Orchestration** step after the artifact (image) has been pushed to an artifact repository.
* In a **Deploy** stage, add the **SBOM Orchestration** step before the deployment step.

{% hint style="info" %}
**SBOM Orchestration** step in deploy stage can only be used in the [Containerized Step Groups](/continuous-delivery/use-continuous-delivery/cd-building-blocks/cd-steps/containerized-steps/containerized-step-groups.md) and ensure you enable the `container based execution`.
{% endhint %}

The SBOM Orchestration step allows you to generate the SBOM for both Container images and Repositories.

{% hint style="info" %}
SBOM generation is not supported for non-container artifacts. For artifact types such as JAR files, Helm charts, or YAML manifests, you must use the SBOM orchestration step in Ingestion mode and provide a pre-generated SBOM file. Go to [Ingest SBOM for Non-Container Images](/software-supply-chain-assurance/use-scs/open-source-management/ingest-sbom-data.md#non-container-images) to understand SBOM orchestration via ingestion mode.
{% endhint %}

Follow the steps to configure the fields for each supported type:

* **Name:** Enter a name for the step.
* **Step Mode:** Select **Generation**.
* **SBOM Tool:** Select **Syft** or **cdxgen**. For other SBOM tools, go to [Ingest SBOM](/software-supply-chain-assurance/use-scs/open-source-management/ingest-sbom-data.md).
* **SBOM Format:** Select **SPDX** or **CycloneDX**.

#### Use Syft <a href="#use-syft" id="use-syft"></a>

If you are using **Syft** to generate the SBOM and want to ensure it includes all component licenses with high accuracy, you will need to set specific environment variables based on your project's programming language. Here are the relevant variables:

<details>

<summary>Set variables for enhanced SBOM</summary>

| Programming Language | Name of Variable                         | Value |
| -------------------- | ---------------------------------------- | ----- |
| Go                   | `SYFT_GOLANG_SEARCH_REMOTE_LICENSES`     | true  |
| Java                 | `SYFT_JAVA_USE_NETWORK`                  | true  |
| JavaScript           | `SYFT_JAVASCRIPT_SEARCH_REMOTE_LICENSES` | true  |

To add a new environment variable, go to **Overview** section of your Build stage, and expand the **Advanced** section.

<figure><img src="/files/B4N7Oqk1OCJUC22BPC94" alt=""><figcaption><p>Click to view full size image</p></figcaption></figure>

By setting these variables, Syft can more effectively fetch and populate the licensing data for the components in your SBOM. This not only enhances the quality of the SBOM but also improves its overall SBOM score. If your SBOM contains `NOASSERTIONS`, it indicates that Syft was unable to retrieve necessary data.

</details>

#### Use cdxgen <a href="#use-cdxgen" id="use-cdxgen"></a>

Generating SBOMs using cdxgen supports CLI flags that customize how the scan runs. These flags are passed directly to cdxgen and control how the repository is scanned, how dependencies are resolved, and how the final SBOM is generated. You can use them to tune performance, scope, and output based on your specific use case.

| Why use the flags?                                                                                                                | When to use?                                                                                                                                  | How can you leverage it?                                                                                                                                                        |
| --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Customize SBOM generation across discovery, dependency resolution, and output phases to balance performance, scope, and accuracy. | When default scans are slow, overly broad, or require environment-specific adjustments (for example, large monorepos or restricted networks). | Add CLI flags to control what gets scanned and limit dependency resolution. Use them to adjust output or validation to improve performance and control SBOM coverage and depth. |

To apply the cdxgen CLI flags within your scan configurations, complete the following steps:

* Select **cdxgen** as the SBOM generation tool. The Additional CLI Flags field will appear as an optional step.
* In the `Additional CLI Flags` field, enter the required cdxgen CLI flags to customize SBOM generation. All cdxgen CLI flags are supported in this step. For a complete list of available flags and their detailed descriptions, refer to the [official cdxgen documentation](https://cdxgen.github.io/cdxgen/#/CLI?id=getting-help).

<figure><img src="/files/Uzy9JTKdq1hRTUi9IgyY" alt=""><figcaption></figcaption></figure>

The following flags can help optimize SBOM generation for common use cases:

| Flag                  | What it does?                                                 | When to use?                                                        | Trade-off                                         |
| --------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------- |
| `--no-install-deps`   | Skips running build tools and uses manifest or lockfile data. | When you need faster scans for large repositories or frequent runs. | May miss dependencies resolved during build time. |
| `--exclude <pattern>` | Skips specified directories or files during scanning.         | When large or irrelevant directories slow down scans.               | Incorrect exclusions can omit valid components.   |
| `--type <ecosystem>`  | Limits scanning to a specific ecosystem.                      | When focusing on a single language or framework.                    | Other ecosystems are ignored.                     |
| `--no-validate`       | Skips SBOM schema validation.                                 | When faster execution is needed in non-critical runs.               | Validation issues may surface later.              |

{% hint style="info" %}

* You can combine multiple CLI flags to optimize SBOM generation.
* Depending on your repository and the flags used, execution time, SBOM size, and component count can change. Results may differ across setups.
* Reducing scan scope or skipping dependency resolution can miss vulnerable dependencies, which may leave gaps in your security visibility.
  {% endhint %}

#### Configure the artifact source <a href="#configure-the-artifact-source" id="configure-the-artifact-source"></a>

Configure the following fields to identify where your artifact is stored.

* **Registry Type**: Select **Harness Artifact Registry** or **Third-Party Artifact Registry**, based on where your artifact is stored.
* **Source**: Select the **Source** by choosing either a supported container registry from the list or Repository if you are generating the SBOM for source code.

{% tabs %}
{% tab title="HAR" %}

* **Registry:** Select the Harness Registry configured for the Harness Artifact Registry where your artifact is stored.
* **Image:** Enter the name of your image with tag or digest, such as `imagename:tag` or `imagename:digest`.
  {% endtab %}

{% tab title="Docker Registry" %}

* **Container Registry:** Select the [Docker Registry connector](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference.md) that is configured for the DockerHub container registry where the artifact is stored.
* **Image:** Enter the name of your image using either a tag or a digest. For example: `my-docker-org/repo-name:tag` or `my-docker-org/repo-name@sha256:<digest>`

{% hint style="info" %}
Unlike other artifact sources, JFrog Artifactory requires additional permissions for attestation. The connector’s user or token must have `Read`, `Annotate`, `Create/Deploy`, and `Delete` permissions.
{% endhint %}
{% endtab %}

{% tab title="ECR" %}

* **Container Registry:** Select the [Docker Registry connector](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference.md) that is configured for the Elastic container registry where the artifact is stored.
* **Image:** Enter the name of your image with tag or digest for the image for which you're generating an SBOM, such as `my-docker-repo/my-artifact:latest` or `my-docker-repo/my-artifact@sha256:<digest>`.
* **Region:** The geographical location of your ECR repository.
* **Account ID:** The unique identifier associated with your AWS account.
  {% endtab %}

{% tab title="GAR" %}

* **Container Registry:** Select the [Docker Registry connector](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference.md) that is configured for the Google artifact registry where the artifact is stored.
* **Image:** Enter the name of your image with tag or digest for which you're generating the SBOM, example `repository-name/image:tag` or `repository-name/image@sha256:<digest>`.
* **Host:** Enter your GAR Host name. The Host name is regional-based. For example, `us-east1-docker.pkg.dev`.
* **Project ID:** Enter the unique identifier of your Google Cloud Project. The Project-ID is a distinctive string that identifies your project across Google Cloud services. example: `my-gcp-project`
  {% endtab %}

{% tab title="ACR" %}

* **Container Registry:** Select the [Docker Registry connector](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference.md) that is configured for the Azure container registry where the artifact is stored.
* **Image:** Enter your image details with a tag or digest in the format `<registry-login-server>/<repository>:<tag>` or `<registry-login-server>/<repository>@sha256:<digest>`. The `<registry-login-server>` is a fully qualified name of your Azure Container Registry. It typically follows the format `<registry-name>.azurecr.io`, where `<registry-name>` is the name you have given to your container registry instance in Azure. Example input: `automate.azurecr.io/acr:test`
* **Subscription Id:** Enter the unique identifier that is associated with your Azure subscription.
  {% endtab %}
  {% endtabs %}

With this configuration, the step generates the SBOM and stores it in the Artifact section of SCS. Optionally, you can attest to the generated SBOM, follow the instructions in the section below.

{% hint style="info" %}
The SBOM generation step supports all registry types, including JFrog, Harbor, and Kubernetes registries. Select the [Docker Registry Connector](/harness-ai/use-harness-platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference.md) that is configured for the Docker Registry where the artifact is stored.

Enter the name of your image with tag, such as:

JFrog: `</your-repo/test-image>:tag`

Harbor: `</your-project/test-image>:tag`
{% endhint %}

#### Attest the generated SBOM <a href="#attest-the-generated-sbom" id="attest-the-generated-sbom"></a>

SBOM signing is the process of cryptographically signing a generated SBOM to ensure its authenticity and integrity. It ensures that the SBOM has not been tampered with and can be trusted by downstream systems for analysis and compliance. Go to [attestation and verification](/software-supply-chain-assurance/new-to-scs/key-concepts.md#attestation-and-verification) to understand the signing and verification process.

You can perform attestation using Cosign with the following signing methods:

* **Keyless** - Uses short-lived, automatically generated keys based on identity to sign generated SBOMs without storing private keys.
* **Key-based** - Uses a user-managed private and public key pair to sign generated SBOMs, requiring secure key storage and handling.
* **Secret Manager** - A secure service used to store, manage, and access sensitive data such as cryptographic keys without exposing them directly in pipelines.

Based on the attestation type you select, click the tab below and specify the configurations for the SBOM Orchestration step to perform the attestation.

{% tabs %}
{% tab title="Keyless" %}
Keyless signing using Cosign lets you sign generated SBOMs without managing long-lived signing keys. Instead, Cosign uses your workload identity (via OIDC) to obtain a short-lived signing certificate during pipeline execution, which is then used to sign the SBOM. The signing key is generated and used only in memory and is not persisted. This reduces the risk of key compromise while ensuring the SBOM remains verifiable and trusted. The signed attestation is pushed to the container registry and associated with the image digest, typically referenced using the digest with a `.att` extension.

To configure SBOM attestation for generated SBOMs with Keyless signing using cosign, complete the following steps:

1. Click the checkbox beside `Attest SBOM` to enable SBOM attestation. The radio button beside `Keyless` will be selected by default.
2. Select your preferred OIDC Provider from the dropdown under `OIDC Provider`. The available options are:
   * [Harness](/software-supply-chain-assurance/use-scs/open-source-management/generate-sbom-for-artifacts.md#harness-oidc)
   * [Non-Harness](/software-supply-chain-assurance/use-scs/open-source-management/generate-sbom-for-artifacts.md#non-harness-oidc)

<figure><img src="/files/Fey30Z0mcfjE6UwaKuSF" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
This attestation method is not supported for SMP at the moment.
{% endhint %}

**Harness OIDC**

Harness OIDC allows you to use the pipeline’s built-in identity for keyless signing of generated SBOMs. In this approach, Harness acts as the OIDC provider and automatically supplies the identity required during pipeline execution, eliminating the need for external identity configuration.

**Non-Harness OIDC**

Non-Harness OIDC allows you to use an external identity provider for keyless signing of generated SBOMs. In this approach, the OIDC token is retrieved from a configured connector (such as AWS, Azure, or GCP) during pipeline execution and used to obtain a signing certificate. This option is useful when you want to integrate with your organization’s existing identity and access management system instead of using Harness as the OIDC provider.

To use a Non-Harness OIDC provider, you need to configure the Connector for Keyless Signing. To configure the Connector:

1. Navigate to the **Configuration** page under the **Manage** section from the sidebar navigation of your SCS account. The **General** tab opens by default.
2. Click `Select Connector` next to `Connector for Keyless Signing` to open the `Create or Select an Existing Connector` dialog.
3. Select your required connector from the list of existing connectors. You can search for your created connector or filter connectors by **Project**, **Organization**, and **Account**.
4. Alternatively, click `+ New Connector` to create a new OIDC connector for your preferred cloud provider. For more information, see [Connectors for Cloud Providers](https://app.gitbook.com/s/3F2TpHXhur2QtQnORSM9/use-harness-platform/connectors/cloud-providers/README).
5. Click `Apply Selected`. Once selected, you can view the **Configuration Saved Successfully** toaster message at the top, indicating that the connector has been selected or created successfully.

<figure><img src="/files/8fd3olUT7hgak3RrFr8q" alt=""><figcaption></figcaption></figure>

Once the connector configuration is done successfully, you can perform attestation using keyless signing with a Non-Harness OIDC provider.
{% endtab %}

{% tab title="Key-based" %}
To perform attestation with **Cosign** selected, you need a key pair. Follow the instructions below to generate the key pair.

<details>

<summary>Generate key pairs using Cosign for SBOM attestation</summary>

To perform the attestation process, you need to input the private key and password. Use [Cosign](https://docs.sigstore.dev/cosign/key_management/overview/) to generate the keys in the ecdsa-p256 format. Here’s how to generate them:

1. [Install Cosign](https://docs.sigstore.dev/cosign/system_config/installation/)
2. Run the command `cosign generate-key-pair` to generate the key pairs.
3. Make sure to note the password used for generating the key pairs. This password is needed along with the private key for performing the attestation.
4. This command will generate a private key as a `.key` file and a public key as a `.pub` file. To securely store these files, use Harness file secret.

</details>

* **Private Key**: Input your Private key from the [Harness file secret](/harness-ai/use-harness-platform/secrets/add-file-secrets.md).
* **Password**: Input your Password for the Private key from the [Harness file secret](/harness-ai/use-harness-platform/secrets/add-file-secrets.md).
  {% endtab %}

{% tab title="Secret Manager" %}
In this mode, you can pass your **Cosign keys** using a **Secret Manager**. Currently, SCS supports only the **HashiCorp Vault** secret manager. You can connect your Vault with Harness using the [Harness HashiCorp Vault connector](/harness-ai/use-harness-platform/secrets/secrets-management/add-hashicorp-vault.md). Here are the key points to consider when connecting your Vault:

1. **Enable the Transit Secrets Engine** on your HashiCorp Vault. This is essential for key management and cryptographic operations.
2. Configure your HashiCorp Vault connector using the following authentication methods [**AppRole**](/harness-ai/use-harness-platform/secrets/secrets-management/add-hashicorp-vault.md#option-app-role), [**Token**](/harness-ai/use-harness-platform/secrets/secrets-management/add-hashicorp-vault.md#option-token) , [**JWT Auth**](https://developer.harness.io/docs/platform/secrets/secrets-management/add-hashicorp-vault/#option-jwtoidc-auth) or [**Vault Agent**](/harness-ai/use-harness-platform/secrets/secrets-management/add-hashicorp-vault.md#option-vault-agent).
3. Create a Cosign key pair of type `ecdsa-p256`,`rsa-2048`, or `rsa-4096` in the Transit Secrets Engine. You can do this in two ways:
   * **CLI**: Run the command:

     ```bash
     vault write -f <transit_name>/<key_name> type=ecdsa-p256
     ```
   * **Vault UI**: Create the key pair directly from the Vault interface.
4. Ensure the Vault token generated has the [**required policy**](https://docs.sigstore.dev/cosign/key_management/overview/#hashicorp-vault) applied for Cosign to perform attestation operations.

{% hint style="info" %}
Harness Vault Connector now supports fetching keys from Vault subfolder paths. This feature is behind the FF `SSCA_COSIGN_USING_VAULT_V2`. To enable it contact [Harness Support](mailto:support@harness.io), and also ensure to upgrade your Harness delegate version to `25.10.87000` or higher.
{% endhint %}

Configure the following fields in the step to perform the attestation

* **Connector**: Select the HashiCorp Vault connector.
* **Key**: Enter the path to the Transit Secrets Engine in your HashiCorp Vault where the keys are stored.

{% hint style="info" %}
Harness Vault Connector is supported only for Kubernetes and VM infrastructure. Ensure your Harness delegate is on version `25.10.87000` or higher.
{% endhint %}
{% endtab %}
{% endtabs %}

#### Configure SBOM drift <a href="#configure-sbom-drift" id="configure-sbom-drift"></a>

This feature allows you to track changes in SBOMs by comparing against the last generated SBOM. It provides a detailed analysis of addition or removal of components and licenses, helping you manage and oversee software artifacts more effectively. However, this is optional and not required for SBOM generation. If you prefer not to detect changes in SBOMs, leave this option unchecked.

<figure><img src="/files/qnt3JTyIvW94ZBoEcP4V" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
When SBOM and SLSA attestation steps run in parallel, only one attestation layer may be uploaded to the container registry due to a race condition in Cosign.

**Recommended approach:**

* Run the SBOM and SLSA attestation steps **sequential** rather than in parallel way to avoid SLSA verification or SBOM policy enforcement failures.
* Place the SLSA generation step just after the **Docker Build and Push step.**
  {% endhint %}

### Run the pipeline <a href="#run-the-pipeline" id="run-the-pipeline"></a>

When the pipeline runs, the **SBOM Orchestration** step performs the following actions:

* Generates an SBOM in the chosen format for both Containers and Repositories.
* Specifically for Containers:
  * Generates and signs an attestation using the provided private key and password.
  * Stores the SBOM in Harness and uploads the `.att` file to your container registry.

SBOMs for both Containers and Code Repositories are accessible in the [Artifacts view](/software-supply-chain-assurance/use-scs/artifact-security/overview.md#sbom-tab). Additionally, you can locate the SBOM for any artifact on the **Supply Chain** tab within the **Execution Details** page in Harness.

<figure><img src="/files/AZpT7O5U9uaN8cob0rzB" alt=""><figcaption></figcaption></figure>

<details>

<summary>Example Pipeline for SBOM generation</summary>

These examples demonstrate how you could set up Build and Deploy stages to generate SBOM.

This example Build stage has three steps:Run step: Build and test an artifact (image).Build and Push an image to Docker Registry step: Build and push the image to a Docker registry.SBOM Orchestration step: Generate the SBOM.SBOM Orchestration in deploy stage can only be used in the Containerized Step Groups This example Deploy stage has two steps:SBOM Orchestration step: Generate the SBOM.Rolling deployment step: Deploy the image.

</details>

#### View vulnerabilities in the SBOM <a href="#view-vulnerabilities-in-the-sbom" id="view-vulnerabilities-in-the-sbom"></a>

After you run the SBOM orchestration step followed by the STO Snyk scan, the [SBOM tab](/software-supply-chain-assurance/use-scs/artifact-security/overview.md#sbom-tab) on the Artifacts page displays vulnerabilities for the components identified by Snyk. This helps you effectively identify and prioritize open source risks

#### Publish SBOM <a href="#publish-sbom" id="publish-sbom"></a>

After you run the SBOM Orchestration step, you can download or publish SBOM through multiple ways depending on your workflow:

* Via [Harness API](https://apidocs.harness.io/sbom/downloadsbomforartifact)
* Use the Download SBOM button available on the Artifacts page.
* Download the SBOM score for an artifact via [Harness API](https://apidocs.harness.io/sbom/getsbomscoreforartifact)
* Access the SBOM file directly from the pipeline output, generated under the default `/harness` working directory and is available at `/harness/harness/sbom/{sbom_<sbom_orchestration_step_execution_id>}.json`.

### Next steps <a href="#next-steps" id="next-steps"></a>

After generating an SBOM, you can apply [SBOM Policy Enforcement](/software-supply-chain-assurance/use-scs/open-source-management/enforce-sbom-policies.md) to achieve open source governance.
