# Versions

A Version represents a point-in-time snapshot of a Product's software composition within a specific Environment. Each Version is created when an SBOM is uploaded or ingested, and it serves as the central unit for vulnerability tracking, license analysis, compliance evaluation, and distribution.

***

## Overview

Versions are the operational core of Interlynk. While Products provide organizational grouping and Environments provide isolation, Versions hold the actual SBOM data — components, dependencies, vulnerabilities, licenses, and compliance status.

A Version may have multiple SBOMs associated with it (e.g., when an SBOM is re-uploaded to correct errors or add details), but only one SBOM is considered **active** at any time.

Key capabilities at the Version level:

* **Details** — metadata, TLP classification, lifecycle phase, dates, and CI traceability.
* **Relations (Parts)** — composition of multiple Product versions into a parent SBOM.
* **Components** — dependency tree, identifiers (PURL, CPE), suppliers, and support status.
* **Vulnerabilities** — CVE mapping, VEX status, severity scoring (CVSS, EPSS, KEV).
* **Licenses** — license inventory, obligations, and compliance review.
* **Checks** — SBOM quality and compliance evaluation results.
* **Change Log** — audit trail of all modifications.

## Architecture

```
Product
  └── Environment
        └── Version (Sbom)
              ├── Details (metadata, TLP, phase, lifecycle)
              ├── Parts (references to other Product versions)
              ├── Components
              │     ├── Dependency Tree
              │     ├── Identifiers (PURL, CPE)
              │     ├── Suppliers
              │     └── Support Status
              ├── Vulnerabilities
              │     ├── CVE / Advisory Mapping
              │     ├── VEX Status & Justification
              │     ├── CVSS / EPSS / KEV Scoring
              │     └── Custom Fields
              ├── Licenses
              │     ├── License Expressions
              │     └── Obligations
              ├── Checks (quality / compliance)
              └── Change Log (audit trail)
```

**Processing Pipeline:**

When an SBOM is uploaded, the platform executes a multi-stage processing pipeline:

```
Upload → SBOM Checks → Internal Labeling → Automation Rules → Vulnerability Scan → Component Support Analysis → Policy Evaluation
```

Each stage has a tracked status: `NOT_STARTED`, `IN_PROGRESS`, `COMPLETED`.

***

## Supported SBOM Formats

| Format    | Versions                     | Encodings |
| --------- | ---------------------------- | --------- |
| CycloneDX | 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 | JSON, XML |
| SPDX      | 2.2, 2.3                     | JSON      |

***

## Uploading SBOMs

### Via Dashboard

1. Navigate to the Product detail page.
2. Click **Upload SBOM**.
3. Select the target **Environment** from the dropdown.
4. Drag and drop the SBOM file or click to browse.
5. Click **Upload**.

### Via CLI

```bash
# Upload to default environment
pylynk upload --prod "my-backend-service" --sbom sbom.cdx.json

# Upload to a specific environment
pylynk upload --prod "my-backend-service" --env "production" --sbom sbom.cdx.json

# Upload with retry (useful in CI/CD)
pylynk upload --prod "my-backend-service" --sbom sbom.cdx.json --retries 5
```

| Parameter         | Required | Default                     | Description                                     |
| ----------------- | -------- | --------------------------- | ----------------------------------------------- |
| `--prod`          | Yes      | —                           | Product name                                    |
| `--sbom`          | Yes      | —                           | Path to the SBOM file                           |
| `--env`           | No       | `default`                   | Target environment name                         |
| `--retries`       | No       | `0`                         | Number of retry attempts for transient failures |
| `--token`         | No       | `$INTERLYNK_SECURITY_TOKEN` | Override authentication token                   |
| `-v`, `--verbose` | No       | Off                         | Enable verbose output                           |

**Retry behavior:**

| Condition        | Retried | Reason                 |
| ---------------- | ------- | ---------------------- |
| 5xx server error | Yes     | Transient server issue |
| 429 rate limit   | Yes     | Rate limiting          |
| 401 unauthorized | No      | Invalid credentials    |
| 4xx client error | No      | Request error          |
| Network error    | Yes     | Connectivity issue     |

The CLI uses exponential backoff (1s, 2s, 4s) between retry attempts.

### Via API

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -F operations='{"query":"mutation UploadSbom($input: UploadSbomInput!) { uploadSbom(input: $input) { sbom { id projectVersion } errors } }","variables":{"input":{"projectGroupName":"my-backend-service","projectName":"production","sbom":null}}}' \
  -F map='{"0":["variables.input.sbom"]}' \
  -F 0=@sbom.cdx.json
```

### Via CI/CD

**GitHub Actions:**

```yaml
env:
  INTERLYNK_SECURITY_TOKEN: ${{ secrets.INTERLYNK_SERVICE_TOKEN }}

steps:
  - name: Generate SBOM
    run: syft . -o cyclonedx-json > sbom.cdx.json

  - name: Upload SBOM to Interlynk
    run: pylynk upload --prod "my-backend-service" --env "production" --sbom sbom.cdx.json
```

**GitLab CI:**

```yaml
variables:
  INTERLYNK_SECURITY_TOKEN: $INTERLYNK_SERVICE_TOKEN

upload_sbom:
  script:
    - syft . -o cyclonedx-json > sbom.cdx.json
    - pylynk upload --prod "my-backend-service" --env "production" --sbom sbom.cdx.json
```

**Bitbucket Pipelines:**

```yaml
pipelines:
  default:
    - step:
        script:
          - syft . -o cyclonedx-json > sbom.cdx.json
          - pylynk upload --prod "my-backend-service" --env "production" --sbom sbom.cdx.json
```

**Azure DevOps:**

```yaml
steps:
  - script: |
      syft . -o cyclonedx-json > sbom.cdx.json
      pylynk upload --prod "my-backend-service" --env "production" --sbom sbom.cdx.json
    env:
      INTERLYNK_SECURITY_TOKEN: $(INTERLYNK_SERVICE_TOKEN)
```

When running in a supported CI environment, `pylynk` automatically captures CI metadata — commit SHA, PR details, build URL — and attaches it to the Version.

***

## Checking Processing Status

After upload, monitor the processing pipeline to confirm all stages complete:

```bash
# By version ID
pylynk status --prod "my-backend-service" --verId "abc-123-def"

# By product, environment, and version name
pylynk status --prod "my-backend-service" --env "production" --ver "v1.2.0"
```

| Parameter | Required | Default                     | Description                                   |
| --------- | -------- | --------------------------- | --------------------------------------------- |
| `--prod`  | Yes      | —                           | Product name                                  |
| `--verId` | No       | —                           | Version ID (alternative to `--env` + `--ver`) |
| `--env`   | No       | `default`                   | Environment name                              |
| `--ver`   | No       | —                           | Version string                                |
| `--token` | No       | `$INTERLYNK_SECURITY_TOKEN` | Override authentication token                 |

The status command tracks five processing stages:

| Stage              | Description                        |
| ------------------ | ---------------------------------- |
| `checksStatus`     | SBOM quality and compliance checks |
| `labelingStatus`   | Internal component labeling        |
| `automationStatus` | Automation rule execution          |
| `vulnScanStatus`   | Vulnerability scanning             |
| `policyStatus`     | Policy evaluation                  |

Each stage reports: `UNKNOWN`, `NOT_STARTED`, `IN_PROGRESS`, or `COMPLETED`.

***

## Version Details

### Metadata Fields

Each Version includes the following metadata:

| Field                   | Description                                                      |
| ----------------------- | ---------------------------------------------------------------- |
| **Version string**      | Product version identifier (e.g., `v1.2.0`, `build-456`)         |
| **Spec**                | SBOM format — CycloneDX or SPDX                                  |
| **Spec version**        | Format version (e.g., 1.5, 2.3)                                  |
| **Creation date**       | When the SBOM was created                                        |
| **Release date**        | When the software was released                                   |
| **End-of-support date** | When support ends for this version                               |
| **End-of-life date**    | When the version reaches end of life                             |
| **CI metadata**         | Build URL, commit SHA, PR details (captured automatically in CI) |

### TLP Classification

The Traffic Light Protocol (TLP) classification controls sharing restrictions for the SBOM:

| TLP Level            | Sharing Scope                             |
| -------------------- | ----------------------------------------- |
| **TLP:CLEAR**        | No restrictions on sharing                |
| **TLP:GREEN**        | Share within the community                |
| **TLP:AMBER**        | Share within the organization             |
| **TLP:AMBER+STRICT** | Share only with specific recipients       |
| **TLP:RED**          | Do not share outside of direct recipients |

TLP can be set when editing the Version's general metadata.

### Lifecycle Phase

Phases identify the product lifecycle stage that the SBOM represents. Phases are defined by the CycloneDX and SPDX specifications and include stages such as design, build, pre-release, and post-release.

### Editing Version Details

1. Navigate to the Product and select a Version.
2. Click the **General** tab.
3. Edit the desired fields:
   * **Phases** — identify the lifecycle stage(s) the SBOM represents.
   * **Creation Tool** — software tools and their versions used to build the SBOM.
   * **Authors** — entities that created the SBOM data.
   * **Supplier** — organization that built, distributed, or packaged the application.
   * **Data License** — set to `CC0-1.0` for consumers to freely use SBOM data.

{% hint style="info" %}
Interlynk is automatically added as a creation tool with the Vendor Name **Interlynk** and Tool Name **SbomZen**.
{% endhint %}

***

## Relations (Parts)

Parts represent other Product versions that are embedded in or compose the current Version. Use Parts to model assemblies, firmware bundles, or microservice compositions.

### What Parts Represent

* Optional hardware or software modules
* An assembly of applications on a device
* A set of microservices comprising a final service
* Third-party libraries distributed as separate Products

### Managing Parts

Parts are added or removed directly on the Version by referencing the version of another Product.

1. Navigate to the Product and select a Version.
2. Click the **Parts** tab.
3. Click **Add Part** to reference another Product version.
4. To remove a Part, click the remove action next to it.

When Parts are included, the parent Version inherits the components and vulnerabilities from each Part. This composition is reflected in downloads and compliance evaluations.

{% hint style="info" %}
When downloading an SBOM, you can include Part data by selecting the **Parts** option to embed components and vulnerabilities from all referenced Parts.
{% endhint %}

***

## Components

The Components tab displays the dependency tree extracted from the SBOM. Each component includes identifiers, version information, suppliers, and support status.

### Component Metadata

| Field              | Description                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------ |
| **Name**           | Component name                                                                             |
| **Version**        | Component version                                                                          |
| **Type**           | Component kind (e.g., library, framework, application, operating-system, device, firmware) |
| **PURL**           | Package URL — primary identifier for vulnerability and license matching                    |
| **CPE**            | Common Platform Enumeration — secondary identifier                                         |
| **License**        | License expression (e.g., `Apache-2.0`, `MIT OR GPL-2.0`)                                  |
| **Supplier**       | Entity distributing the component                                                          |
| **Support Status** | Maintenance state (actively maintained, no longer maintained, abandoned, unspecified)      |

### Dependency Tree

Components are displayed in a hierarchical tree showing dependency relationships. The tree shows:

* **Direct dependencies** — components explicitly declared.
* **Transitive dependencies** — components pulled in by direct dependencies.
* **Component kinds** — 14 types including library, framework, application, operating-system, device, firmware, and more.

### Component Identification

Components are identified using two primary schemes:

| Scheme   | Format                             | Example                                       | Usage                                                              |
| -------- | ---------------------------------- | --------------------------------------------- | ------------------------------------------------------------------ |
| **PURL** | `pkg:type/namespace/name@version`  | `pkg:npm/%40angular/core@16.2.0`              | Primary identifier for vulnerability mapping and license detection |
| **CPE**  | `cpe:2.3:a:vendor:product:version` | `cpe:2.3:a:apache:log4j:2.17.1:*:*:*:*:*:*:*` | Secondary identifier, used for NVD vulnerability matching          |

{% hint style="warning" %}
Components without PURL or CPE identifiers cannot be matched against vulnerability databases. Ensure your SBOM generation tools include identifiers for accurate vulnerability and license detection.
{% endhint %}

### Editing Components

1. Navigate to the Product and select a Version.
2. Click the **Components** tab.
3. Select a component to view details.
4. Edit fields such as license expression, supplier information, or identifiers.

***

## Vulnerabilities

The Vulnerabilities tab displays all known vulnerabilities mapped to the Version's components. Vulnerabilities are discovered through automated scanning using PURL and CPE identifiers.

### Vulnerability Sources

Vulnerabilities are sourced from multiple databases:

* **NVD** — National Vulnerability Database (CVE)
* **OSV** — Open Source Vulnerability database
* **GitHub Advisory Database**
* **Vendor-specific advisories**

### Severity and Scoring

| Metric   | Description                                                               |
| -------- | ------------------------------------------------------------------------- |
| **CVSS** | Common Vulnerability Scoring System — severity score (0.0–10.0)           |
| **EPSS** | Exploit Prediction Scoring System — probability of exploitation (0.0–1.0) |
| **KEV**  | Known Exploited Vulnerabilities catalog — actively exploited in the wild  |
| **CWE**  | Common Weakness Enumeration — root cause classification                   |

### VEX Status (Vulnerability Disposition)

The VEX (Vulnerability Exploitability eXchange) standard defines how to declare the exploitability status of a vulnerability:

| Status                  | Description                                                     |
| ----------------------- | --------------------------------------------------------------- |
| **Not Affected**        | The vulnerability does not affect this Product                  |
| **Affected**            | The vulnerability affects this Product and requires remediation |
| **Fixed**               | The vulnerability has been remediated                           |
| **Under Investigation** | The vulnerability is being analyzed                             |

### Not Affected Justifications

When setting a vulnerability to **Not Affected**, a justification is required:

| Justification                                         | Description                                           |
| ----------------------------------------------------- | ----------------------------------------------------- |
| **Component Not Present**                             | The vulnerable component is not included in the build |
| **Vulnerable Code Not Present**                       | The specific vulnerable code path is not included     |
| **Vulnerable Code Cannot Be Controlled by Adversary** | The vulnerability cannot be triggered by an attacker  |
| **Vulnerable Code Not in Execute Path**               | The vulnerable code is not reachable at runtime       |
| **Inline Mitigations Already Exist**                  | Existing controls prevent exploitation                |

### Managing Vulnerability Status

Vulnerabilities can be triaged individually or in bulk:

* **Set status for a single vulnerability** — click on the vulnerability and update the VEX status.
* **Import statuses from previous versions** — carry forward triage decisions using VEX retention settings.
* **Set status across multiple versions** — apply a disposition to the same vulnerability across all versions of a Product.
* **Set status across multiple products** — apply a disposition organization-wide.

### Querying Vulnerabilities via CLI

```bash
# List vulnerabilities for a product
pylynk vulns --prod "my-backend-service"

# Include vulnerability and VEX details
pylynk vulns --prod "my-backend-service" --vuln-details --vex-details

# Custom columns
pylynk vulns --prod "my-backend-service" --columns "id,component_name,severity,cvss,status"

# List available columns
pylynk vulns --list-columns
```

| Parameter        | Required | Default     | Description                            |
| ---------------- | -------- | ----------- | -------------------------------------- |
| `--prod`         | Yes      | —           | Product name                           |
| `--env`          | No       | `default`   | Environment name                       |
| `--vuln-details` | No       | Off         | Include vulnerability metadata         |
| `--vex-details`  | No       | Off         | Include VEX status details             |
| `--columns`      | No       | Default set | Comma-separated list of output columns |
| `--list-columns` | No       | —           | Display all available column names     |
| `--output`       | No       | `table`     | Output format: `table`, `json`, `csv`  |

### Integration with Issue Trackers

Vulnerabilities can be linked to external issue trackers for remediation tracking:

* **Jira** — create tickets directly from vulnerability details.
* **Linear** — create issues from vulnerability details.

For integration setup, see [Administration: Integrations](https://docs.interlynk.io/administration/integrations).

***

## Licenses

The Licenses tab displays the license inventory for all components in the Version. License data supports compliance review and obligation tracking.

### License Information

Each component may declare one or more licenses using SPDX license expressions:

| Field                  | Description                                            |
| ---------------------- | ------------------------------------------------------ |
| **License Expression** | SPDX expression (e.g., `Apache-2.0`, `MIT OR GPL-2.0`) |
| **License Name**       | Human-readable name                                    |
| **License URL**        | Link to the full license text                          |

### Editing License Details

1. Navigate to the Product and select a Version.
2. Click the **Licenses** tab.
3. Select a component to view or edit its license information.
4. Update the license expression, name, or URL.

{% hint style="info" %}
When **Interpret License List as "AND" expression** is enabled in Environment Settings, multi-license declarations are treated as requiring all listed licenses (conjunctive interpretation). When disabled, they are treated as alternatives (disjunctive interpretation).
{% endhint %}

***

## Downloading SBOMs

The platform can return enhanced SBOMs — the original SBOM enriched with vulnerability data, support status, and compliance annotations.

### Via CLI

```bash
# Download enhanced SBOM with vulnerabilities
pylynk download --prod "my-backend-service" --env "production" --ver "v1.2.0" \
  --out-file enhanced-sbom.json \
  --vuln true \
  --include-support-status

# Download in a specific format
pylynk download --verId "abc-123-def" \
  --spec CycloneDX --spec-version 1.5 \
  --out-file sbom.json

# Download original (unmodified) SBOM
pylynk download --verId "abc-123-def" --original --out-file original-sbom.json

# Download lightweight SBOM
pylynk download --verId "abc-123-def" --lite --out-file sbom-lite.json

# Export support status as CSV
pylynk download --verId "abc-123-def" --support-level-only --out-file support.csv
```

| Parameter                  | Required    | Default   | Description                                          |
| -------------------------- | ----------- | --------- | ---------------------------------------------------- |
| `--prod`                   | Conditional | —         | Product name (use with `--env` and `--ver`)          |
| `--env`                    | No          | `default` | Environment name                                     |
| `--ver`                    | No          | —         | Version string                                       |
| `--verId`                  | Conditional | —         | Version ID (alternative to `--prod`/`--env`/`--ver`) |
| `--out-file`               | No          | stdout    | Output file path                                     |
| `--vuln`                   | No          | `false`   | Include vulnerability data                           |
| `--include-support-status` | No          | Off       | Include component support status                     |
| `--spec`                   | No          | Original  | Output format: `CycloneDX` or `SPDX`                 |
| `--spec-version`           | No          | Original  | Specification version (e.g., `1.5`, `2.3`)           |
| `--original`               | No          | Off       | Download unmodified original SBOM                    |
| `--lite`                   | No          | Off       | Download lightweight version                         |
| `--support-level-only`     | No          | Off       | Export support levels as CSV                         |

### Via Dashboard

1. Navigate to the Product and select a Version.
2. Click the **Download** button.
3. Select the specification and format:
   * CycloneDX 1.5 (JSON)
   * SPDX 2.3 (JSON)
   * PDF
4. Select content options:
   * **Parts** — include components and vulnerabilities from Parts.
   * **Vulnerabilities** — include vulnerability details (CycloneDX only).
   * **Vulnerability Status** — include VEX data (CycloneDX only).
   * **Base64 Unencoded** — make encoded content readable.
5. Click **Download**.

{% hint style="info" %}
The download view shows a summary of Compliance Checks so you can verify requirements before distribution.
{% endhint %}

### ShareLynk (Automated Distribution)

ShareLynk generates a shareable link for automatic SBOM distribution:

1. Navigate to the **Products** page.
2. Click **...** (Actions) on the Product and select **View ShareLynk**.
3. Click **+** (Add ShareLynk).
4. Set an expiration date or select **No Expiration**.
5. Click **Add** and copy the generated link.

ShareLynk makes all Environments accessible to the recipient and automatically shares SBOMs for newer Versions until the expiration date.

***

## Listing Versions

### Via CLI

```bash
# List versions for a product
pylynk vers --prod "my-backend-service"

# List versions for a specific environment
pylynk vers --prod "my-backend-service" --env "production"

# Output as JSON
pylynk vers --prod "my-backend-service" --output json
```

| Parameter      | Required | Default | Description                                 |
| -------------- | -------- | ------- | ------------------------------------------- |
| `--prod`       | Yes      | —       | Product name                                |
| `--env`        | No       | All     | Filter by environment                       |
| `--output`     | No       | `table` | Output format: `table`, `json`, `csv`       |
| `--human-time` | No       | Off     | Display timestamps in human-readable format |

### Via Dashboard

1. Navigate to the Product detail page.
2. Select an Environment.
3. The **Versions** list displays all versions in the selected Environment, sorted by creation date.

***

## Version Comparison (Drift Analysis)

Compare two Versions to identify component drift — added, removed, and modified components between releases.

### Via MCP

```
compare_versions       # Shows added, removed, and modified components between two versions
```

This is useful for:

* Tracking component changes across releases.
* Identifying newly introduced risks.
* Validating that expected dependency updates were applied.
* Detecting unexpected dependency additions.

***

## SBOM Building

The platform supports manually building SBOMs when a generated SBOM is not available. Manual builds allow creating a Version by adding components individually through the Dashboard.

{% hint style="info" %}
Manually built versions do not support downloading the original SBOM — only the updated format is available.
{% endhint %}

***

## Compliance Evaluation

The **Checks** tab on a Version displays quality and compliance evaluation results. Checks are run automatically when **Run SBOM Checks** is enabled in Environment Settings.

Check results indicate whether the SBOM meets defined quality standards and compliance requirements. Failed checks can be resolved by:

* Editing the SBOM metadata or components manually.
* Creating Automation Rules from check results (click **Fix** > **Save as Rule**).

For policy-based compliance evaluation, see the **Policies** section in the Product Settings.

***

## Permission Matrix

| Permission           | Admin | Operator | Viewer |
| -------------------- | :---: | :------: | :----: |
| View SBOMs           |   ✓   |     ✓    |    ✓   |
| Update SBOMs         |   ✓   |     ✓    |    —   |
| Delete SBOMs         |   ✓   |     ✓    |    —   |
| Edit SBOM components |   ✓   |     ✓    |    —   |
| Edit vulnerabilities |   ✓   |     ✓    |    —   |
| Edit checks          |   ✓   |     ✓    |    —   |
| Sign SBOMs           |   ✓   |     ✓    |    —   |
| Reprocess SBOMs      |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](https://docs.interlynk.io/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Deleting a Version is irreversible.** All associated component data, vulnerability triage decisions (VEX), compliance results, and audit history are permanently removed.
{% endhint %}

{% hint style="warning" %}
**VEX status is lost on re-upload unless retention is enabled.** Enable "Retain Vulnerability Status with Version" in Environment Settings to preserve triage decisions when replacing an SBOM.
{% endhint %}

{% hint style="warning" %}
**Components without PURL or CPE identifiers will not be matched against vulnerability databases.** Ensure your SBOM generation tools produce identifiers for all components to avoid blind spots in vulnerability detection.
{% endhint %}

{% hint style="warning" %}
**ShareLynk exposes SBOM data to anyone with the link.** Set an expiration date and revoke links when they are no longer needed. Review active ShareLynk links periodically.
{% endhint %}

***

## Common Misconfigurations

| Issue                                                | Symptom                                  | Fix                                                                       |
| ---------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------- |
| Same SBOM uploaded repeatedly with no version change | Duplicate Versions clutter the list      | Use unique version strings for each build                                 |
| VEX status lost on re-upload                         | Triage work disappears after SBOM update | Enable "Retain Vulnerability Status with Version" in Environment Settings |
| Processing stuck in `IN_PROGRESS`                    | Status never completes                   | Check for malformed SBOM; verify the SBOM format is supported             |
| No CI metadata attached                              | Build traceability missing               | Ensure `pylynk` runs in a supported CI environment                        |
| Version uploaded to wrong Environment                | Data appears in unexpected location      | Verify `--env` flag in CLI or Environment Rules configuration             |
| No vulnerability data after upload                   | Vulnerabilities tab is empty             | Enable "Run Vulnerability Scan" in Environment Settings                   |
| Components missing from vulnerability scan           | Known-vulnerable components not flagged  | Verify SBOM includes PURL or CPE identifiers for components               |
| Download missing vulnerability data                  | Enhanced SBOM has no VEX data            | Use `--vuln true` flag when downloading via CLI                           |
| Parts not reflected in download                      | Downloaded SBOM excludes Part components | Select the **Parts** option when downloading                              |

***

## Recommended Best Practices

* **Use meaningful version strings.** Align with your release versioning scheme (semver, build numbers, commit SHAs) so Versions are traceable to specific builds.
* **Upload SBOMs in CI/CD, not manually.** Automated uploads ensure every build is tracked and reduce the risk of missed or inconsistent data.
* **Enable "Retain Vulnerability Status with Version"** to avoid re-triaging vulnerabilities on each SBOM update.
* **Enable "Copy VEX Across Versions on Import"** if your workflow involves frequent updates, so triage decisions carry forward automatically.
* **Set a data retention policy.** Use at least 90 days for audit trail purposes. Use "Forever" for Products with regulatory requirements.
* **Download enhanced SBOMs for distribution.** The enhanced SBOM includes vulnerability and support data not present in the original upload.
* **Monitor processing status in CI/CD.** Use `pylynk status` after upload to confirm all stages complete before marking builds as successful.
* **Use Parts for composite applications.** Model microservice bundles, firmware assemblies, or multi-module applications using the Parts system rather than combining SBOMs manually.
* **Triage vulnerabilities promptly.** Set VEX status for discovered vulnerabilities to distinguish real risks from false positives.
* **Include PURL and CPE identifiers** in your SBOM generation pipeline for accurate vulnerability and license detection.
