# Getting Started

## What is Interlynk?

Interlynk is a platform for automating software supply chain security. It uses Software Bill of Materials (SBOM) and Vulnerability Exploitability eXchange (VEX) as base artifacts for managing and eliminating software supply chain risks.

With Interlynk, you can:

* **Generate SBOMs** — Produce CycloneDX SBOMs from your build systems and package manifests with [lynkctl](/lynkctl/lynkctl)
* **Manage SBOMs** — Request and collect SBOMs from first-party build pipelines or third-party suppliers
* **Monitor vulnerabilities** — Continuously track open-source dependencies and security vulnerabilities
* **Enforce policies** — Prevent vulnerable, malicious, or insecure components from entering your codebase
* **Prioritize remediation** — Implement risk-based prioritization for vulnerability remediation
* **Meet compliance requirements** — Satisfy open-source license and SBOM compliance obligations

## How It Works

Interlynk organizes your software supply chain data in a hierarchical model:

```
Organization → Product → Environment → Version (SBOM) → Components → Vulnerabilities
```

Upload an SBOM to a Product's Environment, and the platform automatically processes it — running quality checks, scanning for vulnerabilities, evaluating policies, and surfacing actionable insights.

To learn more, see [Core Concepts](/interlynk-core-concepts/core-concepts).

## Quick Start

### 1. Set Up Your Organization

* [Manage users](/administration/user-management) and [assign roles](/administration/role-management)
* [Configure integrations](/administration/integrations) with GitHub, GitLab, Jira, Slack, and more
* [Set up SSO](/administration/sso) for your team

### 2. Create Products and Upload SBOMs

* [Generate an SBOM](/lynkctl/lynkctl) from your build system or package manifests with lynkctl
* [Create a Product](/product-guides/sbom-management/products) to represent your software
* [Upload SBOMs](/product-guides/sbom-management/versions) to track versions over time
* [Review packages](/product-guides/sbom-management/packages) and their dependencies

### 3. Monitor Security and Compliance

* [Track vulnerabilities](/product-guides/security-and-compliance/vulnerabilities) across your software
* [Review licenses](/product-guides/security-and-compliance/licenses) for compliance
* [Create policies](/product-guides/security-and-compliance/policies) to enforce standards

### 4. Gain Insights

* [View analytics](/product-guides/insights/analytics) across your portfolio
* [Assess tool coverage](/product-guides/insights/tools) in your pipelines

## Productivity Tools

Interlynk provides CLI tools to integrate with your workflows:

* [pylynk](/productivity-tools/pylynk) — Python CLI for the Interlynk API
* [lynk-mcp](/productivity-tools/lynk-mcp) — MCP server for AI-assisted workflows
* [sbomqs](/productivity-tools/sbomqs) — SBOM quality scoring
* [sbomasm](/productivity-tools/sbomasm) — SBOM assembly and manipulation


# SBOM Management


# Products

Products are the top-level organizational unit in Interlynk. Each Product represents a software artifact your organization builds, releases, and tracks — such as a web application, library, firmware image, or container. All SBOM data, vulnerability tracking, policy evaluation, and compliance reporting is scoped to a Product and its Environments.

***

## Overview

A Product groups all SBOM versions, vulnerability data, policies, and automation rules for a single software artifact. Products provide logical isolation — each has its own Environments, settings, labels, and notification subscriptions.

Products support:

* **Environments** — isolated contexts (e.g., Development, Production) with independent settings, automation rules, and policies.
* **Automation Rules** — conditional actions that modify SBOMs on import (e.g., set missing supplier fields, apply license expressions).
* **Labels** — color-coded tags for cross-cutting categorization (e.g., `compliance:fda`, `team:platform`).
* **Notifications** — per-environment subscriptions for vulnerability, license, and policy changes.
* **Settings** — per-environment controls for scanning, data retention, and integrations.

## Architecture

```
Organization
  └── Product (ProjectGroup)
        ├── Environment: Default
        │     ├── Versions (SBOMs)
        │     ├── Automation Rules
        │     ├── Settings (scan, retention, VEX)
        │     └── Policies
        ├── Environment: Development
        │     └── ...
        ├── Environment: Production
        │     └── ...
        ├── Labels
        ├── Notifications
        └── Change Log (Activity Audit)
```

**Interactions:**

* **Dashboard** — create, configure, disable, and delete Products.
* **CLI** (`pylynk prods`) — list Products, upload SBOMs (auto-creates Products).
* **API** — GraphQL mutations for creating, updating, and deleting Products (`ProjectGroup` model).
* **MCP** (`lynk-mcp`) — read-only queries for listing and inspecting Products.

***

## Product Lifecycle

| State        | Behavior                                                                                                                                                                  |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Active**   | Accepts SBOM uploads, vulnerability scanning runs, contributes to metrics and analytics.                                                                                  |
| **Disabled** | Stops accepting new Versions and SBOMs. Vulnerability updates halt. Excluded from platform metrics and analytics. Existing data remains accessible for historical review. |
| **Deleted**  | Permanently removed. All associated Environments, Versions, Components, and Vulnerabilities are deleted.                                                                  |

A disabled Product can be re-enabled. Deletion is irreversible.

{% hint style="warning" %}
Deleting a Product removes all associated data permanently. Disable Products instead if you need to preserve historical data for audit purposes.
{% endhint %}

***

## Creating Products

### Via Dashboard

1. Navigate to the **Products** page.
2. Click the **+** (Add Product) button in the top right.
3. Enter the **Name** (required) and optional **Description**.
4. Click **Save**.

The Product is created with three default Environments: Default, Development, and Production.

### Via CLI

The `pylynk` CLI creates Products implicitly on first SBOM upload if they do not already exist:

```bash
pylynk upload --prod "my-backend-service" --sbom sbom.cdx.json
```

To list existing Products:

```bash
pylynk prods
pylynk prods --output json
pylynk prods --output csv
```

| Parameter         | Required | Default                     | Description                                 |
| ----------------- | -------- | --------------------------- | ------------------------------------------- |
| `--output`        | No       | `table`                     | Output format: `table`, `json`, `csv`       |
| `--human-time`    | No       | Off                         | Display timestamps in human-readable format |
| `--token`         | No       | `$INTERLYNK_SECURITY_TOKEN` | Override authentication token               |
| `-v`, `--verbose` | No       | Off                         | Enable verbose output                       |

### Via API

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation CreateProduct($input: CreateProjectGroupInput!) { createProjectGroup(input: $input) { projectGroup { id name } errors } }",
    "variables": {
      "input": {
        "name": "my-backend-service",
        "description": "Core backend API service"
      }
    }
  }'
```

### Via MCP

The `lynk-mcp` server provides read-only access to Products:

```
list_products          # List all products
get_product            # Get product details with all environments
```

{% hint style="info" %}
Product creation via MCP is not supported. Use the Dashboard, API, or CLI to create Products.
{% endhint %}

***

## Disabling and Deleting Products

### Disabling a Product

1. Navigate to the **Products** page.
2. Click the **Active** toggle switch on the Product row to disable it.

A disabled Product:

* Stops accepting version creation and SBOM uploads.
* Stops updating vulnerabilities for existing versions.
* Does not contribute to platform metrics and analytics.
* Can be re-enabled at any time.

{% hint style="info" %}
If a disabled Product is not visible in the list, check the **Active** filter at the top of the Products table — it defaults to showing only active Products.
{% endhint %}

### Deleting a Product

1. Navigate to the **Products** page.
2. Click the **...** (Actions) on the Product row and select **Delete Product**.
3. Type `DELETE` in the confirmation modal and click **Yes**.

Alternatively, from inside the Product Environment page, click the **Delete Product** icon.

***

## Environments

Each Product is created with three default Environments: **Default**, **Development**, and **Production**. Environments provide isolated contexts within a Product — each has its own versions, automation rules, settings, and policies.

| Environment     | Typical Use                                                       |
| --------------- | ----------------------------------------------------------------- |
| **Default**     | Catch-all for SBOMs that do not match a specific environment rule |
| **Development** | Feature branches, development builds, pre-release testing         |
| **Production**  | Main/master branch, release tags, production deployments          |

Environments are mapped to incoming SBOMs via [Environment Rules](/administration/environment-rules). You can create additional environments to match your deployment topology (e.g., `staging`, `qa`).

For full details on environment configuration, see [Core Concepts: Environments](/interlynk-core-concepts/environments) and [Administration: Environment Rules](/administration/environment-rules).

***

## Automation Rules

Automation Rules modify SBOMs automatically on import, reducing manual toil for recurring quality and compliance fixes. Rules consist of a **name**, a set of **conditions** to match, and **actions** to take when conditions are met.

### Rule Structure

Rules apply to one of two subject types:

| Subject       | Description                                               | Example                                                                                      |
| ------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| **Version**   | Conditions and actions target version-level SBOM metadata | Set the Supplier Contact Name when it is missing                                             |
| **Component** | Conditions and actions target a specific component        | Set license expression to `Apache-2.0` when Component Name is `log4j` and license is missing |

{% hint style="info" %}
Automation Rules are configured per Environment. Rules can be copied from one Environment to another.
{% endhint %}

### Creating Rules Manually

1. Navigate to the **Products** page and click the Product Name.
2. Select the target Environment.
3. Click the **Automation Rules** tab.
4. Click **+** (Add Rule).
5. Enter a **Rule Name**.
6. Select conditions to match — once the first condition is specified, additional conditions apply to the same subject.
7. Add actions — actions only apply to subjects matching the conditions.
8. Click **Create**.

### Creating Rules from Checks

When an SBOM fails a check, you can create a rule directly from the check result:

1. Navigate to the Product and select a Version.
2. Click the **Checks** tab.
3. Click the **Fix** icon under Resolution.
4. Configure the fix.
5. Click **Save as Rule** to create an Automation Rule.

The same drawer can also fix the check on this SBOM alone: **Save** applies the correction to the current Version, while **Save as Rule** turns it into an Automation Rule that applies to future uploads. Use the rule when the same gap recurs across builds, and the direct save for a one-off correction. See [Fixing a Failed Check](/product-guides/sbom-management/versions#fixing-a-failed-check).

### Rule Priority and Ordering

Rules are evaluated in order. To reorder:

1. Navigate to the **Automation Rules** tab.
2. Use the drag handle on each rule to reorder.

Rules with higher position (lower in the list) execute last and can override earlier rules.

### Copying Rules Between Environments

1. Navigate to the **Automation Rules** tab.
2. Click the **...** (Actions) on the rule.
3. Select **Copy To \[Environment Name]**.

### Disabling Rules

* **Individual rule**: Toggle the **Active** switch on the rule row.
* **All automation for an environment**: Navigate to the **Settings** tab and toggle the **Automation** switch off.

{% hint style="warning" %}
Disabling automation in Settings is per-Environment. To disable automation across all Environments, repeat for each one.
{% endhint %}

### Rules Library

The platform ships with a library of common rules (e.g., copying Author Name to Supplier Name). These rules are disabled by default and can be enabled as needed.

### Applying Rules

* **Automatic**: Rules are applied on every SBOM import. Changes are logged in the SBOM's Change Log.
* **Manual**: Navigate to the Product Environment page, click **...** (Actions) on a Version, and select **Run Automation**.

***

## Product Settings

Each Environment within a Product has its own settings that control scanning behavior, data retention, and integration features. Settings are inherited from [Organization Environment Defaults](/administration/environment-defaults) at creation time and can be customized per Environment.

The Settings tab has a left-hand navigation with two pages: **Import & defaults**, and **Issue trackers** for the defaults applied to tickets Interlynk creates. Each entry under a page jumps to that section, so nothing is more than one click away.

### Import Behavior

| Setting                                      | Description                                                                      |
| -------------------------------------------- | -------------------------------------------------------------------------------- |
| **Use latest versions of referenced parts**  | When a version depends on another part, use the most recent version of that part |
| **Mark internal components on import**       | Mark detected internal components as the SBOM is imported                        |
| **Run environment automation rules**         | Apply this Environment's automation rules after each SBOM import                 |
| **Treat license lists as "AND" expressions** | Combine listed licenses with AND instead of the default OR SPDX expression       |

### Automated Analysis

| Setting                                    | Description                                                                                                                                                                                                               |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Run SBOM checks after import**           | Find issues in imported SBOMs as part of the import workflow                                                                                                                                                              |
| **Scan for vulnerabilities after import**  | Automatically scan imported components for known vulnerabilities                                                                                                                                                          |
| **Overwrite Existing VEX Dispositions**    | Allow imported VEX data to replace existing dispositions when there is a conflict. See [Importing Third-Party VEX Documents](/product-guides/security-and-compliance/vulnerabilities#importing-third-party-vex-documents) |
| **Analyze component support after import** | Automatically determine component support status                                                                                                                                                                          |

### Version Lifecycle

| Setting                                                     | Description                                                                                                                                                                               |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Archive older versions after import**                     | Archive every enabled version except the latest uploaded version. Confirmation is required                                                                                                |
| **Preserve vulnerability status on same-version re-import** | Keep existing vulnerability decisions when a pipeline uploads the same product version again                                                                                              |
| **Carry VEX forward to the latest version**                 | Copy existing VEX information when a new version is imported                                                                                                                              |
| **Reuse Jira tickets for matching vulnerabilities**         | Link existing Jira tickets when the same vulnerability appears in another SBOM version                                                                                                    |
| **Reuse Jira tickets across environments**                  | Reuse existing Jira tickets for matching vulnerabilities in other Environments of this Product when the Jira project matches. See [Jira: Ticket Reuse](/administration/jira#ticket-reuse) |

{% hint style="info" %}
**Reuse Jira tickets across environments** is Product-wide, not per-Environment. Toggling it applies the same value to every Environment in the Product. If Environments currently disagree, the row says so, and toggling aligns them.
{% endhint %}

### Environment Defaults

| Setting                              | Options                                | Default |
| ------------------------------------ | -------------------------------------- | ------- |
| **Retain SBOM data for**             | 1, 30, 90, 365 days, or Forever        | Forever |
| **Default manufacturer for exports** | Any organization manufacturer          | Not set |
| **Default TLP classification**       | CLEAR, GREEN, AMBER, AMBER+STRICT, RED | Not set |

### Pull Request Integration

| Setting                          | Description                                      |
| -------------------------------- | ------------------------------------------------ |
| **Enable pull request comments** | Allow Interlynk to add comments to pull requests |

### SBOM Doctor Checks

When SBOM Doctor is enabled for the organization, this section controls which checks run for the Environment. See [SBOM Doctor](/product-guides/sbom-management/doctor).

### Configuring Settings

1. Navigate to the Product and select the target Environment.
2. Click the **Settings** tab.
3. Use the left-hand navigation to reach a section, then toggle settings or pick values.
4. Changes are saved automatically.

Editing these settings requires the **Edit product settings** permission. See [Role Management](/administration/role-management).

***

## Support Status

Support status tracking monitors the maintenance state of components within a Product's SBOMs. When **Run Component Support Analysis** is enabled in Settings, the platform evaluates each component and assigns a support level:

| Support Level            | Description                                                      |
| ------------------------ | ---------------------------------------------------------------- |
| **Actively Maintained**  | Component is actively developed and receives updates             |
| **No Longer Maintained** | Component has stopped receiving updates but is not yet abandoned |
| **Abandoned**            | Component is no longer maintained or supported                   |
| **Unspecified**          | Support status could not be determined                           |

Support status data is visible on the Version detail page under the **Support** tab and can be included in downloaded SBOMs using the `--include-support-status` flag.

For support level overrides and organization-wide support management, see [Administration: Health Scoring](/administration/health-scoring).

***

## Labels

Labels are color-coded tags applied to Products for cross-cutting categorization and filtering. Use labels to group Products by team, compliance requirement, tier, or any other dimension.

### Managing Labels

1. Navigate to the **Products** page.
2. Click the **Manage Labels** icon in the top right.

**Create a Label:**

1. Enter a **Name** for the label.
2. Type a color hex code or click the auto-shuffle icon for random colors.
3. Preview the label in the **Label Preview** badge.
4. Click **+ Add Label**.

**Edit a Label:**

1. Click the **Edit** icon next to the label.
2. Modify the name or color.
3. Click the Accept or Cancel icon.

**Delete a Label:**

1. Remove the label from all Products it is applied to first.
2. Click the **Delete** icon next to the label.

{% hint style="warning" %}
Labels must be removed from all Products before they can be deleted.
{% endhint %}

### Applying Labels to Products

From the Products list:

1. Navigate to the **Products** page.
2. Click **...** (Edit Labels) on the Product row.
3. Select labels from the checkbox list.
4. Click outside the submenu to apply.

From a Product's details page:

1. Open the Product.
2. Open the **...** (Actions) menu.
3. Hover **Assign Labels** and select labels from the flyout.

Labels are visible on the Products list and can be used to filter and sort Products.

{% hint style="info" %}
Assigning labels requires the Update Products permission. The action is not available on the free tier or through a share link.
{% endhint %}

***

## Pinned Products

Pin up to 8 frequently accessed Products for one-click access. Pinned Products appear in a compact **Pinned** strip above the main Products table, one entry per product showing its name and environment tag.

A red dot on an entry means the latest SBOM has critical vulnerabilities. Hovering an entry opens a preview with the product's counts and status, plus a link to open it.

Pins are personal. Each user's pinned list is independent.

### Pinning a Product

1. Navigate to the **Products** page.
2. Open the **...** (Actions) menu on the Product row.
3. Select **Pin Product**.

The action is disabled once you have reached the 8-product limit. The pin counter next to the **Pinned** heading shows how many of the 8 you have used.

### Unpinning a Product

1. In the **Pinned** strip, click **Manage**.
2. Click the remove icon on the entry you want to unpin.
3. Click **Done**.

You can also unpin from the Products table through the row's **...** (Actions) menu.

***

## Change Log

The Change Log provides an audit trail of all modifications made to a Product's SBOMs. Every change resulting from automation rules, manual edits, or system processing is recorded.

### Viewing the Change Log

1. Navigate to the Product and select a Version.
2. Click the **Change Log** tab.

The Change Log displays:

| Column        | Description                                                   |
| ------------- | ------------------------------------------------------------- |
| **Timestamp** | When the change occurred                                      |
| **Action**    | What was changed (e.g., field update, component modification) |
| **Source**    | Whether the change was manual, automated, or system-generated |
| **Details**   | Specific values before and after the change                   |

***

## Notifications

Users can subscribe to notifications for changes within a Product's Environments. Notifications alert on vulnerability discoveries, license changes, and policy failures.

### Subscribing to Notifications

1. Navigate to the Product Environment page.
2. Click the **Bell** icon.
3. Select notification categories: **Vulnerabilities**, **Licenses**, **Policies**, or **All**.

Notifications are delivered based on configured integrations — [Slack](/administration/slack), [Microsoft Teams](/administration/microsoft-teams), or [Email](/administration/email).

{% hint style="info" %}
At least one integration must be configured in **Settings > Organization > Integrations > Connections** before notifications become effective.
{% endhint %}

***

## Permission Matrix

| Permission                | Admin | Operator | Viewer |
| ------------------------- | :---: | :------: | :----: |
| View products             |   ✓   |     ✓    |    ✓   |
| Create products           |   ✓   |     ✓    |    —   |
| Update products           |   ✓   |     ✓    |    —   |
| Delete products           |   ✓   |     ✓    |    —   |
| Edit share link           |   ✓   |     ✓    |    —   |
| Edit product automations  |   ✓   |     ✓    |    —   |
| Edit product policies     |   ✓   |     ✓    |    —   |
| Edit product integrations |   ✓   |     ✓    |    —   |
| Edit product settings     |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Product deletion is irreversible.** All Environments, Versions, Components, Vulnerabilities, and audit history are permanently removed. Disable Products instead of deleting them if you need to preserve historical data.
{% endhint %}

{% hint style="warning" %}
**Automation rules execute on every import.** Misconfigured rules can silently modify SBOM data at scale. Test rules on a development environment before enabling them in production.
{% endhint %}

{% hint style="warning" %}
**"Apply to All Projects" overwrites per-project settings.** Use this action only when you intentionally want to standardize all projects. Per-project customizations will be lost.
{% endhint %}

***

## Common Misconfigurations

| Issue                                   | Symptom                                                   | Fix                                                                      |
| --------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------ |
| Duplicate Products for the same service | Fragmented vulnerability data, inconsistent metrics       | Consolidate SBOMs under a single Product; delete the duplicate           |
| Product name mismatch in CI/CD          | New Products created unintentionally on each pipeline run | Standardize the `--prod` value in pipeline configuration                 |
| Product disabled accidentally           | SBOM uploads rejected with no clear error                 | Re-enable the Product from the Products page (check the Active filter)   |
| Automation rules not running            | SBOM data not modified on import                          | Check that **Apply Automation Rules** is enabled in Environment Settings |
| Rules configured in wrong Environment   | Automation applies to development but not production      | Copy rules to the correct Environment or configure per-environment rules |
| Notifications not delivered             | No alerts on vulnerability changes                        | Verify at least one integration (Slack, Teams, Email) is configured      |
| Vulnerability scanning disabled         | No vulnerability data after SBOM upload                   | Enable **Run Vulnerability Scan** in Environment Settings                |
| Labels not deletable                    | Delete action fails silently                              | Remove the label from all Products before deleting                       |

***

## Recommended Best Practices

* **Use consistent naming conventions.** Adopt a pattern such as `team-service-name` or `org/repo-name` so Products are easily identifiable and sortable.
* **Use labels for cross-cutting categorization.** Labels like `compliance:fda`, `team:platform`, `tier:critical` allow filtering and grouping without duplicating Product definitions.
* **Avoid creating duplicate Products.** If a Product already exists, upload SBOMs to it rather than creating a new one with a similar name.
* **Disable rather than delete.** If a Product reaches end-of-life, disable it to preserve historical data for audit purposes.
* **Scope Products to compliance boundaries.** Products with different regulatory requirements should be separate so that policies can be tailored independently.
* **Enable vulnerability scanning and SBOM checks by default** in Environment Settings — these are core value-add features.
* **Enable "Retain Vulnerability Status with Version"** to avoid re-triaging vulnerabilities when SBOMs are re-uploaded.
* **Test automation rules in development** before enabling them in production Environments.
* **Configure notifications early.** Subscribe to vulnerability and policy alerts in production Environments to catch issues promptly.
* **Review the Change Log regularly** to audit automated and manual modifications to SBOMs.


# 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.
* **Files** — file-level artifacts imported from the SBOM, with their own license and attribution data. See [Files](/product-guides/sbom-management/files).
* **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
              ├── Files (file-level artifacts)
              ├── 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

### Detail Page Layout

The Version detail page opens on a compact header band that summarizes the SBOM before you drill into any tab. It carries the Version's identity and lifecycle stage, a strip of stats (freshness, pipeline, component and vulnerability totals, policy and compliance scores), and, when the Version has Parts, an expandable **N Parts** row with one row per Part.

Inside the tabs, the summary cards above a table (vulnerability remediation, support status, SBOM Doctor coverage) sit in a collapsible **Insights** panel. Collapse it to put the table itself at the top of the page. The choice is remembered per panel and persists across visits and across SBOMs, so it does not have to be repeated on every tab switch.

### 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.

The version selector badge shows the lifecycle stage date alongside the stage, so you can see when a Version entered its current lifecycle phase without opening the details.

### 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 %}

### Visualizing Part Relationships

The **View Relations** button on the Parts tab opens an interactive tree drawer showing the full composition graph — the current SBOM, its parts, any parent SBOMs that include this version as a part, and their transitive relationships.

**To open the tree:**

1. Navigate to the Product, select a Version, and click the **Parts** tab.
2. Click **View Relations**.

The drawer opens full-screen with the current SBOM highlighted as the root node.

**Navigation controls:**

| Control            | Action                                        |
| ------------------ | --------------------------------------------- |
| Click and drag     | Pan the tree                                  |
| Scroll             | Zoom in and out                               |
| Click a node       | Expand or collapse its children               |
| Search box         | Highlight matching nodes by name              |
| Orientation toggle | Switch between horizontal and vertical layout |
| Zoom buttons       | Fine-grained zoom control                     |

Each node shows the product name, version, and a badge with the number of direct children. The current SBOM is marked with a **Current** label in green. Clicking a child node lazily loads its sub-parts from the server.

***

## 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](/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 and pick what to export:

   | Menu item                | Output                                                               |
   | ------------------------ | -------------------------------------------------------------------- |
   | **SBOM**                 | CycloneDX, SPDX, or SPDX-Lite. SPDX exports default to 3.0.1         |
   | **VEX**                  | VEX statements on their own, in CycloneDX (1.7) or SPDX (3.0.1) JSON |
   | **PDF**                  | Version details as a PDF report                                      |
   | **Excel**                | Version details as a spreadsheet                                     |
   | **CSV (Support Levels)** | Component support levels as CSV                                      |
   | **Original**             | The unmodified SBOM as uploaded, if available                        |
3. For an SBOM download, select an **Export Profile**:

   | Profile                        | Output                                                                                                                                                                                        |
   | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **Interlynk Profile**          | The default. All specifications and content options below are available.                                                                                                                      |
   | **NTIA Minimum Elements 2021** | Pruned to the NTIA minimum elements. Parts, file artifacts, vulnerability data, and support status are excluded.                                                                              |
   | **BSI TR-03183-2 v2.1.0**      | CycloneDX 1.7 or SPDX 3.0.1, with file artifacts and parts included and declared and concluded licenses kept distinguishable. Vulnerability data, support status, and redaction are excluded. |

   The two framework profiles fix the content options rather than letting you set them, and SPDX-Lite is not offered under either. See [Compliance: Export Profiles](/administration/compliance#export-profiles).
4. Select the specification and format.
5. Under the Interlynk Profile, select content options:
   * **Parts** — include components and vulnerabilities from Parts.
   * **Vulnerabilities** — include vulnerability details (CycloneDX only).
   * **Vulnerability Status** — include VEX data (CycloneDX only).
   * **File Artifacts** — include file-level artifacts and their relationships (CycloneDX only). See [Files](/product-guides/sbom-management/files).
   * **Base64 Unencoded** — make encoded content readable.
6. Click **Download**.

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

The **VEX** option exports dispositions as a standalone document, without the component inventory. See [Exporting VEX Documents](/product-guides/security-and-compliance/vulnerabilities#exporting-vex-documents).

### 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.

**What recipients see.** For each vulnerability on a shared SBOM, recipients see the version that fixes it, where a fixed version is known, alongside the vulnerability itself. They can tell whether an upgrade path exists rather than only that a vulnerability was reported.

***

## 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:

* Correcting the underlying data in the check drawer and rescanning (see Fixing a Failed Check below).
* Editing the SBOM metadata or components manually.
* Creating Automation Rules from check results (click **Fix** > **Save as Rule**). See [Creating Rules from Checks](/product-guides/sbom-management/products#creating-rules-from-checks).

### Fixing a Failed Check

Selected checks carry an in-app fix flow, so a failing check can be corrected and re-evaluated without leaving the Checks tab.

1. Click the **Fix** icon under Resolution on the failing check. The drawer opens in an editable state with the fields the check evaluates.
2. Correct the values. Validation errors are reported against the individual field rather than as a single message on the drawer.
3. Click **Save**. The check is only treated as changed once the server accepts the save.
4. Click **Run** to re-evaluate that check against the corrected data.

Checks that do not support inline fixing open in a read-only **View** state, which shows what the check evaluated but offers no **Save** action. Resolve those by editing the SBOM data directly or by creating an Automation Rule.

The checks that support the inline fix flow cover:

| Area                     | Checks                                                        |
| ------------------------ | ------------------------------------------------------------- |
| BSI component properties | The five BSI component property checks                        |
| Checksums                | Both checksum checks                                          |
| External references      | The three external URL checks                                 |
| Component fields         | Copyright and component name, edited on a shared field editor |
| Document metadata        | Document creation tools                                       |
| Licensing                | Declared license                                              |

{% hint style="info" %}
**Run** re-evaluates only the check whose drawer is open. To re-evaluate the whole SBOM, reprocess the Version.
{% endhint %}

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](/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.


# Packages

The Packages view provides an organization-wide perspective on components across all Products and Versions. While the Components tab on a Version shows components within a single SBOM, the Packages view aggregates component data across your entire portfolio — enabling cross-product analysis, version tracking, and centralized override management.

***

## Overview

Packages consolidate component data from all SBOMs in your organization. Each package record represents a unique component (identified by name and ecosystem) and tracks all versions of that component encountered across your Products.

Key capabilities:

* **Cross-product visibility** — see which Products use a specific package and version.
* **Version tracking** — identify outdated versions and track upgrade progress across the portfolio.
* **Support overrides** — set organization-wide support level overrides for specific packages.
* **Enrichment data** — view package health scores, OpenSSF Scorecard results, and ecosystem insights.
* **Vulnerability correlation** — identify packages with known vulnerabilities across all Products.

## Architecture

```
Organization Package Registry
  └── Package (unique by name + ecosystem)
        ├── Versions Tab
        │     ├── All encountered versions across Products
        │     ├── Products using each version
        │     └── Vulnerability count per version
        ├── Overrides Tab
        │     ├── Support level overrides
        │     └── Custom metadata
        └── Enrichment Data
              ├── OpenSSF Scorecard
              ├── Health Score (Age, Community, Security)
              ├── Package Insights (deprecation, archive, downloads)
              ├── Version Insights (outdated, latest available)
              └── Source Code Insights (repo activity, contributors)
```

***

## Viewing Packages

### Package List

1. Navigate to the **Packages** page in the main navigation (or access via a component link from a Version).
2. The package list displays:

| Column            | Description                                                                            |
| ----------------- | -------------------------------------------------------------------------------------- |
| **Name**          | Package name                                                                           |
| **Ecosystem**     | Package ecosystem (npm, PyPI, Maven, Go, etc.)                                         |
| **PURL**          | Package URL identifier                                                                 |
| **Versions**      | Number of distinct versions encountered                                                |
| **Products**      | Number of Products using this package                                                  |
| **Health Score**  | Aggregated health score (0–100)                                                        |
| **Support Level** | Maintenance status (Actively Maintained, No Longer Maintained, Abandoned, Unspecified) |

### Filtering and Search

* **Search** by package name to find specific components.
* **Filter** by ecosystem, support level, or health score range.
* **Sort** by any column to prioritize review.

***

## Package Detail View

Click on a package to open its detail view, which includes two tabs:

### Versions Tab

The Versions tab shows all encountered versions of the package across your organization:

| Column              | Description                                      |
| ------------------- | ------------------------------------------------ |
| **Version**         | Component version string                         |
| **Products**        | Products using this version (with links)         |
| **Environments**    | Environments where this version is present       |
| **Vulnerabilities** | Number of known vulnerabilities for this version |
| **First Seen**      | When this version was first encountered          |
| **Last Seen**       | Most recent SBOM upload containing this version  |

Use this view to:

* Identify which Products are running outdated versions.
* Track upgrade progress across the organization.
* Find Products affected by a vulnerable version.

### Overrides Tab

The Overrides tab allows setting organization-wide overrides for the package:

| Override                | Description                                     |
| ----------------------- | ----------------------------------------------- |
| **Support Level**       | Override the automated support level assessment |
| **End-of-Support Date** | Set a custom end-of-support date                |
| **End-of-Life Date**    | Set a custom end-of-life date                   |

Overrides apply to all instances of the package across all Products and persist across SBOM re-uploads.

***

## Component Enrichment

Packages are enriched with data from open-source ecosystems:

### OpenSSF Scorecard

The [OpenSSF Scorecard](https://securityscorecards.dev/) evaluates the security posture of open-source projects. Scorecard results include checks for:

* Branch protection policies
* Dependency update tooling
* Signed releases
* Vulnerability disclosure process
* Code review practices

### Health Score

The health score (0–100) aggregates three weighted factors:

| Factor        | What It Measures                                                            |
| ------------- | --------------------------------------------------------------------------- |
| **Age**       | How recently the package was updated, whether it shows signs of abandonment |
| **Community** | Number of active contributors                                               |
| **Security**  | OpenSSF Scorecard results, vulnerability history, support status            |

For health score customization, see [Administration: Health Scoring](/administration/health-scoring).

### Package Insights

| Insight                | Description                                       |
| ---------------------- | ------------------------------------------------- |
| **Deprecation status** | Whether the package is deprecated in its registry |
| **Archive status**     | Whether the repository is archived                |
| **Download counts**    | Popularity indicator from the package registry    |

### Version Insights

| Insight            | Description                                                  |
| ------------------ | ------------------------------------------------------------ |
| **Outdated**       | Whether the installed version is behind the latest available |
| **Latest version** | The most recent version available in the registry            |

### Source Code Insights

| Insight                 | Description                               |
| ----------------------- | ----------------------------------------- |
| **Repository activity** | Commit frequency and recency              |
| **Contributor metrics** | Number and activity level of contributors |

***

## Cross-Product Analysis

The Packages view enables several cross-product analysis patterns:

### Finding All Users of a Vulnerable Package

1. Navigate to the **Packages** page.
2. Search for the affected package (e.g., `log4j`).
3. Click on the package to open the detail view.
4. On the **Versions** tab, identify the vulnerable version(s).
5. The **Products** column shows all affected Products.

### Tracking Upgrade Progress

1. Open the package detail view.
2. Compare the **Versions** tab entries against the latest available version.
3. Products still using older versions need upgrades.

### Identifying Abandoned Dependencies

1. Filter the package list by **Support Level: Abandoned**.
2. For each abandoned package, review the Products using it.
3. Plan migration to maintained alternatives.

***

## Permission Matrix

| Permission                            | Admin | Operator | Viewer |
| ------------------------------------- | :---: | :------: | :----: |
| View products (includes package data) |   ✓   |     ✓    |    ✓   |
| View SBOMs (includes component data)  |   ✓   |     ✓    |    ✓   |
| Edit SBOM components                  |   ✓   |     ✓    |    —   |
| Edit support                          |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**A single vulnerable package can affect multiple Products.** Use the Packages view to identify the full blast radius of a vulnerability across your organization. Do not assume a CVE only affects the Product where it was first discovered.
{% endhint %}

{% hint style="warning" %}
**Packages without PURL identifiers cannot be correlated across Products.** Each SBOM will show them as separate, unrelated components. Ensure SBOM tooling produces consistent PURL identifiers for accurate cross-product analysis.
{% endhint %}

***

## Common Misconfigurations

| Issue                                    | Symptom                             | Fix                                                                                         |
| ---------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------- |
| Same package appears as multiple entries | Inconsistent naming across SBOMs    | Standardize SBOM generation tooling to produce consistent PURL identifiers                  |
| Support overrides not applying           | Automated support level still shown | Verify the override was applied to the correct package identifier                           |
| Health score missing                     | No score displayed for package      | Verify the package has a PURL identifier; packages without PURL cannot be enriched          |
| Outdated version insights missing        | No "latest version" data            | Package may not be in a supported registry, or registry data may be temporarily unavailable |
| Cross-product search too slow            | Large result sets                   | Use specific package names rather than broad searches; filter by ecosystem                  |

***

## Recommended Best Practices

* **Review the Packages view regularly** for abandoned and deprecated components across your organization.
* **Use cross-product analysis** when a critical CVE is published to quickly identify all affected Products.
* **Track upgrade progress** by monitoring how many Products are running the latest version of critical dependencies.
* **Apply support overrides** when you have internal knowledge about a component's maintenance status that differs from the automated assessment.
* **Prioritize packages by blast radius.** A vulnerable package used by 20 Products is more urgent than one used by a single Product.
* **Ensure consistent PURL identifiers** across all SBOM generation tools to enable accurate cross-product correlation.
* **Use health scores for portfolio-level risk assessment.** Sort by health score to identify the riskiest packages in your supply chain.
* **Set up policies** that target packages with low health scores or abandoned support levels to enforce supply chain standards.


# Files

The Files view tracks file-level records from an SBOM separately from its components. When an SBOM declares individual files — source files, scripts, binaries — Interlynk imports them as dedicated file artifacts rather than mixing them into the component dependency tree.

***

## Overview

A file artifact represents a single file declared in an SBOM document. Files are stored apart from components, so the Components tab stays focused on packages and dependencies while file-level detail lives on its own Files tab.

File artifacts are imported from:

* **SPDX** — entries in the SBOM's `files` array (SPDX 2.x).
* **CycloneDX** — components with `type: "file"`.

Each file record carries its own name, version, checksums, license expressions, copyright, notice text, external references, and properties. Files can be annotated and linked back to the components they belong to.

{% hint style="info" %}
SPDX packages are not treated as files even when their primary package purpose is `SOURCE`, `ARCHIVE`, `FILE`, or `INSTALL`. Only explicit SPDX file entries and CycloneDX `file` components become file artifacts. Packages remain components so they continue to participate in vulnerability scanning and policy evaluation.
{% endhint %}

***

## Files vs. Components

|                            | Components                                   | Files                                        |
| -------------------------- | -------------------------------------------- | -------------------------------------------- |
| **Represents**             | Packages and dependencies                    | Individual file-level entries                |
| **Source**                 | SPDX packages, CycloneDX non-file components | SPDX `files` array, CycloneDX `type: "file"` |
| **Vulnerability scanning** | Yes                                          | No                                           |
| **Policy evaluation**      | Yes                                          | No                                           |
| **Health and metrics**     | Yes                                          | No                                           |
| **View**                   | Components tab                               | Files tab                                    |

File artifacts are excluded from component workflows — they are not scanned for vulnerabilities, evaluated against policies, or counted in component metrics. They serve as a license and attribution record at the file level.

***

## Files Tab

The Files tab appears on the SBOM detail view alongside General, Components, Vulnerabilities, and Licenses.

### Viewing Files

1. Open a Product and navigate to a Version.
2. Click the **Files** tab on the SBOM detail page.
3. The table lists one row per file artifact.

| Column                | Description                           |
| --------------------- | ------------------------------------- |
| **Name**              | File name                             |
| **Declared License**  | License as declared in the SBOM       |
| **Concluded License** | Concluded license expression          |
| **Copyright**         | Copyright text                        |
| **Updated**           | When the file record was last updated |

### Filtering

| Filter            | Description                                       |
| ----------------- | ------------------------------------------------- |
| **Search**        | Filter by file name                               |
| **License**       | Filter files by license expression                |
| **Include Parts** | Include file artifacts from referenced Part SBOMs |

When **Include Parts** is enabled, the table also shows files contributed by the Version's Parts, with a Parts filter to narrow to specific Parts.

### Editing Files

Each file row offers the following actions:

| Action                     | Description                                                                                            |
| -------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Edit File**              | Edit the file's license expressions, copyright, notice, external references, checksums, and properties |
| **Edit Notes**             | Add or update annotations on the file                                                                  |
| **Apply File Attribution** | Copy license, copyright, and notice information from the file to a linked component                    |

***

## File Attribution

A file artifact can be linked to a component as its source — a `source_for` relationship. This records that a given file is the source for a component, which is useful when a component's license or copyright is best evidenced at the file level.

**Apply File Attribution** copies attribution fields from a file to the component it is the source for:

* Declared license expression
* Concluded license expression
* Copyright
* Notice

Use this when a component lacks license or copyright metadata but the originating file carries it.

***

## Including Files in Exports

By default, CycloneDX exports contain only package components. To include file artifacts in the exported document:

1. Open the SBOM download dialog.
2. Set the format to **CycloneDX**.
3. Enable the **File Artifacts** option.
4. Download.

When enabled, the export adds each file artifact as a CycloneDX `file` component and includes the file-level dependency relationships imported from the original CycloneDX SBOM. The option is available for CycloneDX exports only (not SPDX or PDF).

### Exporting the Files Table as CSV

To export the file artifacts themselves rather than embed them in an SBOM, use the CSV export on the Files tab. This downloads the Files table — file name, license, copyright, and related columns — as a CSV file for offline review or sharing.

***

## GraphQL API

File artifacts are exposed through the GraphQL API for automation:

* The `sbomFiles` connection on an SBOM returns its file artifacts, with search and license filtering and optional inclusion of Part files.
* `SbomFileType` exposes a file's name, version, checksums, declared and concluded license expressions, copyright, notice, external URLs, properties, annotations, and the components it is a source for.
* Mutations support editing a file's attribution fields, creating and removing `source_for` links between a file and a component, and adding annotations.

For API access details, see [API Key Management](/administration/api-key-management).

***

## Recommended Best Practices

* **Use file artifacts for file-level license evidence.** When component metadata is incomplete, link the originating file and apply its attribution.
* **Enable File Artifacts in CycloneDX exports** when downstream consumers need file-level detail, and leave it off for a lighter, package-only document.
* **Annotate files** with review notes to keep attribution decisions auditable.
* **Don't expect vulnerability data on files.** Vulnerability scanning runs against components; keep packages classified as components for accurate scanning.


# Requests

SBOM requests enable organizations to collect SBOMs from third-party vendors and suppliers. Interlynk provides a workflow for sending requests, receiving uploaded SBOMs, validating them, and integrating them into your Product inventory — all without requiring the vendor to have an Interlynk account.

***

## Overview

The SBOM request workflow addresses a common challenge: obtaining SBOMs from vendors and suppliers who may not use SBOM management tooling. Interlynk sends an email to the vendor contact with a secure upload link, validates the uploaded SBOM, and makes it available for review and acceptance into your Products.

Key capabilities:

* **No vendor account required** — vendors receive an email with a secure upload link.
* **Automatic link renewal** — upload links are valid for 24 hours but regenerate automatically if the vendor clicks an expired link.
* **SBOM validation** — uploaded SBOMs are validated for format and completeness.
* **Acceptance workflow** — review and accept vendor SBOMs into your Products and Environments.

## Architecture

```
SBOM Request Workflow

1. Requester creates request
   └── Email sent to vendor contact
         └── Secure upload link (valid 24 hours)

2. Vendor uploads SBOM
   └── Upload link → SBOM validation
         └── Status changes to "Uploaded"

3. Requester reviews and accepts
   └── Select target Product + Environment
         └── SBOM ingested into platform
               └── Standard processing pipeline applies
```

***

## Sending SBOM Requests

### Via Dashboard

1. Navigate to the **Requests** page in the main navigation.
2. Click **+** (Request SBOM).
3. Enter the request details:

| Field            | Required | Description                                                |
| ---------------- | -------- | ---------------------------------------------------------- |
| **Vendor Email** | Yes      | Email address of the contact who will supply the SBOM      |
| **Product Name** | No       | Name of the vendor product for which the SBOM is requested |
| **Version**      | No       | Specific version of the vendor product                     |

4. Click **Save** to send the request.

The vendor receives an email with a link to upload the SBOM. The vendor does not need an Interlynk account.

{% hint style="info" %}
The upload link is valid for 24 hours. If the vendor clicks the link after it expires, a new link is automatically generated and sent to the same email address.
{% endhint %}

***

## Request Statuses

| Status       | Description                                                       |
| ------------ | ----------------------------------------------------------------- |
| **Pending**  | Request has been sent; waiting for vendor to upload               |
| **Uploaded** | Vendor has uploaded an SBOM; awaiting review and acceptance       |
| **Accepted** | SBOM has been accepted and ingested into a Product                |
| **Expired**  | Request link has expired without an upload (auto-renews on click) |

***

## Accepting Vendor SBOMs

When a vendor uploads an SBOM, the request status changes to **Uploaded**. To accept and ingest the SBOM:

1. Navigate to the **Requests** page.
2. Locate the request with **Uploaded** status.
3. Click **Accept**.
4. Select the target **Product** and **Environment** to receive the SBOM.
5. Click **Accept** to complete.

The SBOM is ingested into the selected Product and Environment and goes through the standard processing pipeline (SBOM Checks, Automation Rules, Vulnerability Scan, Policy Evaluation).

{% hint style="warning" %}
Review the vendor SBOM before accepting. Once accepted, the SBOM is processed and integrated into your Product data. Ensure the content matches your expectations for the requested product and version.
{% endhint %}

***

## Managing Requests

### Viewing All Requests

1. Navigate to the **Requests** page.
2. The request list displays:

| Column           | Description                           |
| ---------------- | ------------------------------------- |
| **Vendor Email** | Email address the request was sent to |
| **Product**      | Requested product name (if specified) |
| **Version**      | Requested version (if specified)      |
| **Status**       | Current request status                |
| **Date**         | When the request was created          |

### Tracking Outstanding Requests

Filter the request list by **Pending** status to identify requests that have not yet been fulfilled. Follow up with vendors as needed.

***

## Permission Matrix

| Permission    | Admin | Operator | Viewer |
| ------------- | :---: | :------: | :----: |
| View requests |   ✓   |     ✓    |    ✓   |
| Edit requests |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Vendor-supplied SBOMs should be reviewed before acceptance.** A vendor may provide an incomplete, inaccurate, or outdated SBOM. Validate the content — check for complete component lists, proper identifiers, and correct version information — before accepting.
{% endhint %}

{% hint style="warning" %}
**Upload links are sent via email.** Ensure you are sending requests to verified vendor contacts. The upload link allows anyone with access to it to upload a file.
{% endhint %}

***

## Common Misconfigurations

| Issue                                        | Symptom                                         | Fix                                                                                              |
| -------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Vendor did not receive the email             | Request stays in "Pending" status               | Verify the email address is correct; check the vendor's spam folder                              |
| Upload link expired                          | Vendor reports link does not work               | The link auto-renews when clicked; ask the vendor to click the expired link to receive a new one |
| Wrong Product/Environment selected on accept | SBOM appears in unexpected location             | Delete the ingested SBOM and re-accept with the correct target                                   |
| Vendor uploaded incorrect file               | SBOM validation fails or content does not match | Contact the vendor and request a corrected SBOM upload                                           |
| No requests page visible                     | User cannot access the Requests page            | Verify the user has "View requests" permission                                                   |

***

## Recommended Best Practices

* **Include product name and version in requests.** This gives vendors clear context on what SBOM to provide and reduces back-and-forth.
* **Follow up on pending requests** within a reasonable timeframe. Some vendors may need guidance on SBOM generation.
* **Review vendor SBOMs before accepting.** Validate that the SBOM contains meaningful component data, proper identifiers (PURL/CPE), and matches the requested product.
* **Accept into a dedicated Environment.** Consider accepting vendor SBOMs into a "vendor" or "third-party" Environment for separate tracking and policy evaluation.
* **Run vulnerability scanning on accepted SBOMs.** Ensure "Run Vulnerability Scan" is enabled in the target Environment Settings so vendor components are scanned for known vulnerabilities.
* **Establish a regular cadence for vendor SBOM collection.** Request updated SBOMs from critical vendors on a quarterly or release-based schedule.
* **Track request fulfillment rates.** Monitor which vendors consistently provide SBOMs and which require follow-up, to improve your vendor management process.


# SBOM Doctor

SBOM Doctor runs a suite of quality checks against an SBOM's components and flags structural problems — malformed identifiers, version mismatches, missing licenses, and unresolvable PURLs — before they affect vulnerability correlation or compliance scoring.

***

## Overview

Doctor results appear on the **Doctor** tab of any uploaded SBOM's detail page, with filters, per-component findings, and project-scoped suppressions.

Results are cached for 30 minutes and recomputed when the SBOM changes. A **force-rescan** button bypasses the cache to recompute findings immediately. Authenticated users unlock a broader set of checks that require external registry lookups.

***

## Checks

Doctor runs checks across two domains:

* **Identifier checks** — validate CPE and PURL syntax, cross-consistency between identifiers, version alignment, whether a CPE is too broad to identify the component precisely, and whether components are missing identifiers entirely.
* **License checks** — validate SPDX expression syntax and whether components have a license declared.

Authenticated users unlock an additional set of checks that perform external lookups — verifying CPEs against the NVD dictionary, resolving PURLs against package registries, and confirming license IDs are recognized SPDX identifiers.

***

## Dashboard UI

Doctor results appear on the **Doctor** tab of any SBOM's detail view.

### Viewing Results

1. Open a Product and navigate to a Version.
2. Click the **Doctor** tab on the SBOM detail page.
3. The table shows one row per finding, with columns for the affected component, version, check code, severity, domain, and a human-readable summary.

CPE and PURL identifiers in findings are click-to-copy — click an identifier to copy it to the clipboard.

### Refreshing Results

Doctor caches results for 30 minutes. To recompute findings without waiting for the cache to expire, use the **force-rescan** button (next to **Export CSV**). This bypasses the cache and re-runs the checks immediately, which is useful after correcting identifiers or re-uploading an SBOM.

### Filtering

Use the sub-header controls to narrow findings:

| Filter         | Options                               |
| -------------- | ------------------------------------- |
| **Search**     | Filter by component name              |
| **Domain**     | `identifier`, `license`               |
| **Severity**   | `critical`, `high`, `medium`, `low`   |
| **Check Code** | Filter to one or more specific checks |

Click a row to open the component drawer for full component detail and editing.

### Stats Badge

The Doctor tab label shows a badge with the count of `critical` and `high` findings for quick triage without opening the tab.

### Exporting Results

Use the **Export CSV** action in the Doctor tab's menu (next to **Refresh**) to download the findings table as a CSV file for offline review or sharing. The export dialog includes an **Apply search and filters** option (on by default) — leave it on to export only the currently filtered findings, or turn it off to export the full diagnostics table. Click **Download** to save the file.

## Suppressions

Suppress specific checks per project to avoid noise from checks that don't apply to your context — for example, suppressing `IDT-MISSING-001` for a project that intentionally ships internal-only components without PURLs.

### Configuring Suppressions

1. Navigate to the Product page.
2. Open **Settings** and select the **Doctor Checks** section.
3. Toggle any check off to suppress it for all SBOMs in this project.

Suppressed checks do not generate findings and are excluded from stats. The toggle is on by default (suppressed = off). Suppression changes are audit-logged.

### Permission

Suppression configuration requires the `edit_product_settings` permission within `view_product_group`.

***

## Common Findings and Fixes

| Finding        | What it means                                                                                              |
| -------------- | ---------------------------------------------------------------------------------------------------------- |
| `IDT-CPE-001`  | CPE is not in valid CPE 2.3 format — regenerate from your SBOM tool or correct the string                  |
| `IDT-CPE-003`  | CPE is too broad (e.g., wildcarded fields) and would match unintended components — use a more specific CPE |
| `IDT-PURL-001` | PURL is malformed — regenerate from your build tool                                                        |

For help interpreting other findings, contact <support@interlynk.io>.


# TLP Classification

Traffic Light Protocol (TLP) is a standardized labeling scheme for controlling information sharing. Applying a TLP classification to an SBOM communicates its distribution constraints to recipients — from unrestricted public sharing to strictly private.

***

## TLP Levels

| Level            | Color      | Distribution Rule                                                                 |
| ---------------- | ---------- | --------------------------------------------------------------------------------- |
| **CLEAR**        | White/Blue | Disclosure is not limited. Can be shared publicly.                                |
| **GREEN**        | Green      | Restricted to the community. Can be shared within the community but not publicly. |
| **AMBER**        | Yellow     | Restricted to the organization and its clients on a need-to-know basis.           |
| **AMBER+STRICT** | Orange     | Restricted to the organization only. Cannot be shared with clients.               |
| **RED**          | Red        | Not for disclosure. Restricted to named participants only.                        |

For the full TLP specification, see [FIRST.org TLP](https://www.first.org/tlp/).

***

## How Classification Cascades

TLP classification resolves through a three-level hierarchy:

```
Organization Default
       ↓ (inherited unless overridden)
  Project Setting
       ↓ (inherited unless overridden)
   SBOM (Version)      ← effective classification
```

An SBOM-level classification takes precedence over the project setting, which in turn takes precedence over the organization default. If none is set, no TLP label is applied.

This means you can:

* Set a default across all new projects at the organization level.
* Override for a specific product in its project settings.
* Override for a specific SBOM version on the SBOM detail page.

***

## Setting TLP Classification

### On an Individual SBOM

1. Navigate to the Product, select the Environment, and open a Version.
2. Click the **Details** tab.
3. Find the **TLP Classification** field.
4. Click **Add Classification** (or the edit icon if one is already set).
5. Select a TLP level from the dropdown.
6. Click **Save**.

To remove a classification, click the trash icon next to the current label.

### At the Project Level

Set a default for all SBOMs within a project environment:

1. Navigate to the Product and select an Environment.
2. Click the **Settings** tab.
3. Find the **TLP Classification** setting.
4. Select a level.
5. Changes apply to new SBOMs. Existing SBOMs that have an explicit classification are not affected.

### At the Organization Level

Set an organization-wide default inherited by all new projects:

1. Navigate to **Settings > Organization > Environments > Defaults**.
2. Find the **TLP Classification** field.
3. Select a level.
4. Click **Save**.

New projects inherit this default. Existing project settings are not retroactively changed unless you use the **Apply to All Projects** option.

***

## TLP and SBOM Downloads

When downloading an SBOM, the TLP classification can be overridden at download time using the `tlpClassificationOverride` argument. This is useful when sharing SBOMs with different audiences — for example, generating a CLEAR version for public disclosure while keeping the stored copy as AMBER.

```bash
# Download with a TLP override (via GraphQL)
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { sbomDownload(id: \"<sbom-id>\", tlpClassificationOverride: \"CLEAR\") { downloadUrl errors } }"
  }'
```

Reclassifying an SBOM is a publisher decision. ShareLynk recipients downloading through a share link cannot set an override, so a TLP:RED SBOM cannot be re-downloaded stamped CLEAR by the party it was shared with.

***

## Common Questions

**Does TLP affect vulnerability scanning or policy evaluation?** No. TLP is a metadata label for distribution control. It does not change how the platform scans vulnerabilities, evaluates policies, or scores compliance.

**Can I set TLP on archived SBOMs?** Yes. The classification can be edited on any SBOM regardless of lifecycle state.

**Is TLP visible in the ShareLynk view?** The effective TLP classification is visible to ShareLynk recipients so they understand the distribution constraints of the SBOM they are viewing.


# Security & Compliance


# Vulnerabilities

Vulnerability management is the process of identifying, triaging, and remediating known security issues in your software supply chain. Interlynk maps vulnerabilities to components in your SBOMs using package identifiers (PURL, CPE), enriches them with exploitability data (EPSS, KEV), and provides VEX-based disposition tracking to document your organization's response.

***

## Overview

When an SBOM is uploaded and vulnerability scanning is enabled, the platform automatically:

1. Extracts identifiers (PURL, CPE) from each component.
2. Queries multiple vulnerability databases for known issues.
3. Checks whether the component's version falls within affected version ranges.
4. Creates vulnerability records linking components to CVEs.
5. Enriches records with EPSS scores, KEV status, and CWE classifications.

Vulnerability data is scoped per Product, Environment, and Version. Each vulnerability record tracks its VEX status, justification, custom field values, and remediation history.

## Architecture

```
SBOM Upload
  └── Component Extraction
        └── Identifier Matching (PURL / CPE)
              └── Vulnerability Database Lookup
                    ├── NVD (National Vulnerability Database)
                    ├── GitHub Security Advisories
                    ├── OSV (Open Source Vulnerabilities)
                    └── Ecosystem-specific databases
                          └── Affected Version Range Check
                                └── Vulnerability Record
                                      ├── CVSS Score + Vector
                                      ├── EPSS Score + Percentile
                                      ├── KEV Status
                                      ├── CWE Classification
                                      ├── VEX Status + Justification
                                      └── Custom Fields
```

**Interactions:**

* **Policies** — trigger on vulnerability severity, EPSS score, KEV status, VEX status, and custom fields.
* **Automation Rules** — auto-assign VEX status or trigger actions based on vulnerability attributes.
* **Ticketing** — Jira and Linear tickets can be created from vulnerability details.
* **Notifications** — Slack, Teams, and email alerts for new or changed vulnerabilities.
* **Health Scoring** — open vulnerabilities reduce component and Product health scores.
* **Compliance** — VEX disposition status affects compliance evaluations (NTIA, FDA, CRA).

***

## Viewing Vulnerabilities

### Product-Level View

1. Navigate to the **Products** page and select a Product.
2. Select an Environment and Version.
3. Click the **Vulnerabilities** tab.

The vulnerability list displays:

| Column         | Description                                                                                        |
| -------------- | -------------------------------------------------------------------------------------------------- |
| **CVE ID**     | Vulnerability identifier (e.g., CVE-2024-1234)                                                     |
| **Component**  | Affected component name and version                                                                |
| **Severity**   | Critical, High, Medium, Low                                                                        |
| **CVSS**       | Base CVSS score (0.0–10.0)                                                                         |
| **EPSS**       | Exploit prediction probability (0.0–1.0)                                                           |
| **KEV**        | Whether the vulnerability is in a known exploited vulnerabilities catalog (CISA KEV or ENISA EUVD) |
| **VEX Status** | Current disposition (Affected, Not Affected, Under Investigation, Fixed)                           |

For CPE-matched vulnerabilities, the detail view also shows the **fixed version** and **last-affected version** when available. When the last-affected version is empty, the vulnerability is shown as "Affected before \<fix>".

{% hint style="info" %}
Vulnerability scan status updates live. As a scan runs, counts in the versions table and the SBOM vulnerabilities view refresh in place — no manual reload is needed. Vulnerability stat badges are not clickable while a scan is in progress.
{% endhint %}

### Organization-Level View

The **Vulnerabilities** page in the main navigation provides a cross-product view of all vulnerabilities across the organization, with filtering by severity, VEX status, KEV inclusion, EPSS range, retracted status, and product. Component vulnerabilities can also be filtered by label.

**Retracted filter:** Retracted vulnerabilities can be filtered out of component and SBOM vulnerability lists so withdrawn advisories don't clutter triage.

**EPSS range filter:** Set a minimum and maximum EPSS value using the custom range control to isolate vulnerabilities at a specific exploitation probability. For example, set `0.5–1.0` to see only high-exploitation-probability issues.

**Dashboard impact badges:** The severity badges in the dashboard's vulnerability impact summary are clickable. Clicking a badge (Critical, High, Medium, or Low) opens the product vulnerability list pre-filtered to that severity.

***

## Severity and Scoring

### CVSS (Common Vulnerability Scoring System)

| Severity     | Score Range |
| ------------ | ----------- |
| **Critical** | 9.0–10.0    |
| **High**     | 7.0–8.9     |
| **Medium**   | 4.0–6.9     |
| **Low**      | 0.1–3.9     |

Each vulnerability includes a CVSS v3.1 base score and vector string (e.g., `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`).

### EPSS (Exploit Prediction Scoring System)

EPSS provides a probability (0–1) that a vulnerability will be exploited in the wild within 30 days. The percentile ranks the vulnerability relative to all scored CVEs.

| EPSS Range | Interpretation                                              |
| ---------- | ----------------------------------------------------------- |
| > 0.5      | Very high exploitation probability — prioritize immediately |
| 0.1–0.5    | High exploitation probability — investigate promptly        |
| 0.01–0.1   | Moderate exploitation probability                           |
| < 0.01     | Low exploitation probability                                |

### KEV (Known Exploited Vulnerabilities)

A known exploited vulnerability is one confirmed to be actively exploited in the wild. KEV-listed vulnerabilities should be remediated with the highest priority regardless of CVSS score.

The KEV flag draws on two feeds:

| Feed           | Source                                                                                        |
| -------------- | --------------------------------------------------------------------------------------------- |
| **CISA KEV**   | U.S. Cybersecurity and Infrastructure Security Agency Known Exploited Vulnerabilities catalog |
| **ENISA EUVD** | European Union Agency for Cybersecurity, EU Vulnerability Database known-exploited entries    |

A vulnerability is flagged as KEV if it appears in either feed, so the two catalogs are unioned rather than treated separately. The KEV filter and the KEV policy subject both operate on this combined flag.

{% hint style="info" %}
If one feed is temporarily unavailable, entries from the other are still applied. A feed outage narrows KEV coverage for that refresh but does not drop the entries the other feed supplied.
{% endhint %}

### CWE (Common Weakness Enumeration)

CWE classifies the root cause of a vulnerability (e.g., CWE-79: Cross-site Scripting, CWE-89: SQL Injection). This helps identify patterns in vulnerability types across your portfolio.

### Custom Scoring Adjustments

Administrators can adjust vulnerability scoring per component:

* **Adjusted CVSS Score** — override the base CVSS score based on organizational context.
* **Temporal Vector** — apply temporal metrics (exploit maturity, remediation level).
* **Environmental Vector** — apply environmental metrics specific to your deployment context.

### Editing CVSS Scores

CVSS scores can be edited directly from the vulnerability view for any organization:

1. Navigate to the vulnerability detail view.
2. Click the **Edit** action on the CVSS score field (available in the expanded vulnerability row or detail panel).
3. Enter the adjusted score and optionally provide a CVSS vector string.
4. Save.

The adjusted score is used by policy rules, compliance calculations, and all downstream reporting. The original base score is preserved and visible alongside the adjusted value.

For custom field configuration, see [Administration: Vulnerability Custom Fields](/administration/vulnerability-custom-fields).

***

## VEX Status (Vulnerability Disposition)

The [Vulnerability Exploitability eXchange (VEX)](https://www.cisa.gov/resources-tools/resources/minimum-requirements-vulnerability-exploitability-exchange-vex) standard defines how to declare the exploitability status of a vulnerability in your specific context.

### Status Values

| Status                  | Description                                        | When to Use                                                                            |
| ----------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------- |
| **Affected**            | The vulnerability applies and requires remediation | Component is in use, vulnerable code is reachable, no mitigations exist                |
| **Not Affected**        | The vulnerability does not apply                   | Component is present but the vulnerability is not exploitable (justification required) |
| **Under Investigation** | Applicability is being assessed                    | Newly discovered vulnerability, awaiting analysis                                      |
| **Fixed**               | The vulnerability has been remediated              | Component updated, patch applied, or workaround implemented                            |

### Not Affected Justifications

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

| Justification                                         | Description                                                                         |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **Component Not Present**                             | The vulnerable component is not actually present in the deployed build              |
| **Vulnerable Code Not Present**                       | The specific vulnerable code path is not included                                   |
| **Vulnerable Code Not in Execute Path**               | The vulnerable code exists but cannot be reached at runtime                         |
| **Vulnerable Code Cannot Be Controlled by Adversary** | The vulnerable code is present and reachable but cannot be exploited by an attacker |
| **Inline Mitigations Already Exist**                  | Compensating controls prevent exploitation                                          |

{% hint style="warning" %}
All "Not Affected" dispositions must include a justification. This is required for VEX compliance and provides audit evidence for compliance frameworks.
{% endhint %}

***

## Managing Vulnerability Status

### Setting Status for a Single Vulnerability

1. Navigate to the Version's **Vulnerabilities** tab.
2. Click on a vulnerability to open its detail view.
3. Select the VEX status from the dropdown.
4. If **Not Affected**, select the justification.
5. Optionally add a response description.
6. Save.

### Acting on Several Vulnerabilities at Once

Select vulnerabilities in the list using the row checkboxes. A bulk action bar floats above the table while a selection is active, showing how many rows are selected and the actions available for them. Each action is labeled, so you can tell what a bulk action will do before applying it.

Clearing the selection dismisses the bar. Filtering the list also clears the selection, so a bulk action never applies to rows that have scrolled out of the current filter.

### Importing Status from Previous Versions

When "Copy VEX Across Versions on Import" is enabled in Environment Settings, VEX dispositions from previous Versions carry forward automatically to new uploads. This eliminates re-triaging the same vulnerabilities.

#### Recovering VEX for the Same Version

When an automatic same-version VEX copy was incomplete, use **Copy VEX from this version** to recover the VEX data on demand. A review notification confirms when the copy completes.

### Setting Status Across Multiple Versions

Apply a disposition to the same vulnerability across all Versions of a Product:

1. Open the vulnerability detail view.
2. Select **Apply to All Versions**.
3. Confirm the action.

### Setting Status Across Multiple Products

Apply a disposition organization-wide for a specific CVE:

1. Navigate to the organization-level Vulnerabilities page.
2. Select the vulnerability.
3. Apply the VEX status across all affected Products.

### Custom Vulnerabilities

In addition to automatically discovered vulnerabilities, you can create custom vulnerability records:

1. Navigate to the Version's **Vulnerabilities** tab.
2. Click **Add Custom Vulnerability**.
3. Enter the vulnerability details (ID, description, severity, affected component).
4. Save.

Custom vulnerabilities are useful for tracking internally discovered issues or vulnerabilities not yet published in public databases.

***

## Importing Third-Party VEX Documents

When a supplier or upstream project provides a VEX document, the **VEX Import Wizard** bulk-applies its statements to the matching components in your SBOM, so you do not have to re-triage vulnerabilities the supplier has already assessed.

### Supported Formats

VEX documents in **JSON** or **XML**, up to 10 MB, in any of four formats:

| Format        | Notes                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------- |
| **CycloneDX** | VEX-only documents, or combined BOM/VDR documents with embedded `vulnerabilities[].analysis` |
| **OpenVEX**   | JSON                                                                                         |
| **CSAF**      | JSON                                                                                         |
| **SPDX 3.0**  | Standalone VEX documents                                                                     |

### Running an Import

The wizard has four steps: **Upload → Select Products → Review → Result**.

1. Navigate to the Version's **Vulnerabilities** tab.
2. From **Import Statuses**, choose **Import VEX**.
3. **Upload** — drop or select the VEX document. The wizard analyzes it and shows a preview summary (document format, spec version, timestamp, statement count, product, supplier, authors, tools) before you continue. If the document's scope does not match this SBOM, the preview flags it. Click **Next**.
4. **Select Products** — a VEX document can carry statements about several products. Pick the affected products whose statements should be applied to this SBOM; the step shows a statement count per product and a running total for your selection. When the document names one affected product or none at all, the wizard skips this step and imports the whole document.
5. **Review** — statements are grouped by how they matched the SBOM's components, into **Matched**, **Conflicts**, **Ambiguous**, and **Unmatched** tabs, each with a count. Select the entries you want to apply, then click **Apply VEX**.
6. **Result** — a summary shows how many dispositions were **Applied**, **Skipped**, and (if any) **Errors**. Click **Done**.

### Resolving Conflicts

A statement lands in the **Conflicts** tab when the vulnerability already carries a disposition in Interlynk and the imported statement proposes a different status. Nothing is overwritten silently.

Each conflict row shows the existing status and the proposed status side by side. Selecting the row marks it **Overwrite**; leaving it unselected marks it **Keep existing**, which skips the statement and preserves your triage.

Statements that merely restate the existing status are not treated as conflicts.

{% hint style="info" %}
The Environment setting **Overwrite Existing VEX Dispositions** decides how conflicts arrive in the Review step. With it off (the default), conflicting entries start unselected, so you opt each one in. With it on, they start selected to overwrite. Either way you can change any row before applying. See [Product Settings](/product-guides/sbom-management/products#product-settings).
{% endhint %}

### How Statements Are Matched

The importer maps each VEX statement onto components using, in order:

| Strategy             | Basis                                                               |
| -------------------- | ------------------------------------------------------------------- |
| **SPDX IRI**         | SPDX 3.0 element IRI matched against the target SBOM's own elements |
| **Identity**         | PURL, CPE, or component name and version                            |
| **BOM-Link**         | CycloneDX `bom-ref` resolved against the target SBOM                |
| **Vulnerability ID** | Fallback when the statement carries no usable component reference   |

If a statement has a missing or blank affects reference, it falls through to vulnerability-ID matching rather than failing the whole import. A vulnerability ID that matches more than one component is reported as **Ambiguous**, and you pick the intended component in the Review step.

### Import History

Each import is recorded in the **VEX Import History** drawer for the SBOM, with per-status counts (applied, skipped, error) so you can audit what a given document changed.

***

## Exporting VEX Documents

To share your dispositions without shipping the full SBOM, export VEX on its own.

1. Navigate to the Version and click the **Download** button.
2. Choose **VEX**.
3. Select a specification: **CycloneDX** (1.7) or **SPDX** (3.0.1).
4. Click **Download**. The file is written as JSON, named `<product>-<version>-vex.cdx.json` or `<product>-<version>-vex.spdx.json`.

The VEX option requires vulnerability edit access and is not available on the Free tier or through ShareLynk links. To ship VEX data inside the SBOM instead, use the **SBOM** download and select the **Vulnerability Status** option. See [Downloading SBOMs](/product-guides/sbom-management/versions#downloading-sboms).

***

## Querying Vulnerabilities

### Via CLI

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

# Filter by environment
pylynk vulns --prod "my-backend-service" --env "production"

# 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,component_version,severity,cvss,epss,status,justification"

# Export for compliance reporting
pylynk vulns --prod "my-backend-service" --env "production" \
  --vuln-details --vex-details --output csv > vuln-report.csv

# List all available column names
pylynk vulns --list-columns
```

| Parameter        | Required | Default     | Description                                                   |
| ---------------- | -------- | ----------- | ------------------------------------------------------------- |
| `--prod`         | Yes      | —           | Product name                                                  |
| `--env`          | No       | `default`   | Environment name                                              |
| `--vuln-details` | No       | Off         | Include vulnerability metadata (CVSS vector, CWE, references) |
| `--vex-details`  | No       | Off         | Include VEX status details (justification, response)          |
| `--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`                         |

### Via API

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { organization { projectGroups(first: 5) { nodes { name projects { nodes { name sboms(first: 1) { nodes { id componentVulns(first: 10) { nodes { vuln { vulnId sev cvssScore } component { name version } } } } } } } } } } }"
  }'
```

### Via MCP

```
list_vulnerabilities       # List vulnerabilities with severity/VEX/KEV filtering
get_vulnerability          # Get vulnerability by CVE ID or UUID
search_vulnerabilities     # Search vulnerabilities across all products
```

***

## Issue Tracker Integration

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

### Jira Integration

1. Ensure the Jira integration is configured (see [Administration: Jira](/administration/jira)).
2. Open a vulnerability detail view.
3. Click **Create Jira Ticket**.
4. The ticket is created with vulnerability details pre-populated.
5. Ticket status is synced bidirectionally — updates in Jira are reflected in Interlynk.

### Linear Integration

1. Ensure the Linear integration is configured (see [Administration: Linear](/administration/linear)).
2. Open a vulnerability detail view.
3. Click **Create Linear Issue**.
4. The issue is created with vulnerability details.

### Bulk Ticket Actions

Issue-tracker actions are also available on a multi-row selection, from the bulk action bar described in [Acting on Several Vulnerabilities at Once](#acting-on-several-vulnerabilities-at-once).

These actions stay visible when no tracker is connected, and when the feature is not included in your plan, rather than disappearing from the bar. Selecting one in that state tells you what is missing, so the path to enabling ticketing is discoverable from the place you would use it.

{% hint style="info" %}
Custom field values can flow into Jira tickets when custom field mappings are configured. See [Vulnerability Custom Fields](/administration/vulnerability-custom-fields) for details.
{% endhint %}

***

## Downloading Vulnerability Data

Vulnerability data can be included in SBOM downloads:

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

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

{% hint style="info" %}
Vulnerability data in downloaded SBOMs includes VEX status and justifications in CycloneDX, and in **SPDX 3.0** exports, which round-trip VEX and support status. SPDX 2.x downloads include vulnerability references but not VEX data.
{% endhint %}

***

## Permission Matrix

| Permission                      | Admin | Operator | Viewer |
| ------------------------------- | :---: | :------: | :----: |
| View vulnerabilities            |   ✓   |     ✓    |    ✓   |
| View feeds                      |   ✓   |     ✓    |    ✓   |
| Manage feeds                    |   ✓   |     ✓    |    —   |
| Manage lists                    |   ✓   |     ✓    |    —   |
| Manage custom fields            |   ✓   |     ✓    |    —   |
| Edit vulnerabilities            |   ✓   |     ✓    |    —   |
| View SBOMs (vulnerability data) |   ✓   |     ✓    |    ✓   |

View Vulnerabilities gates VEX and vulnerability exports, the download options on vulnerability tables, and the Copy VEX action. It is not granted automatically to custom roles. See [Role Management](/administration/role-management) for the full permission list.

***

## Security Warnings

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

{% hint style="warning" %}
**VEX status is lost on re-upload unless retention is enabled.** Enable "Retain Vulnerability Status with Version" and "Copy VEX Across Versions on Import" in Environment Settings to preserve triage decisions.
{% endhint %}

{% hint style="warning" %}
**Custom CVSS adjustments override the original severity.** Misconfigured adjustments can suppress critical vulnerabilities. Review all custom scoring changes periodically.
{% endhint %}

{% hint style="warning" %}
**KEV-listed vulnerabilities are actively exploited.** These should be remediated with the highest priority regardless of CVSS score. Configure policies to fail on KEV-listed vulnerabilities.
{% endhint %}

***

## Common Misconfigurations

| Issue                                    | Symptom                                                   | Fix                                                                                          |
| ---------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Vulnerability scanning disabled          | No vulnerabilities appear after upload                    | Enable "Run Vulnerability Scan" in Environment Settings                                      |
| Components lack identifiers              | Known-vulnerable components show no vulnerabilities       | Improve SBOM tooling to produce PURL/CPE identifiers                                         |
| VEX status not preserved across versions | Triage work lost on each upload                           | Enable "Retain Vulnerability Status with Version" and "Copy VEX Across Versions on Import"   |
| EPSS/KEV data missing                    | EPSS and KEV columns empty                                | EPSS/KEV enrichment is automatic; the vulnerability may be too new or not in the KEV catalog |
| Overly broad automation rules            | Non-critical vulnerabilities generating excessive tickets | Narrow rule conditions — target specific severities, EPSS thresholds, or KEV status          |
| Custom CVSS override too low             | Critical vulnerability not flagged by policies            | Review custom scoring adjustments; reset to base CVSS if the override is unjustified         |
| No Jira integration configured           | "Create Ticket" button not available                      | Configure the Jira integration in Settings > Organization > Integrations > Connections       |
| "Not Affected" without justification     | Compliance audit findings                                 | All "Not Affected" dispositions require a justification — review and add missing ones        |

***

## Recommended Best Practices

* **Prioritize by exploitability, not just severity.** Use EPSS scores and KEV status to focus on vulnerabilities most likely to be exploited. A high-EPSS, KEV-listed medium-severity vulnerability may be more urgent than a critical vulnerability with no known exploit.
* **Triage systematically.** Establish a workflow: new vulnerabilities → under investigation → affected/not affected → fixed. Record justifications for all "not affected" dispositions.
* **Use environment-aware prioritization.** A vulnerability in a `production` Environment is more urgent than the same vulnerability in `development`. Configure policies accordingly.
* **Enable VEX retention settings** to avoid re-triaging the same vulnerabilities when SBOMs are updated.
* **Use Custom Fields** to track organization-specific metadata (e.g., assigned engineer, remediation deadline, business impact assessment).
* **Review KEV-listed vulnerabilities immediately.** These are confirmed to be actively exploited and should be remediated with the highest priority.
* **Automate ticket creation** for vulnerabilities that match your triage thresholds (e.g., critical severity + KEV = auto-create Jira ticket).
* **Export vulnerability reports regularly** for compliance documentation using `pylynk vulns --output csv`.
* **Monitor vulnerability trends** across Products using the organization-level Vulnerabilities page to identify systemic issues (e.g., the same CVE appearing across multiple Products).
* **Document all VEX decisions** with clear justifications — this is essential for compliance audits and organizational knowledge transfer.


# Licenses

License management ensures your organization understands, tracks, and governs the open-source and proprietary licenses present in your software supply chain. Interlynk extracts license data from SBOMs, maps it to the SPDX license standard, and provides organization-wide license inventory, approval workflows, and obligation tracking.

***

## Overview

Every component in an SBOM may declare one or more licenses using [SPDX license expressions](https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/). The platform aggregates license data across all Products and Environments into an organization-wide inventory, enabling centralized governance.

Key capabilities:

* **SBOM-level license review** — view and edit licenses for all components in a Version.
* **Organization-level license inventory** — centralized view of all licenses across all Products.
* **License approval workflow** — approve, reject, or flag licenses for organizational use.
* **License obligations** — track compliance obligations associated with each license.
* **Custom licenses** — define and manage licenses not in the SPDX standard catalog.
* **Policy enforcement** — create policies that trigger on specific licenses or license types.

## Architecture

```
SBOM Upload
  └── Component Extraction
        └── License Expression Parsing
              ├── SPDX License Matching
              │     └── Organization License Record
              │           ├── Approval Status
              │           ├── Obligations
              │           └── Custom Attributes
              └── Custom License Matching
                    └── Organization Custom License Record

Organization License Inventory
  ├── All licenses across all Products
  ├── Approval status (Approved, Rejected, Unreviewed)
  ├── Obligation tracking
  └── Policy evaluation
```

***

## SBOM-Level License Review

### Viewing Component Licenses

1. Navigate to the Product and select a Version.
2. Click the **Licenses** tab.
3. The license list displays each component with its license expression, approval status, and obligation summary.

### License Expression Interpretation

Components may declare licenses using SPDX expressions:

| Expression Type    | Example                                | Meaning                                                    |
| ------------------ | -------------------------------------- | ---------------------------------------------------------- |
| **Single license** | `Apache-2.0`                           | Component is licensed under Apache 2.0                     |
| **OR expression**  | `MIT OR GPL-2.0`                       | Component is available under either license (user chooses) |
| **AND expression** | `Apache-2.0 AND MIT`                   | Component requires compliance with both licenses           |
| **WITH exception** | `GPL-2.0 WITH Classpath-exception-2.0` | License with a specific exception                          |

{% 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). When disabled, they are treated as alternatives (disjunctive).
{% endhint %}

### Editing Component Licenses

1. Navigate to the Version's **Licenses** tab.
2. Select a component.
3. Update the license expression, name, or URL.
4. Save.

License edits are recorded in the Version's Change Log.

***

## Organization License Inventory

The organization-level license inventory provides a centralized view of every license encountered across all Products.

### Accessing the Inventory

1. Navigate to the **Licenses** page in the main navigation.
2. The inventory displays all licenses with:

| Column              | Description                             |
| ------------------- | --------------------------------------- |
| **License Name**    | SPDX identifier or custom name          |
| **Type**            | SPDX standard or Custom                 |
| **Approval Status** | Approved, Rejected, or Unreviewed       |
| **Products**        | Number of Products using this license   |
| **Components**      | Number of components using this license |

### Adding a License

1. Navigate to the **Licenses** page.
2. Click **+** (Add License).
3. Enter:
   * **License Name** (required)
   * **License Text** (optional) — full license text for reference
   * **Attribution details** (optional) — required attribution notices
   * **Approval Status** — Approved, Rejected, or Unreviewed
4. Click **Save**.

### Editing a License

1. Navigate to the **Licenses** page.
2. Click **...** (Actions) on the license row and select **Edit License**.
3. Update the license details.
4. Click **Update**.

***

## License Approval Workflow

The approval workflow enables organizations to govern which licenses are acceptable in their software supply chain.

### Approval Statuses

| Status         | Description                                      | Impact                                                           |
| -------------- | ------------------------------------------------ | ---------------------------------------------------------------- |
| **Approved**   | License is cleared for use in the organization   | No policy violations triggered                                   |
| **Rejected**   | License is not acceptable for organizational use | Policy rules targeting rejected licenses will trigger violations |
| **Unreviewed** | License has not been evaluated yet               | Identified for review; may trigger policy warnings               |

### Setting Approval Status

1. Navigate to the **Licenses** page.
2. Click **...** (Edit License) on the license row.
3. Set the **Approval Status**.
4. Click **Update**.

### Bulk License Review

For organizations with many licenses, prioritize review by:

1. Sort by **Components** (descending) to address the most widely-used licenses first.
2. Filter by **Unreviewed** status to focus on licenses that need attention.
3. Group by license family (e.g., all GPL variants, all Apache variants).

***

## License Obligations

Obligations track the compliance requirements associated with each license.

### Common Obligation Types

| Obligation            | Affected Licenses      | Requirement                                |
| --------------------- | ---------------------- | ------------------------------------------ |
| **Attribution**       | MIT, BSD, Apache-2.0   | Include copyright notice and license text  |
| **Source disclosure** | GPL-2.0, GPL-3.0, LGPL | Make source code available                 |
| **Copyleft**          | GPL-2.0, GPL-3.0       | Derivative works must use the same license |
| **Patent grant**      | Apache-2.0             | License includes a patent grant            |
| **Network copyleft**  | AGPL-3.0               | Source must be available for network users |

### Tracking Obligations

Obligations are associated with licenses in the organization inventory. When viewing a Version's Licenses tab, obligation indicators show which components carry specific compliance requirements.

***

## Custom Licenses

For licenses not in the SPDX standard catalog, create custom license records:

1. Navigate to the **Licenses** page.
2. Click **+** (Add License).
3. Enter the custom license details:
   * **License Name** — a unique identifier for the custom license
   * **License Text** — the full license text
   * **Attribution details** — any required notices
   * **Approval Status** — your organization's assessment
4. Click **Save**.

Custom licenses appear alongside SPDX licenses in the inventory and can be referenced in policy rules.

***

## Policy Integration

Licenses can be evaluated by the policy engine. Create policy rules that:

| Policy Purpose                         | Subject           | Operator | Value    |
| -------------------------------------- | ----------------- | -------- | -------- |
| Block GPL licenses                     | Component License | IS       | GPL-2.0  |
| Require license presence               | Component License | EXISTS   | —        |
| Flag rejected licenses                 | License Approval  | IS       | Rejected |
| Block copyleft in proprietary products | Component License | IS       | AGPL-3.0 |

For policy configuration details, see [Policies](/product-guides/security-and-compliance/policies).

***

## Permission Matrix

| Permission    | Admin | Operator | Viewer |
| ------------- | :---: | :------: | :----: |
| View licenses |   ✓   |     ✓    |    ✓   |
| Edit licenses |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Copyleft licenses (GPL, AGPL) may require source code disclosure.** Components using these licenses in proprietary products can create legal obligations. Review and approve licenses before deploying software containing copyleft-licensed components.
{% endhint %}

{% hint style="warning" %}
**Missing license data creates compliance blind spots.** Components without license expressions cannot be evaluated for license compliance. Ensure SBOM generation tools extract license information for all components.
{% endhint %}

{% hint style="warning" %}
**License expression interpretation affects compliance evaluation.** Verify that the "Interpret License List as AND expression" setting matches your organization's interpretation of multi-license declarations.
{% endhint %}

***

## Common Misconfigurations

| Issue                          | Symptom                                                   | Fix                                                                                   |
| ------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| No licenses reviewed           | All licenses show as "Unreviewed"                         | Prioritize review by component count; start with the most-used licenses               |
| License policy not assigned    | License violations not detected                           | Create license-focused policies and assign them to Product Environments               |
| AND/OR interpretation mismatch | Compliance evaluation does not match legal interpretation | Verify the "Interpret License List as AND expression" setting in Environment Settings |
| Custom license not created     | Components show unknown license status                    | Add the custom license to the organization inventory                                  |
| SBOM missing license data      | Components show no license information                    | Improve SBOM generation tooling to extract license expressions                        |
| Rejected license not flagged   | Products ship with rejected licenses                      | Create a policy rule that triggers on rejected licenses                               |

***

## Recommended Best Practices

* **Review and approve all licenses** in your organization inventory. Unreviewed licenses represent unknown legal risk.
* **Create a license policy** that blocks rejected licenses from being used in production builds.
* **Start with a permissive approach.** Approve well-known permissive licenses (MIT, Apache-2.0, BSD) first, then evaluate copyleft and restrictive licenses individually.
* **Document approval rationale.** Record why each license was approved or rejected for future reference and audit evidence.
* **Monitor for new licenses.** Periodically check the inventory for newly encountered licenses that need review.
* **Use SPDX expressions consistently.** Standardize on SPDX identifiers for license expressions in your SBOM generation tools.
* **Track obligations per license.** Ensure your engineering and legal teams understand the compliance requirements of approved licenses.
* **Configure the AND/OR interpretation setting** based on legal guidance for your organization's products.
* **Include license data in SBOM exports** for distribution to customers and regulators.


# Policies

Policies define automated rules that evaluate SBOMs against security, compliance, and quality standards. When an SBOM is uploaded and policy evaluation is enabled, the platform checks each policy rule and reports violations — enabling organizations to enforce standards across products, environments, and CI/CD pipelines.

***

## Overview

A Policy consists of one or more **rules**, each with a **subject** (what to evaluate), an **operator** (how to compare), and a **value** (the threshold or target). Policies can be scoped to specific Products and Environments, and their results can be surfaced as PR comments, notifications, and ticket creation.

Policies serve three primary purposes:

* **Gate enforcement** — block releases that fail security thresholds (e.g., no critical vulnerabilities in production).
* **Compliance monitoring** — track adherence to regulatory standards (e.g., SBOM quality score above 80%).
* **Risk alerting** — notify teams when risk indicators exceed thresholds (e.g., EPSS score above 0.5).

## Architecture

```
Policy Engine
  ├── Policy
  │     ├── Rule 1: Subject + Operator + Value
  │     ├── Rule 2: Subject + Operator + Value
  │     └── Rule N: ...
  │
  ├── Evaluation Trigger
  │     ├── Automatic: on SBOM upload (when enabled in Settings)
  │     └── Manual: on-demand scan
  │
  └── Results
        ├── Pass / Fail per rule
        ├── Violation details (component, vulnerability, value)
        ├── PR comments (when enabled)
        ├── Notifications (Slack, Teams, Email)
        └── Ticket creation (Jira, Linear)
```

**Interactions:**

* **Environment Settings** — policies are evaluated per Environment when enabled.
* **Automation Rules** — automation executes before policy evaluation, so automation fixes may resolve potential violations.
* **Notifications** — policy failures trigger notifications based on configured integrations.
* **CI/CD** — policy results can be posted as PR comments and used to fail builds.

***

## Creating Policies

### Via Dashboard

1. Navigate to the **Policies** page in the main navigation.
2. Click **+ Create Policy**.
3. Enter a **Policy Name** — use a descriptive name that communicates the policy's purpose (e.g., `Production Vulnerability Gate`, `SBOM Quality Minimum`).
4. Add one or more **Rules** (see Rule Configuration below).
5. Click **Save**.

### Policy Scope

Policies can be applied at two levels:

| Scope                 | Behavior                                              |
| --------------------- | ----------------------------------------------------- |
| **Organization-wide** | Policy is evaluated for all Products and Environments |
| **Product-specific**  | Policy is applied only to selected Products           |

To assign a policy to specific Products:

1. Navigate to the Product's Environment page.
2. Click the **Settings** tab.
3. Under **Policies**, select the policies to apply.

Alternatively, from the Policy detail page, assign the policy to specific Product Environments.

### Policy Options

Beyond its rules, a policy carries options that change what the evaluation considers.

| Option                               | Effect                                                                                 |
| ------------------------------------ | -------------------------------------------------------------------------------------- |
| **Exclude resolved vulnerabilities** | Vulnerabilities marked **Not Affected** or **Fixed** are left out of policy evaluation |

Set the option in the policy form when creating or editing a policy.

Turn **Exclude resolved vulnerabilities** on when triaged findings keep re-triggering the same violations. Once a vulnerability has been dispositioned as Not Affected or Fixed, the policy stops counting it, so violation lists reflect outstanding work rather than work already assessed. Leave it off when you want a policy to report on every matching vulnerability regardless of disposition, for example an audit policy that has to show the full set.

{% hint style="info" %}
The option applies to the whole policy, not to individual rules. A policy that mixes vulnerability rules with component or SBOM rules still excludes resolved vulnerabilities from every vulnerability rule it contains.
{% endhint %}

***

## Rule Configuration

Each rule defines a condition that is evaluated against SBOM data.

### Rule Structure

| Field        | Description                                                                                |
| ------------ | ------------------------------------------------------------------------------------------ |
| **Subject**  | The data attribute to evaluate (e.g., vulnerability severity, license type, component age) |
| **Operator** | The comparison type (e.g., IS, IS\_NOT, LESS\_THAN, MORE\_THAN, EXISTS)                    |
| **Value**    | The threshold or target value                                                              |

### Subject Categories

#### Vulnerability Subjects

| Subject                | Description                                                                   | Operators                     |
| ---------------------- | ----------------------------------------------------------------------------- | ----------------------------- |
| Vulnerability Severity | CVSS severity level                                                           | IS, IS\_NOT                   |
| CVSS Score             | Numeric CVSS base score                                                       | LESS\_THAN, MORE\_THAN, RANGE |
| EPSS Score             | Exploit prediction probability                                                | LESS\_THAN, MORE\_THAN, RANGE |
| KEV Status             | Whether in a known exploited vulnerabilities catalog (CISA KEV or ENISA EUVD) | IS, IS\_NOT                   |
| VEX Status             | Vulnerability disposition                                                     | IS, IS\_NOT                   |
| Vulnerability Count    | Number of vulnerabilities by severity                                         | LESS\_THAN, MORE\_THAN        |
| Assigned Age           | Days since a vulnerability was assigned for triage                            | LESS\_THAN, MORE\_THAN        |
| Risk Region Age        | Days since the affected version range was first published                     | LESS\_THAN, MORE\_THAN        |

#### Component Subjects

| Subject                 | Description                                          | Operators                     |
| ----------------------- | ---------------------------------------------------- | ----------------------------- |
| Component Name          | Specific component name                              | IS, IS\_NOT, EXISTS           |
| Component Version       | Component version string                             | IS, IS\_NOT                   |
| Component License       | License expression                                   | IS, IS\_NOT, EXISTS           |
| Component Type          | Component kind (library, framework, etc.)            | IS, IS\_NOT                   |
| Health Score            | Component health score (0–100)                       | LESS\_THAN, MORE\_THAN, RANGE |
| Support Level           | Component maintenance status                         | IS, IS\_NOT                   |
| Component Published Age | Days since the component version was first published | LESS\_THAN, MORE\_THAN        |
| Component Scope         | A chosen set of components the policy applies to     | IS, IS\_NOT                   |

#### SBOM Subjects

| Subject            | Description              | Operators              |
| ------------------ | ------------------------ | ---------------------- |
| SBOM Quality Score | Compliance quality score | LESS\_THAN, MORE\_THAN |
| Supplier           | SBOM supplier field      | EXISTS, NOT\_EXISTS    |
| Data License       | SBOM data license field  | IS, IS\_NOT, EXISTS    |

#### Custom Field Subjects

| Subject            | Description                | Operators                        |
| ------------------ | -------------------------- | -------------------------------- |
| Custom Text Field  | User-defined text field    | IS, IS\_NOT, EXISTS, NOT\_EXISTS |
| Custom Range Field | User-defined numeric field | LESS\_THAN, MORE\_THAN, RANGE    |

For custom field configuration, see [Vulnerability Custom Fields](/administration/vulnerability-custom-fields).

### Example Rules

| Policy Purpose                        | Subject                 | Operator   | Value               |
| ------------------------------------- | ----------------------- | ---------- | ------------------- |
| Block critical vulnerabilities        | Vulnerability Severity  | IS         | Critical            |
| Require minimum quality score         | SBOM Quality Score      | MORE\_THAN | 80                  |
| Flag KEV-listed vulnerabilities       | KEV Status              | IS         | True                |
| Block high-EPSS vulnerabilities       | EPSS Score              | MORE\_THAN | 0.5                 |
| Require supplier information          | Supplier                | EXISTS     | —                   |
| Flag abandoned components             | Support Level           | IS         | Abandoned           |
| Minimum health score                  | Health Score            | LESS\_THAN | 30                  |
| Flag stale assigned vulnerabilities   | Assigned Age            | MORE\_THAN | 30                  |
| Flag outdated component versions      | Component Published Age | MORE\_THAN | 730                 |
| Limit a policy to specific components | Component Scope         | IS         | Selected components |

***

## Applying Policies

### Automatic Evaluation

Policies are evaluated automatically on SBOM upload when the relevant settings are enabled:

1. Navigate to the Product's Environment **Settings** tab.
2. Ensure **Run SBOM Checks** is enabled (prerequisite for policy evaluation).
3. Assign policies to the Environment.

The policy evaluation runs as part of the SBOM processing pipeline, after automation rules and vulnerability scanning.

### Manual Evaluation

To run policy evaluation on demand:

1. Navigate to the Product and select a Version.
2. Click **...** (Actions) on the Version.
3. Select **Run Policy Scan**.

### CI/CD Integration

#### Policy Gate

The policy gate returns a single verdict for one SBOM version, so a pipeline can block a pull request on policy failures. Run `pylynk gate` after the upload:

```bash
# Upload SBOM
pylynk upload --prod "my-backend-service" --env "production" --sbom sbom.cdx.json

# Block the build if a policy of blocking severity was violated
pylynk gate --prod "my-backend-service" --env "production" --ver "v1.2.0" --timeout 600
```

The gate waits for the asynchronous policy scan to finish, prints the verdict, and exits with a code the pipeline can act on:

| Status          | Exit | Meaning                                                                             |
| --------------- | :--: | ----------------------------------------------------------------------------------- |
| `PASS`          |   0  | All active policies evaluated, no blocking violations                               |
| `NO_POLICIES`   |   0  | The organization has no active policies                                             |
| `FAIL`          |   3  | At least one active policy of blocking severity was violated                        |
| `IN_PROGRESS`   |   4  | The scan was still queued or running when the timeout was reached                   |
| `ERROR`         |   4  | Evaluation was incomplete or errored                                                |
| `NOT_EVALUATED` |   4  | No policy scan applies, such as vulnerability scanning disabled for the environment |

Behavior worth knowing before you wire this into a pipeline:

* **The gate counts policies, not violations.** A policy with four violations counts once as `failed`.
* **Only `fail`-severity policies block by default.** Pass `--fail-on warn` to block on `warn`-severity policies as well. Violations at non-blocking severities are still listed in the output.
* **An incomplete scan never reads as a pass.** A scan that is queued, running, or errored returns exit `4`. This is deliberate, so an interrupted scan cannot let a failing SBOM through.
* **Disabled and deleted policies are excluded** from the verdict and the counts.
* **A specific version is required.** The gate does not fall back to the latest version, because that is racy when parallel CI runs upload concurrently.

Use `--policy-name` or `--policy-id` to gate on a single active policy instead of all of them.

For the full option list and output formats, see [pylynk: gate](/productivity-tools/pylynk#gate-policy-gate-for-ci-cd).

{% hint style="warning" %}
`pylynk status` reports whether the policy evaluation stage has finished, not whether the SBOM passed. Use `gate` to gate a build.
{% endhint %}

**PR comments:**

When **Enable PR Comments** is turned on in Environment Settings, policy results are automatically posted as comments on pull requests via the configured source control integration (GitHub, GitLab, Bitbucket).

***

## Reviewing Policy Results

### Version-Level Results

1. Navigate to the Product and select a Version.
2. Click the **Policy** tab.
3. The results display:

| Column          | Description                                                                     |
| --------------- | ------------------------------------------------------------------------------- |
| **Policy Name** | Name of the evaluated policy                                                    |
| **Status**      | Pass or Fail                                                                    |
| **Violations**  | Number of rule violations                                                       |
| **Details**     | Expandable list of specific violations with affected components/vulnerabilities |

### Policy Detail View

1. Navigate to the **Policies** page.
2. Click on a policy to view its detail page.
3. The detail page shows:
   * Policy rules and their configuration.
   * Evaluation history across Products and Environments.
   * Aggregated violation counts.

In policy results, the **Product** column links through to the product details page, so you can move from a violation to the affected product without going back through the Products list.

**Filtering results:** Use the filter controls on the policy detail page to narrow results by **Product**, **Environment**, and **SBOM version**. Version entries display as *"version (product name)"* for clarity when the same version string appears across multiple products. This is useful for auditing a specific release or tracing a policy failure to a particular environment.

***

## Managing Policies

### Editing Policies

1. Navigate to the **Policies** page.
2. Click on the policy to edit.
3. Modify rules, add new rules, or remove existing ones.
4. Click **Save**.

### Disabling Policies

Policies can be disabled without deletion:

1. Navigate to the Product's Environment **Settings** tab.
2. Remove the policy from the Environment's policy list.

### Deleting Policies

1. Navigate to the **Policies** page.
2. Click **...** (Actions) on the policy row.
3. Select **Delete**.
4. Confirm the deletion.

{% hint style="warning" %}
Deleting a policy removes all historical evaluation results for that policy. Disable policies instead of deleting them if you need to retain evaluation history.
{% endhint %}

***

## Notification and Ticketing on Violations

### Notifications

Policy failures can trigger notifications through configured integrations:

* **Slack** — violation summary posted to configured channels.
* **Microsoft Teams** — violation summary posted to configured channels.
* **Email** — violation details sent to subscribed users.

Subscribe to policy notifications on the Product Environment page by clicking the **Bell** icon and selecting **Policies**.

### Automatic Ticket Creation

When ticketing integrations are configured (Jira, Linear), policy violations can automatically create tickets for remediation tracking. This links the violation to a trackable work item.

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

***

## Permission Matrix

| Permission            | Admin | Operator | Viewer |
| --------------------- | :---: | :------: | :----: |
| View policies         |   ✓   |     ✓    |    ✓   |
| Edit policies         |   ✓   |     ✓    |    —   |
| Run policy scans      |   ✓   |     ✓    |    —   |
| Delete policies       |   ✓   |     ✓    |    —   |
| Edit product policies |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Deleting a policy removes all historical results.** Evaluation history is permanently lost. Disable policies by removing them from Environments instead of deleting them if you need to preserve history.
{% endhint %}

{% hint style="warning" %}
**Overly permissive policies create a false sense of security.** Regularly review policy rules to ensure thresholds match your organization's risk tolerance. A policy that allows critical vulnerabilities in production defeats its purpose.
{% endhint %}

{% hint style="warning" %}
**Policy evaluation requires vulnerability scanning.** If "Run Vulnerability Scan" is disabled, vulnerability-related policy rules will not have data to evaluate against and may produce incomplete results.
{% endhint %}

***

## Common Misconfigurations

| Issue                                  | Symptom                                                                  | Fix                                                                                       |
| -------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| No policies created                    | No policy results on any Version                                         | Create policies on the Policies page and assign them to Product Environments              |
| Policy not assigned to Environment     | Policy exists but never evaluates                                        | Assign the policy to the target Environment in Product Settings                           |
| Vulnerability scanning disabled        | Vulnerability-related rules produce no violations                        | Enable "Run Vulnerability Scan" in Environment Settings                                   |
| SBOM checks disabled                   | Quality score rules cannot evaluate                                      | Enable "Run SBOM Checks" in Environment Settings                                          |
| Policy too broad                       | Excessive violations overwhelm the team                                  | Narrow rules — use specific severity levels, EPSS thresholds, or KEV-only targeting       |
| Policy too narrow                      | Critical issues not caught                                               | Review rules to ensure they cover your minimum security requirements                      |
| PR comments not posting                | Policy results not visible on pull requests                              | Enable "Enable PR Comments" in Environment Settings and verify source control integration |
| Policy results stale                   | Results do not reflect current SBOM state                                | Run a manual policy scan or re-upload the SBOM                                            |
| Triaged vulnerabilities keep violating | Findings already marked Not Affected or Fixed still appear as violations | Turn on **Exclude resolved vulnerabilities** in the policy form                           |

***

## Recommended Best Practices

* **Start with a minimal production gate.** Create a policy that fails on critical vulnerabilities and KEV-listed issues. Expand coverage over time.
* **Differentiate policies by Environment.** Production should have stricter policies than development. Use separate policies or environment-specific assignments.
* **Combine CVSS with EPSS for prioritization.** A rule that triggers on `CVSS > 7.0 AND EPSS > 0.1` catches high-severity, likely-exploited vulnerabilities while reducing noise.
* **Use policies to enforce SBOM quality.** Add rules for minimum quality scores, required supplier information, and data license compliance.
* **Enable PR comments in CI/CD Environments.** This gives developers immediate feedback on policy violations before merge.
* **Review policies quarterly.** As your security posture matures, tighten thresholds and add new rule categories.
* **Name policies descriptively.** Use names like `Production Critical Gate` or `FDA Compliance Minimum` rather than `Policy 1`.
* **Avoid creating too many policies.** Consolidate related rules into a single policy to simplify management and reduce evaluation overhead.
* **Exclude resolved vulnerabilities on enforcement policies.** A gate policy should report outstanding risk. Leave the option off only on policies whose purpose is full-inventory reporting.
* **Use Component Scope to pilot a strict policy.** Apply a tighter rule to a small set of components first, then widen the scope once the violation volume is understood.
* **Use Custom Fields in policy rules** to enforce organization-specific risk thresholds (e.g., fail if custom risk score > 80).
* **Document policy rationale.** Maintain internal documentation of why each policy exists and what risk it mitigates.


# Component Support

Component support tracking monitors the maintenance status of third-party components in your SBOMs. Interlynk identifies abandoned, deprecated, and end-of-life components so your organization can proactively manage supply chain risk before unmaintained dependencies become security liabilities.

***

## Overview

When **Run Component Support Analysis** is enabled in Environment Settings, the platform evaluates each component in an uploaded SBOM and assigns a support level based on package registry data, repository activity, and ecosystem signals.

Support tracking helps answer:

* Which components in my portfolio are no longer maintained?
* Are any components approaching end-of-life or end-of-support?
* Which Products have the highest concentration of unsupported dependencies?

## Architecture

```
SBOM Upload
  └── Component Extraction
        └── Support Analysis Pipeline
              ├── Package Registry Lookup
              │     ├── Deprecation status
              │     ├── Archive status
              │     └── Last publish date
              ├── Repository Analysis
              │     ├── Last commit date
              │     ├── Contributor activity
              │     └── Archive status
              └── Support Level Assignment
                    ├── Actively Maintained
                    ├── No Longer Maintained
                    ├── Abandoned
                    └── Unspecified
```

**Integration points:**

* **Health Scoring** — support status is a factor in the security dimension of the health score (see [Health Scoring](/administration/health-scoring)).
* **Policies** — policy rules can trigger on component support levels (e.g., fail if abandoned components are present).
* **SBOM Downloads** — support status data can be included in downloaded SBOMs.

***

## Support Levels

| Level                    | Description                                                      | Typical Signals                                                                           |
| ------------------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Actively Maintained**  | Component is actively developed and receives updates             | Recent commits, recent package releases, active contributor base                          |
| **No Longer Maintained** | Component has stopped receiving updates but is not yet abandoned | No recent releases, repository still accessible, maintainer has signaled reduced activity |
| **Abandoned**            | Component is no longer maintained or supported                   | Repository archived, package deprecated in registry, no activity for extended period      |
| **Unspecified**          | Support status could not be determined                           | Missing PURL, no package registry match, insufficient signals                             |

***

## Viewing Support Status

### Version-Level View

1. Navigate to the Product and select a Version.
2. Click the **Support** tab.
3. The support view displays each component with:

| Column                  | Description                                            |
| ----------------------- | ------------------------------------------------------ |
| **Component**           | Component name and version                             |
| **Support Level**       | Current support status                                 |
| **End-of-Support Date** | Date when support ends (if known)                      |
| **End-of-Life Date**    | Date when the component reaches end of life (if known) |
| **Last Updated**        | When the support data was last refreshed               |

### Filtering by Support Level

Use filters to focus on components that need attention:

* **Abandoned** — highest priority; these components receive no security patches.
* **No Longer Maintained** — medium priority; may still be functional but risk is increasing.
* **Unspecified** — investigate to determine actual status.

***

## Support Overrides

When the platform's automated assessment is incorrect or your organization has internal knowledge about a component's support status, you can override the assigned level.

### Setting an Override

1. Navigate to the Version's **Support** tab.
2. Select a component and click **Set Status**.
3. Change the support level to the correct value.
4. Optionally set end-of-support or end-of-life dates.
5. Save.

Overrides apply to the specific component and persist across SBOM re-uploads for the same component identifier.

### Setting the Status for Several Components

1. Navigate to the Version's **Support** tab.
2. Select the rows you want to update using the row checkboxes.
3. A **Set Support Status** action appears at the bottom of the table. Click it.
4. Set the support level and any dates, then save.

The selection is cleared once the update is applied, and also when you search, change a filter, or run any other row action, so a stale selection cannot be carried into the next update.

Bulk updates require the Edit Support Levels permission. They are unavailable on archived SBOMs and in the customer share view.

***

## Third-Party Support Status

For third-party components, you can record how the dependency is maintained by its supplier — independent of the platform's automated maintenance assessment.

### Setting Third-Party Support Status

1. Navigate to the Version's **Support** tab.
2. Select a third-party component and click **Set Status**.
3. Choose the **third-party support status**.
4. Optionally add a **supplier description** describing how the supplier maintains the component.
5. Save.

The supplier description is preserved across re-imports, is included in the support-level **CSV export**, and is exported and imported in **CycloneDX**.

### Support Confidence & Assessment Cards

The **Support Status** tab surfaces assessment and summary cards for the SBOM:

* **Support-level confidence** is scored against the **SBOM scope** — the cards reflect how much of the SBOM the recorded status actually covers, so a status set on a handful of components does not read as full coverage.
* **Product Support Status** assessment cards summarize the distribution of support levels across the SBOM.

Third-party support counts are also surfaced in the **product overview** and the **SBOM PDF**, and a support explanation is added to **CycloneDX exports**.

***

## Support Status in Downloads

Include support status data in SBOM downloads:

### Via CLI

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

# Export support levels only as CSV
pylynk download --prod "my-backend-service" --env "production" --ver "v1.2.0" \
  --support-level-only --out-file support-report.csv
```

| Parameter                  | Description                                                                    |
| -------------------------- | ------------------------------------------------------------------------------ |
| `--include-support-status` | Embed support level metadata in the downloaded SBOM                            |
| `--support-level-only`     | Export only support level data as CSV (component name, version, support level) |

### Via Dashboard

When downloading an SBOM from the Dashboard, the support status data is included in the enhanced (non-original) SBOM download.

The support status CSV export includes components contributed by the Version's referenced Parts, so parts-supplied components appear in the export alongside the Version's own components.

***

## Health Score Integration

Support status directly influences the **security** dimension of the component health score:

| Support Status                | Health Score Impact                   |
| ----------------------------- | ------------------------------------- |
| Actively Maintained           | No penalty                            |
| No Longer Maintained          | Moderate penalty to security score    |
| Abandoned                     | Significant penalty to security score |
| Deprecated (package registry) | Penalty to security score             |
| End-of-Life reached           | Significant penalty to security score |

Health score weights and thresholds can be customized in [Administration: Health Scoring](/administration/health-scoring).

***

## Policy Integration

Create policy rules that evaluate component support status:

| Policy Purpose                  | Subject       | Operator   | Value                |
| ------------------------------- | ------------- | ---------- | -------------------- |
| Block abandoned components      | Support Level | IS         | Abandoned            |
| Warn on unmaintained components | Support Level | IS         | No Longer Maintained |
| Enforce minimum health score    | Health Score  | LESS\_THAN | 30                   |

For policy configuration, see [Policies](/product-guides/security-and-compliance/policies).

***

## Permission Matrix

| Permission            | Admin | Operator | Viewer |
| --------------------- | :---: | :------: | :----: |
| View support          |   ✓   |     ✓    |    ✓   |
| Edit support          |   ✓   |     ✓    |    —   |
| Delete support        |   ✓   |     ✓    |    —   |
| View support levels   |   ✓   |     ✓    |    ✓   |
| Edit support levels   |   ✓   |     ✓    |    —   |
| Delete support levels |   ✓   |     ✓    |    —   |

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Abandoned components receive no security patches.** Vulnerabilities discovered in abandoned components cannot be fixed upstream. Plan migration to actively maintained alternatives for all abandoned dependencies.
{% endhint %}

{% hint style="warning" %}
**Components without PURL identifiers cannot be analyzed for support status.** These will be marked as "Unspecified" and represent unknown risk. Ensure SBOM generation tools produce PURL identifiers for accurate support analysis.
{% endhint %}

{% hint style="warning" %}
**End-of-life dates may not be publicly documented.** The platform relies on signals from package registries and repositories. Supplement automated analysis with your own knowledge of component lifecycles.
{% endhint %}

***

## Common Misconfigurations

| Issue                                       | Symptom                                      | Fix                                                                               |
| ------------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------- |
| Support analysis disabled                   | Support tab shows no data                    | Enable "Run Component Support Analysis" in Environment Settings                   |
| Components show "Unspecified"               | Unable to determine support status           | Verify SBOM includes PURL identifiers; components without PURL cannot be analyzed |
| Overrides not persisting                    | Support level resets on re-upload            | Verify the override was applied to the correct component identifier               |
| Health scores not reflecting support status | Abandoned components show high health scores | Verify security weight is not set to 0% in Health Scoring configuration           |
| No policy enforcement on support levels     | Abandoned components not flagged             | Create a policy rule targeting abandoned or unmaintained support levels           |

***

## Recommended Best Practices

* **Enable component support analysis by default** in Environment Settings to surface maintenance risks early.
* **Create policies that block abandoned components** in production Environments to enforce supply chain hygiene.
* **Monitor "No Longer Maintained" components proactively.** These are on a path to abandonment — plan migrations before they become critical.
* **Review support status quarterly.** Component maintenance status changes over time; what was actively maintained last quarter may be abandoned now.
* **Use support status CSV exports** for reporting to management on supply chain health.
* **Supplement automated analysis with internal knowledge.** If you know a component is internally maintained or has a private support contract, apply overrides.
* **Combine support status with vulnerability data** for risk prioritization — a vulnerable abandoned component has no path to a fix and should be replaced.
* **Include support status in SBOM exports** when distributing SBOMs to customers or regulators to demonstrate supply chain awareness.


# Security Incident Impact Alerts

Security Incident Impact Alerts surface malicious-package supply-chain attacks before a CVE exists. When a campaign like Shai-Hulud is confirmed, Interlynk flags the affected package versions and identifies exactly which products across your organizations contain them, so teams can respond ahead of the CVE process.

{% hint style="info" %}
Security incident tracking is available on all plans, including free and trial organizations. Free and trial organizations can create, manage, and review security incidents.
{% endhint %}

***

## How It Works

An incident tracks a malicious-package supply-chain event from confirmation through remediation:

1. **Open an incident** for the confirmed campaign.
2. **Mark affected component versions** — enter them manually or import from a CSV.
3. **Scan SBOMs across organizations** to find the products that contain the affected versions.
4. **Review impact** from the dashboard to see which products are affected.
5. **Suppress findings** that don't apply to your context.
6. **Publish or resolve** the incident as remediation lands.

***

## Organization Impact Timeline

The customer incident view includes a timeline showing how an incident's impact across your organization evolved over time. The timeline is backed by an actor audit trail, so you can see who changed what and when as the incident moved from confirmation through remediation.

***

## Automation with Service Tokens

Security incidents can be created and managed programmatically using service tokens, so you can integrate incident workflows into automation. See [API Key Management](/administration/api-key-management) for token setup.

***

For help interpreting impact results, contact <support@interlynk.io>.


# Insights


# Analytics

The Analytics dashboard provides organization-wide and product-level metrics for SBOM coverage, vulnerability posture, compliance status, and supply chain health. Use analytics to track trends, identify systemic risks, and report on security posture to stakeholders.

***

## Overview

Analytics aggregate data across all Products, Environments, and Versions in your organization. Dashboards update automatically as new SBOMs are uploaded, vulnerabilities are discovered, and VEX dispositions are applied.

Key capabilities:

* **Organization-level metrics** — aggregate portfolio health, vulnerability trends, and compliance posture.
* **Product-level metrics** — drill into individual Product health, vulnerability counts, and component statistics.
* **Vulnerability trends** — track discovery rates, remediation progress, and severity distribution over time.
* **Coverage metrics** — monitor SBOM coverage across your software portfolio.
* **Compliance posture** — track compliance scores across Products and frameworks.

## Architecture

```
Analytics Engine
  ├── Organization Metrics
  │     ├── Total Products, Versions, Components
  │     ├── Vulnerability summary (by severity, VEX status)
  │     ├── SBOM format distribution
  │     ├── Compliance score averages
  │     └── Health score distribution
  │
  ├── Product Metrics
  │     ├── Version count and upload frequency
  │     ├── Component count and dependency depth
  │     ├── Vulnerability count (by severity, VEX status)
  │     ├── Compliance score per Version
  │     └── Health score per Version
  │
  └── Trend Analysis
        ├── Vulnerability discovery over time
        ├── Remediation rate
        ├── SBOM upload frequency
        └── Compliance score progression
```

***

## Organization Dashboard

The organization-level analytics dashboard provides a portfolio-wide view.

### Accessing the Dashboard

1. Navigate to the **Analytics** page in the main navigation.
2. The dashboard displays summary tiles and charts.

### Available Metrics

| Metric                        | Description                                                                                  |
| ----------------------------- | -------------------------------------------------------------------------------------------- |
| **Total Products**            | Number of active Products in the organization                                                |
| **Total Versions**            | Number of SBOM Versions across all Products                                                  |
| **Total Components**          | Number of unique components across all SBOMs                                                 |
| **Vulnerability Summary**     | Count of vulnerabilities by severity (Critical, High, Medium, Low)                           |
| **VEX Status Distribution**   | Breakdown of vulnerability dispositions (Affected, Not Affected, Under Investigation, Fixed) |
| **SBOM Format Distribution**  | Proportion of CycloneDX vs. SPDX SBOMs                                                       |
| **Compliance Score Average**  | Mean compliance score across all Products                                                    |
| **Health Score Distribution** | Distribution of component health scores across the portfolio                                 |

### Vulnerability Trend Charts

* **Discovery trend** — new vulnerabilities discovered per time period.
* **Severity trend** — vulnerability count over time by severity level.
* **Remediation trend** — rate of VEX status changes from "Under Investigation" or "Affected" to "Fixed" or "Not Affected."

### Filtering

Filter the dashboard by:

* **Time range** — last 7 days, 30 days, 90 days, or custom range.
* **Product** — drill down to a specific Product.
* **Environment** — filter by Environment (e.g., production only).
* **Label** — filter by Product labels for cross-cutting views.

***

## Product-Level Metrics

Each Product has its own analytics view accessible from the Product detail page.

### Accessing Product Metrics

1. Navigate to the **Products** page and select a Product.
2. Product-level metrics are displayed on the Product overview and can be accessed from the Environment dashboard.

### Available Product Metrics

| Metric                  | Description                                    |
| ----------------------- | ---------------------------------------------- |
| **Version Count**       | Number of Versions in the selected Environment |
| **Upload Frequency**    | Rate of SBOM uploads over time                 |
| **Component Count**     | Total components in the latest Version         |
| **Dependency Depth**    | Maximum depth of the dependency tree           |
| **Vulnerability Count** | Current vulnerabilities by severity            |
| **Compliance Score**    | Latest compliance score for the Version        |
| **Health Score**        | Component health score distribution            |

***

## Vulnerability Analytics

Vulnerability analytics provide detailed insight into your security posture.

### Severity Distribution

View the breakdown of vulnerabilities by CVSS severity level across:

* The entire organization
* Individual Products
* Specific Environments

### EPSS and KEV Correlation

Identify high-risk vulnerabilities by correlating:

* **High EPSS score** (likely to be exploited) with **Critical/High severity** — highest priority for remediation.
* **KEV-listed** vulnerabilities — actively exploited in the wild.

### VEX Progress Tracking

Track your organization's vulnerability triage progress:

| Metric                  | Meaning                                                                              |
| ----------------------- | ------------------------------------------------------------------------------------ |
| **Triage rate**         | Percentage of vulnerabilities with a VEX status (any status other than unset)        |
| **Remediation rate**    | Percentage of "Affected" vulnerabilities that have been moved to "Fixed"             |
| **Open critical count** | Number of Critical-severity vulnerabilities without "Fixed" or "Not Affected" status |

***

## Coverage Metrics

Coverage metrics help you understand how complete your SBOM program is.

| Metric                              | Description                                                                |
| ----------------------------------- | -------------------------------------------------------------------------- |
| **Products with active SBOMs**      | Number of Products that have received an SBOM upload in the current period |
| **Products without recent uploads** | Products with no SBOM upload in the last 30/90 days                        |
| **Environment coverage**            | Percentage of Environments with at least one SBOM Version                  |

***

## Compliance Analytics

Track compliance posture across the organization.

| Metric                         | Description                                                       |
| ------------------------------ | ----------------------------------------------------------------- |
| **Average compliance score**   | Mean score across all Products for the selected framework         |
| **Products below threshold**   | Number of Products with compliance scores below a defined minimum |
| **Check failure distribution** | Most common compliance check failures across the portfolio        |
| **Compliance trend**           | Score progression over time                                       |

### Compliance Summary Dashboard Cards

The main dashboard includes compliance summary cards that give a quick snapshot of your organization's compliance posture per framework — without navigating to a dedicated compliance view. Cards are visible when at least one compliance framework is enabled and compliance checks have run. Each card links through to the full compliance details view and supports a direct export action.

***

## Reporting and Export

### Dashboard Views

Analytics data is available in visual dashboard form for real-time monitoring and stakeholder presentations.

### Executive Summary PDF Export

Generate a branded PDF of the Executive Summary for sharing with leadership or including in audit packages:

1. Navigate to the **Analytics** page.
2. Open the **Executive Summary** section.
3. Click **Export PDF**.
4. The PDF is generated and downloaded immediately.

The PDF includes a branded cover page, vulnerability summary, compliance posture, and product-level health metrics — formatted for non-technical audiences.

### Compliance Report Export

Export a compliance report directly from the dashboard for a selected compliance framework:

1. Navigate to the **Analytics** page.
2. Locate the **Compliance** dashboard section.
3. Click the export action on the compliance card.
4. The report downloads as a formatted file showing compliance scores and check results across Products.

### Data Export

Export vulnerability and compliance data for external reporting:

```bash
# Export vulnerability data as CSV
pylynk vulns --prod "my-backend-service" --env "production" \
  --vuln-details --vex-details --output csv > vuln-report.csv

# Export component data with support status
pylynk download --prod "my-backend-service" --env "production" --ver "v1.2.0" \
  --support-level-only --out-file support-report.csv
```

***

## Impact of Disabled Products

{% hint style="info" %}
Disabled Products are excluded from analytics metrics and trend calculations. If you disable a Product, its vulnerability and compliance data will no longer contribute to organization-level dashboards. Re-enable the Product to restore its contribution.
{% endhint %}

***

## Permission Matrix

| Permission                              | Admin | Operator | Viewer |
| --------------------------------------- | :---: | :------: | :----: |
| View products (includes analytics data) |   ✓   |     ✓    |    ✓   |
| View SBOMs (includes metric data)       |   ✓   |     ✓    |    ✓   |

Analytics is read-only. All roles with product visibility can view analytics data.

For full permission details, see [Role Management](/administration/role-management).

***

## Security Warnings

{% hint style="warning" %}
**Analytics reflect only scanned data.** If vulnerability scanning or SBOM checks are disabled for some Products, analytics will underrepresent the true risk posture. Ensure scanning is enabled across all production Products for accurate metrics.
{% endhint %}

{% hint style="warning" %}
**Disabled Products are excluded from metrics.** Disabling a Product removes its data from dashboards. If the Product still has active deployments, this creates a gap in visibility.
{% endhint %}

***

## Common Misconfigurations

| Issue                                    | Symptom                             | Fix                                                                                 |
| ---------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------- |
| No data on analytics dashboard           | Dashboard shows zeros               | Verify Products exist and have uploaded SBOMs with scanning enabled                 |
| Vulnerability counts seem low            | Fewer vulnerabilities than expected | Ensure "Run Vulnerability Scan" is enabled in Environment Settings for all Products |
| Compliance scores not showing            | No compliance data                  | Enable a compliance framework and "Run SBOM Checks" in Settings                     |
| Trend data appears flat                  | No changes over time                | Verify SBOMs are being uploaded regularly; trends require multiple data points      |
| Disabled Products missing from dashboard | Expected data not shown             | Re-enable the Product or note that disabled Products are excluded by design         |
| Label-based filtering shows no results   | No data for selected label          | Verify Products have the selected label applied                                     |

***

## Recommended Best Practices

* **Review the organization dashboard weekly** to catch emerging vulnerability trends and coverage gaps.
* **Use label-based filtering** for team-specific or compliance-specific views (e.g., filter by `compliance:fda` to see only regulated Products).
* **Track remediation rates** as a key performance indicator for your security program.
* **Set up notifications for coverage gaps** — Products without recent SBOM uploads may indicate broken CI/CD pipelines.
* **Export reports monthly** for management and compliance stakeholders.
* **Enable scanning across all Products** to ensure analytics data is complete and representative.
* **Monitor EPSS and KEV trends** to identify periods of elevated risk across your portfolio.
* **Use Product-level drill-downs** for incident response — quickly assess which Products are affected by a new vulnerability.


# Tools

The Tools page provides utility functions for SBOM analysis and component investigation. Two tools are available: **SBOM Compare** for identifying drift between Versions, and **PURL Lookup** for investigating individual packages by their Package URL.

***

## Overview

Tools complement the core SBOM management workflow with ad-hoc analysis capabilities:

* **SBOM Compare** — compare two Versions side-by-side to identify added, removed, and modified components. Useful for release validation, drift detection, and change review.
* **PURL Lookup** — query package metadata, vulnerability data, and ecosystem information for any Package URL. Useful for component investigation, pre-adoption review, and incident response.

***

## SBOM Compare

SBOM Compare analyzes the differences between two Versions of the same or different Products. The comparison identifies component-level changes to help you understand what changed between releases.

### Running a Comparison

1. Navigate to the **Tools** page in the main navigation.
2. Select the **Compare** tab.
3. Select the **Source Version**:
   * Choose a Product.
   * Choose an Environment.
   * Choose a Version.
4. Select the **Target Version**:
   * Choose a Product (can be the same or different).
   * Choose an Environment.
   * Choose a Version.
5. Click **Compare**.

### Comparison Results

The comparison results display:

| Category      | Description                                                     |
| ------------- | --------------------------------------------------------------- |
| **Added**     | Components present in the target but not in the source          |
| **Removed**   | Components present in the source but not in the target          |
| **Modified**  | Components present in both but with version or metadata changes |
| **Unchanged** | Components identical in both Versions                           |

For each changed component, the comparison shows:

| Field              | Description                       |
| ------------------ | --------------------------------- |
| **Component Name** | Name of the affected component    |
| **Source Version** | Version string in the source SBOM |
| **Target Version** | Version string in the target SBOM |
| **Change Type**    | Added, Removed, or Modified       |

### Via MCP

The `lynk-mcp` server also supports version comparison:

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

### Use Cases

| Scenario                   | How to Use Compare                                                                          |
| -------------------------- | ------------------------------------------------------------------------------------------- |
| **Release validation**     | Compare the previous production version with the new candidate to review dependency changes |
| **Drift detection**        | Compare the same version across Development and Production environments to identify drift   |
| **Incident response**      | Compare a known-good version with the current version to identify recently added components |
| **Upgrade tracking**       | Compare before and after a dependency upgrade to confirm expected changes                   |
| **Cross-product analysis** | Compare two related Products to understand shared vs. unique dependencies                   |

***

## PURL Lookup

PURL Lookup queries package metadata and vulnerability data for a specific Package URL (PURL). Use it to investigate components before adoption, during incident response, or for ad-hoc analysis.

### Running a Lookup

1. Navigate to the **Tools** page in the main navigation.
2. Select the **PURL** tab.
3. Enter the **Package URL** in PURL format.
4. Click **Lookup**.

### PURL Format

Package URLs follow the format: `pkg:type/namespace/name@version`

| Component   | Description                  | Example                                   |
| ----------- | ---------------------------- | ----------------------------------------- |
| `type`      | Package ecosystem            | `npm`, `pypi`, `maven`, `golang`, `nuget` |
| `namespace` | Package namespace (optional) | `@angular`, `org.apache`                  |
| `name`      | Package name                 | `express`, `log4j-core`                   |
| `version`   | Package version (optional)   | `4.18.2`, `2.17.1`                        |

**Examples:**

```
pkg:npm/%40angular/core@16.2.0
pkg:pypi/django@4.2.0
pkg:maven/org.apache.logging.log4j/log4j-core@2.17.1
pkg:golang/github.com/gin-gonic/gin@v1.9.1
pkg:nuget/Newtonsoft.Json@13.0.3
```

### Lookup Results

The lookup returns available data for the package:

| Data                  | Description                                          |
| --------------------- | ---------------------------------------------------- |
| **Package metadata**  | Name, version, description, homepage, repository URL |
| **Vulnerabilities**   | Known CVEs affecting this package version            |
| **License**           | License expression from the package registry         |
| **Support status**    | Deprecation, archive, and maintenance indicators     |
| **Health score**      | Aggregated health score (age, community, security)   |
| **OpenSSF Scorecard** | Security posture evaluation (if available)           |
| **Version history**   | Available versions and release dates                 |

### Use Cases

| Scenario                        | How to Use PURL Lookup                                                                                 |
| ------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Pre-adoption review**         | Look up a package before adding it as a dependency to check for vulnerabilities and maintenance status |
| **Incident response**           | Quickly check if a specific package version is affected by a newly published CVE                       |
| **Component investigation**     | Research an unfamiliar component found in a vendor SBOM                                                |
| **License review**              | Check the license of a package before adding it to a project with specific license requirements        |
| **Dependency upgrade planning** | Compare vulnerability counts across versions to find a safe upgrade target                             |

***

## Permission Matrix

| Permission                            | Admin | Operator | Viewer |
| ------------------------------------- | :---: | :------: | :----: |
| View products (includes Tools access) |   ✓   |     ✓    |    ✓   |

Tools are read-only. All roles with product visibility can use the Tools page.

For full permission details, see [Role Management](/administration/role-management).

***

## Common Misconfigurations

| Issue                                 | Symptom                                      | Fix                                                                                                                                     |
| ------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Compare shows no differences          | Identical components in both Versions        | The Versions may contain the same SBOM; verify different SBOMs were uploaded                                                            |
| PURL lookup returns no results        | "Not found" for a valid package              | Verify the PURL format is correct; the package may not be in a supported ecosystem registry                                             |
| PURL format invalid                   | Lookup fails with validation error           | Ensure the PURL follows the `pkg:type/namespace/name@version` format; URL-encode special characters (e.g., `%40` for `@` in namespaces) |
| Compare across Products not available | Cannot select a different Product for target | Select the target Product from the Product dropdown in the target section                                                               |

***

## Recommended Best Practices

* **Compare Versions before every production release** to validate that only expected dependency changes are included.
* **Use PURL Lookup for pre-adoption review** before adding new dependencies to your projects.
* **Look up PURLs during incident response** to quickly assess if your portfolio contains a vulnerable package version.
* **Compare across Environments** to detect configuration drift between development and production builds.
* **Use Compare results to validate automation rules** — confirm that automation rule changes produce the expected SBOM modifications.
* **URL-encode PURL namespaces** that contain special characters (e.g., use `%40` for `@` in npm scoped packages).


# Overview

This section describes the domain model of the Interlynk platform — how data is organized, how entities relate, and how to operate them safely. Understanding these concepts is essential for configuring the platform, building automation, and troubleshooting issues.

***

## System Model Overview

Interlynk organizes software supply chain data in a hierarchical model. Each level of the hierarchy adds specificity, from the broadest grouping (Product) down to individual security findings (Vulnerability).

```
Organization
└── Product
    └── Environment
        └── Version (SBOM)
            ├── Parts (embedded sub-SBOMs)
            │   └── Components
            │       └── Vulnerabilities
            └── Components
                └── Vulnerabilities
```

### Data Flow

1. A team member creates a **Product** to represent a software artifact.
2. Each Product contains one or more **Environments** (e.g., Development, Production) that reflect deployment stages.
3. When an SBOM is uploaded to a Product's Environment, it creates a **Version** — a point-in-time snapshot of the software's composition.
4. Each Version contains **Components** — the libraries, packages, and modules that make up the software.
5. Versions may also contain **Parts** — references to other Product Versions that are embedded or bundled alongside the primary SBOM.
6. The platform maps **Vulnerabilities** to Components using package identifiers (PURL, CPE) and vulnerability databases.

### Isolation Boundaries

| Boundary     | Scope                  | Behavior                                                                                                                                                                |
| ------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Organization | Top-level tenant       | All data is scoped to the organization. Users, tokens, policies, and vulnerabilities are isolated between organizations.                                                |
| Product      | Logical grouping       | Products are independent. Policies, labels, and settings do not cross Product boundaries unless explicitly configured at the organization level.                        |
| Environment  | Deployment stage       | Environments within a Product are independent. Each has its own settings, automation rules, and Version history. Vulnerability data does not merge across Environments. |
| Version      | Point-in-time snapshot | Each Version is an immutable record of the software's composition at upload time.                                                                                       |

### Lifecycle Flow

```
SBOM Upload → Version Created → Processing Pipeline → Operational State

Processing Pipeline:
  1. SBOM Checks (quality, completeness)
  2. Internal Component Labeling
  3. Automation Rules execution
  4. Vulnerability Scanning
  5. Component Support Analysis
  6. Policy Evaluation
```

After processing completes, the Version and its Components are available for querying, reporting, and compliance evaluation.


# Products

## Definition

A Product represents a software artifact that your organization builds, releases, and versions. It is the top-level grouping for all SBOM data within the platform.

A Product may represent:

* A web application or API service
* A library or SDK
* A firmware image
* A container image
* A hardware appliance with embedded software

Products provide logical isolation — each Product has its own set of Environments, Versions, policies, automation rules, and settings.

## Multi-Tenant Isolation

Products are scoped to your organization. No data from one organization's Products is visible to another organization. Within an organization, access to Products is governed by role-based permissions.

## When to Create a New Product

| Scenario                                | Recommendation                                                                                 |
| --------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Monolithic application                  | One Product                                                                                    |
| Microservices (independently versioned) | One Product per service                                                                        |
| Microservices (released as a unit)      | One Product, use Parts to compose sub-SBOMs                                                    |
| Internal tool vs. customer-facing app   | Separate Products — different compliance requirements                                          |
| Mobile app + backend API                | Separate Products — different build pipelines and release cadences                             |
| Same codebase, multiple build targets   | One Product with multiple Environments, or separate Products if compliance requirements differ |

**Compliance boundaries matter.** If two artifacts have different regulatory requirements (e.g., one is FDA-regulated and one is not), create separate Products so that policies and compliance checks can be scoped independently.

## Managing Products

### Creating via UI

1. Navigate to the **Products** page.
2. Click the **+** (Add Product) button.
3. Enter the **Name** (required) and optional **Description**.
4. Click **Save**.

The Product is created with the three default Environments: Default, Development, and Production.

### Creating via API

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation CreateProduct($input: CreateProjectGroupInput!) { createProjectGroup(input: $input) { projectGroup { id name } errors } }",
    "variables": {
      "input": {
        "name": "my-backend-service",
        "description": "Core backend API service"
      }
    }
  }'
```

### Creating via CLI

The `pylynk` CLI does not have an explicit `create product` command. Products are created implicitly on first SBOM upload if they do not already exist:

```bash
pylynk upload --prod "my-backend-service" --sbom sbom.cdx.json
```

To list existing Products:

```bash
pylynk prods
pylynk prods --output json
```

### Creating via MCP

When using the `lynk-mcp` server with an AI assistant, Products can be discovered and queried:

```
list_products          # List all products
get_product            # Get product details with all environments
```

{% hint style="info" %}
The MCP server provides read-only access to Products. Product creation is done via the UI, API, or CLI.
{% endhint %}

## Product Lifecycle

| State                   | Behavior                                                                                                                                                                  |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Active**              | Accepts SBOM uploads, vulnerability scanning runs, contributes to metrics and analytics.                                                                                  |
| **Disabled**            | Stops accepting new Versions and SBOMs. Vulnerability updates halt. Excluded from platform metrics and analytics. Existing data remains accessible for historical review. |
| **Marked for Deletion** | Scheduled for permanent removal. All associated Environments, Versions, Components, and Vulnerabilities will be deleted.                                                  |

A disabled Product can be re-enabled. Deletion is irreversible.

## Best Practices

* **Use consistent naming conventions.** Adopt a pattern such as `team-service-name` or `org/repo-name` so Products are easily identifiable and sortable.
* **Use labels for cross-cutting categorization.** Labels (e.g., `compliance:fda`, `team:platform`, `tier:critical`) allow filtering and grouping across Products without duplicating Product definitions.
* **Avoid creating duplicate Products.** If a Product already exists, upload SBOMs to it rather than creating a new one with a similar name.
* **Disable rather than delete.** If a Product reaches end-of-life, disable it to preserve historical data for audit purposes.
* **Scope Products to compliance boundaries.** Products with different regulatory requirements should be separate so that policies can be tailored independently.

## Common Misconfigurations

| Issue                                   | Symptom                                                   | Fix                                                            |
| --------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------- |
| Duplicate Products for the same service | Fragmented vulnerability data, inconsistent metrics       | Consolidate SBOMs under a single Product; delete the duplicate |
| Product name mismatch in CI/CD          | New Products created unintentionally on each pipeline run | Standardize `--prod` value in pipeline configuration           |
| Product disabled accidentally           | SBOM uploads rejected with no clear error                 | Re-enable the Product from the Products page                   |
| No description set                      | Products are hard to distinguish in large organizations   | Add descriptions during creation or via the edit action        |


# Environments

## Definition

An Environment represents a deployment stage or context within a Product. Environments isolate Version history, settings, automation rules, and policy evaluation so that different stages of your software lifecycle can be managed independently.

## Default Environments

Interlynk ships with three default Environments:

| Environment     | Purpose                                                              |
| --------------- | -------------------------------------------------------------------- |
| **Default**     | Catch-all for SBOMs uploaded without an explicit environment target. |
| **Development** | Feature branches, development builds, pre-merge artifacts.           |
| **Production**  | Release builds, production deployments, release-tagged artifacts.    |

Custom Environments are not supported. All Products use the same three default Environments.

## Isolation Behavior

Each Environment within a Product is fully independent:

* **Settings**: Import actions (vulnerability scanning, SBOM checks, automation rules) are configured per Environment.
* **Versions**: Each Environment maintains its own Version history. The same SBOM version string (e.g., `v1.2.0`) can exist in multiple Environments with different SBOMs.
* **Policies**: Policies can be scoped to specific Environments or applied across all Environments.
* **Automation Rules**: Rules are defined per Environment and do not cascade across Environments unless explicitly copied.

## Environment Settings Inheritance

```
Organization Defaults
  └── Environment Settings (per Environment)
```

1. When a new Environment is created, it inherits settings from **Organization Defaults** (see [Environment Defaults](/administration/environment-defaults)).
2. After creation, Environment settings are **independent** — changes to Organization Defaults do not propagate to existing Environments unless the administrator explicitly clicks "Apply to All Projects."
3. Individual Environment settings can be customized at any time.

## Environment Rules

Environment rules automate the routing of SBOMs from source control events (pushes, pull requests) to the correct Environment. See [Environment Rules](/administration/environment-rules) for details.

## Managing Environments

Every Product ships with the three default Environments. Environments cannot be added or removed.

**Via MCP:**

```
list_environments      # List environments for a product
get_environment        # Get environment details
```

### Configuring Environment Settings

1. Navigate to the **Product** detail page.
2. Select the target **Environment** from the environment selector.
3. Open the **Settings** tab.
4. Configure import actions, data retention, and scanning options.
5. Save changes.

## Promotion Workflows

Interlynk does not enforce a built-in promotion pipeline, but you can implement promotion workflows by:

1. **Uploading the same SBOM to successive Environments.** For example, upload to `development` during CI, then re-upload to `production` on release.
2. **Using Environment Rules** to automatically route SBOMs based on branch patterns (e.g., `feature/*` → development, `main` → production).
3. **Combining with policies** so that stricter policies in `production` act as promotion gates — SBOMs that fail production policies are flagged before deployment.

## Best Practices

* **Apply stricter policies in production.** Development Environments may warn on critical vulnerabilities; Production Environments should fail.
* **Enable vulnerability scanning in all Environments.** Catching vulnerabilities early in development reduces remediation cost.
* **Use Environment Rules for CI/CD.** Automate Environment routing based on branch patterns rather than relying on manual `--env` flags in every pipeline step.
* **Use the default Environment names consistently.** The three Environments (`default`, `development`, `production`) map to standard deployment stages. Use them consistently across Products so that organization-level policies and rules apply predictably.
* **Review Environment settings after applying Organization Defaults.** The "Apply to All Projects" action overwrites per-Environment customizations.

## Common Misconfigurations

| Issue                                             | Symptom                             | Fix                                                                                  |
| ------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------ |
| All SBOMs land in `default`                       | No environment-specific data        | Configure Environment Rules or add `--env` to CLI/CI commands                        |
| Vulnerability scanning disabled in an Environment | No vulnerability data after upload  | Enable "Run Vulnerability Scan" in Organization Defaults or per-Environment settings |
| Environment Rules wildcard at highest priority    | All events match the catch-all rule | Set wildcard rules to the lowest priority (highest number)                           |


# Versions

## Definition

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.

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.

## Relationship to Product and Environment

```
Product
  └── Environment
      └── Version (Sbom)
          ├── project_version: "v1.2.0"
          ├── spec: "CycloneDX" or "SPDX"
          └── lifecycle: processing → active → archived
```

A Version is uniquely identified by the combination of Product + Environment + Version string. The same version string (e.g., `v1.2.0`) can exist in multiple Environments but represents independent snapshots.

## 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, 3.0                | JSON      |

{% hint style="info" %}
SPDX exports default to **SPDX 3.0** when no version is requested. SPDX 3.0 documents round-trip VEX and support status alongside standard SBOM data. Request SPDX 2 explicitly (e.g., `SPDX-2.3`) if you need the older format.
{% endhint %}

## Upload Workflow

When an SBOM is uploaded, the platform executes a 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`.

### Via UI

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
```

The CLI automatically retries on transient failures with exponential backoff (1s, 2s, 4s between attempts). It does not retry on authentication errors (401) or client errors (4xx), except rate limiting (429).

### 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
```

When running in a supported CI environment (GitHub Actions, GitLab CI, Bitbucket Pipelines, Azure DevOps), `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:

```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"
```

The status command tracks five processing stages: `checksStatus`, `policyStatus`, `labelingStatus`, `automationStatus`, `vulnScanStatus`.

## Downloading SBOMs

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

```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
```

## Version Metadata

Each Version may include:

| Field                   | Description                                                      |
| ----------------------- | ---------------------------------------------------------------- |
| **Version string**      | The product version identifier (e.g., `v1.2.0`, `build-456`)     |
| **Spec**                | SBOM format (CycloneDX or SPDX)                                  |
| **Lifecycle**           | Current state (`processing`, `active`, `archived`)               |
| **TLP Classification**  | Traffic Light Protocol classification for sharing restrictions   |
| **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) |

## Version Comparison (Drift Analysis)

The MCP server supports comparing two Versions to identify drift:

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

This is useful for tracking component changes across releases and identifying newly introduced risks.

## Best Practices

* **Use meaningful version strings.** Align with your release versioning scheme (semver, build numbers, commit SHAs) so that 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"** in Environment settings to preserve VEX triage work when re-uploading SBOMs.
* **Enable "Copy VEX Across Versions on Import"** if your workflow involves frequent SBOM updates, so triage decisions carry forward to new Versions.
* **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.

## 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 or set `PYLYNK_INCLUDE_CI_METADATA=true` |
| Version uploaded to wrong Environment                | Data appears in unexpected location      | Verify `--env` flag in CLI or Environment Rules configuration                               |


# Parts

## Definition

A Part represents a reference to another Product's Version that is embedded or exists alongside the current Version. Parts enable hierarchical SBOM composition — modeling scenarios where a software artifact is assembled from multiple independently-managed components.

## Usage Scenarios

| Scenario                          | Description                                                                                                                 |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **Multi-module builds**           | A Java application with multiple Maven modules, each with its own SBOM, composed into a single Product Version.             |
| **Container layers**              | A container image composed of a base OS layer, middleware, and application, each managed as separate Products.              |
| **Microservice bundles**          | A deployment unit consisting of multiple microservices, each independently versioned, assembled into a single release SBOM. |
| **Hardware + firmware**           | An appliance Product composed of a hardware BOM and firmware SBOM from separate Product tracks.                             |
| **Embedded third-party software** | A Product that bundles an open-source component (e.g., OpenSSL, SQLite) managed as a separate Product.                      |

## How Parts Work

```
Product A - Version 1.0 (Parent SBOM)
  ├── Component: app-core v2.1
  ├── Component: app-utils v1.3
  └── Part: Product B - Version 3.0 (Child SBOM)
      ├── Component: lib-crypto v1.0
      └── Component: lib-network v2.2
```

When a Part is added to a Version:

1. The child SBOM's Components are included in the parent Version's component list.
2. Vulnerabilities from the child's Components are reflected in the parent Version.
3. Policy evaluation considers Components from both the parent and child SBOMs.
4. The parent can set its own VEX status for vulnerabilities inherited from Parts — allowing the parent Product's team to record their own assessment of a child Part's vulnerabilities independently from the child's own triage.

## Operational Considerations

* **Vulnerability rollups**: Vulnerabilities from Parts are aggregated into the parent Version. A critical vulnerability in a Part's component affects the parent Version's risk profile.
* **Health scoring**: The parent Version's health score incorporates data from all Parts. A poorly-scored Part will impact the parent's overall health.
* **Policy evaluation**: Policies can be configured to include or exclude Parts using the `exclude_parts` option on policy definitions.
* **"Always Use Latest Parts"** setting: When enabled, the parent Version automatically references the latest Version of each Part's source Product, keeping composition up to date without manual re-linking.

## Best Practices

* **Manage Parts as separate Products** when they have independent release cycles, teams, or compliance requirements.
* **Use the "Always Use Latest Parts" setting** in Environments where you want the composition to track the latest state of dependencies.
* **Set VEX status at the parent level** when a Part's vulnerability does not apply in the context of the parent Product — record your justification independently from the child Part's own triage.
* **Exclude Parts from policies** when the Part's source Product already has its own policy coverage and you want to avoid duplicate violations.


# Components

## Definition

A Component represents a unit of software — a library, package, framework, container, or application — that makes up a Product Version. Components are extracted from SBOMs during upload and enriched with data from open-source ecosystems and vulnerability databases.

## Component Types

The platform supports 14 component kinds:

| Kind                     | Description                  |
| ------------------------ | ---------------------------- |
| `library`                | Reusable software library    |
| `framework`              | Application framework        |
| `application`            | Standalone application       |
| `container`              | Container image              |
| `platform`               | Operating system or platform |
| `device`                 | Hardware device              |
| `device-driver`          | Device driver                |
| `firmware`               | Firmware binary              |
| `file`                   | Individual file              |
| `operating-system`       | Operating system             |
| `machine-learning-model` | ML model                     |
| `data`                   | Data asset                   |
| `cryptographic-asset`    | Cryptographic material       |

## Component Metadata

| Field                   | Description                                                         | Required |
| ----------------------- | ------------------------------------------------------------------- | -------- |
| **Name**                | Component name                                                      | Yes      |
| **Version**             | Component version                                                   | Yes      |
| **Type**                | Component kind (see above)                                          | Yes      |
| **PURL**                | Package URL — canonical identifier for package ecosystem lookup     | No       |
| **CPE**                 | Common Platform Enumeration — identifier for vulnerability matching | No       |
| **Supplier**            | Organization or individual that supplies the component              | No       |
| **License**             | SPDX license expression (e.g., `MIT`, `Apache-2.0 OR MIT`)          | No       |
| **Group**               | Component grouping (e.g., Maven groupId)                            | No       |
| **Scope**               | Usage scope (`required`, `optional`, `excluded`)                    | No       |
| **Description**         | Human-readable description                                          | No       |
| **Copyright**           | Copyright statement                                                 | No       |
| **Support Level**       | Maintenance status (see below)                                      | No       |
| **End-of-Support Date** | Date when support ends                                              | No       |
| **Primary**             | Whether this is the primary (top-level) component                   | No       |
| **Internal**            | Whether this is an internal (first-party) component                 | No       |

## Component Identification

Components are identified and matched to vulnerability databases using:

1. **PURL (Package URL)**: The primary identifier. Encodes ecosystem, namespace, name, version, and qualifiers. Example: `pkg:npm/@express/express@4.18.2`
2. **CPE (Common Platform Enumeration)**: Used for matching against NVD and other CVE databases. Example: `cpe:2.3:a:expressjs:express:4.18.2:*:*:*:*:node.js:*:*`

{% hint style="warning" %}
Components without PURL or CPE identifiers may not be matched against vulnerability databases. Ensure your SBOM generation tooling produces accurate identifiers.
{% endhint %}

## Component Support Levels

| Level                  | Description                                     |
| ---------------------- | ----------------------------------------------- |
| `actively_maintained`  | Component is actively developed and supported   |
| `no_longer_maintained` | Component is no longer receiving updates        |
| `abandoned`            | Component has been abandoned by its maintainers |
| `unspecified`          | Support status is unknown                       |

The platform can analyze component support status automatically when the **Run Component Support Analysis** setting is enabled.

## Component Enrichment

After upload, the platform enriches components with:

| Data Source                | Information Added                                                              |
| -------------------------- | ------------------------------------------------------------------------------ |
| **OpenSSF Scorecard**      | Security posture scoring for open-source projects                              |
| **Component Health Score** | Aggregated health metric based on maintenance, security, and community signals |
| **Package Insights**       | Deprecation status, archive status, download counts                            |
| **Version Insights**       | Whether the component version is outdated, latest available version            |
| **Source Code Insights**   | Repository activity, contributor metrics                                       |

## Component Relationships

Components can have dependency relationships:

* **Direct dependencies**: Components explicitly declared in the project manifest.
* **Transitive dependencies**: Components pulled in indirectly through direct dependencies.

The platform tracks these relationships as a dependency graph, which is visible in the Version's **Relations** tab.

## Querying Components

**Via CLI:**

```bash
# List vulnerabilities (includes component info)
pylynk vulns --prod "my-backend-service" --env "production" \
  --columns "component_name,component_version,severity,cvss"
```

**Via MCP:**

```
list_components        # List components with filtering by kind, direct dependencies
get_component          # Get component details with PURL, CPE, licenses
```

## Best Practices

* **Ensure accurate PURL and CPE identifiers.** Use mature SBOM generation tools (Syft, Trivy, CycloneDX CLI) that produce complete identifiers. Poor identifiers lead to missed vulnerability matches.
* **Label internal components.** Enable "Run Internal Labeling" so that first-party components are distinguished from third-party dependencies. This improves policy targeting and reduces false positives.
* **Monitor component support status.** Enable "Run Component Support Analysis" to identify abandoned or deprecated components before they become security liabilities.
* **Track transitive dependencies.** Vulnerabilities in transitive dependencies are just as exploitable as those in direct dependencies. Do not ignore them.
* **Review unknown components.** Components with no PURL, no CPE, and no supplier are difficult to track. Investigate and enrich them manually or improve your SBOM tooling.

## Common Misconfigurations

| Issue                                          | Symptom                                                              | Fix                                                                                   |
| ---------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| Missing PURL/CPE in SBOM                       | Components show zero vulnerabilities despite being known-vulnerable  | Improve SBOM generation tooling; use tools that produce complete identifiers          |
| Internal components flagged as vulnerable      | False positives from internal packages matching public package names | Enable Internal Labeling; configure policies to exclude internal components           |
| Transitive dependencies excluded from policies | Vulnerabilities in transitive deps not flagged                       | Review policy exclusions; remove `exclude_transitive_dependencies` unless intentional |
| Component support analysis disabled            | No deprecation/abandonment warnings                                  | Enable "Run Component Support Analysis" in Environment settings                       |


# Vulnerabilities

## Definition

A Vulnerability represents a known security issue that affects one or more Components in a Version. The platform maps vulnerabilities to Components using their identifiers (PURL, CPE) and correlates them against multiple vulnerability databases.

Each vulnerability record includes the CVE ID, severity, and description, and is scoped per organization. When a vulnerability is linked to a specific Component, additional context is tracked — including VEX status, fix availability, and custom CVSS adjustments.

## Source Databases

The platform aggregates vulnerability data from:

* **NVD** (National Vulnerability Database)
* **GitHub Security Advisories**
* **OSV** (Open Source Vulnerabilities)
* **Other ecosystem-specific databases**

## Vulnerability Mapping

```
Component (PURL/CPE) → Vulnerability Database Lookup → Affected Version Range Check → Vulnerability Record
```

The platform:

1. Extracts identifiers (PURL, CPE) from each Component.
2. Queries vulnerability databases for known issues.
3. Checks whether the Component's version falls within the affected version range.
4. Creates a vulnerability record linking the Component to the Vulnerability.

## Severity and Scoring

| Metric              | Description                                                                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **CVSS Score**      | Common Vulnerability Scoring System (v3.1). Base score from 0.0 to 10.0.                                                                                               |
| **CVSS Vector**     | Detailed attack vector string (e.g., `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`).                                                                                  |
| **Severity**        | Derived classification: Critical (9.0–10.0), High (7.0–8.9), Medium (4.0–6.9), Low (0.1–3.9).                                                                          |
| **EPSS Score**      | Exploit Prediction Scoring System — probability (0–1) that the vulnerability will be exploited in the wild within 30 days.                                             |
| **EPSS Percentile** | Relative ranking among all scored vulnerabilities.                                                                                                                     |
| **KEV**             | Whether the vulnerability appears in a known exploited vulnerabilities catalog. The flag is the union of the CISA KEV catalog and the ENISA EUVD known-exploited feed. |
| **CWE**             | Common Weakness Enumeration classification.                                                                                                                            |

### Custom Scoring Adjustments

Administrators can adjust vulnerability scoring per component:

* **Adjusted CVSS Score**: Override the base CVSS score based on organizational context.
* **Temporal Vector**: Apply temporal metrics (exploit maturity, remediation level).
* **Environmental Vector**: Apply environmental metrics specific to your deployment context.

## Vulnerability Lifecycle (VEX)

The platform supports the [Vulnerability Exploitability eXchange (VEX)](https://www.cisa.gov/resources-tools/resources/minimum-requirements-vulnerability-exploitability-exchange-vex) standard for tracking vulnerability disposition:

| Status                  | Description                                                                           |
| ----------------------- | ------------------------------------------------------------------------------------- |
| **Affected**            | The vulnerability applies to this component in this context. Remediation is required. |
| **Not Affected**        | The vulnerability does not apply. A justification must be provided.                   |
| **Under Investigation** | The applicability of the vulnerability is being assessed.                             |
| **Fixed**               | The vulnerability has been remediated.                                                |

When marking a vulnerability as **Not Affected**, a justification is required:

| Justification                                       | Meaning                                                                               |
| --------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `component_not_present`                             | The vulnerable component is not actually present.                                     |
| `vulnerable_code_not_present`                       | The specific vulnerable code path is not included.                                    |
| `vulnerable_code_not_in_execute_path`               | The vulnerable code exists but cannot be reached.                                     |
| `vulnerable_code_cannot_be_controlled_by_adversary` | The vulnerable code is present and reachable, but cannot be exploited by an attacker. |
| `inline_mitigations_already_exist`                  | Compensating controls are in place.                                                   |

## Querying Vulnerabilities

**Via CLI:**

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

# With full details
pylynk vulns --prod "my-backend-service" --vuln-details --vex-details --output json

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

# Export for compliance reporting
pylynk vulns --prod "my-backend-service" --env "production" \
  --vuln-details --vex-details --output csv > vuln-report.csv

# List all available column names
pylynk vulns --list-columns
```

**Via API:**

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { organization { projectGroups(first: 5) { nodes { name projects { nodes { name sboms(first: 1) { nodes { id componentVulns(first: 10) { nodes { vuln { vulnId sev cvssScore } component { name version } } } } } } } } } } }"
  }'
```

**Via MCP:**

```
list_vulnerabilities       # List vulnerabilities with severity/VEX/KEV filtering
get_vulnerability          # Get vulnerability by CVE ID or UUID
search_vulnerabilities     # Search vulnerabilities across all products
```

## Integration Impact

Vulnerabilities interact with other platform features:

| Feature              | Impact                                                                                                     |
| -------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Policies**         | Policies can trigger on vulnerability severity, EPSS score, KEV status, VEX status, and more.              |
| **Automation Rules** | Rules can auto-assign VEX status, create tickets, or send notifications based on vulnerability attributes. |
| **Ticketing**        | Jira/Linear tickets can be created automatically for new vulnerabilities matching policy conditions.       |
| **Notifications**    | Slack, Teams, and email notifications can be triggered for vulnerability events.                           |
| **Health Scoring**   | Open vulnerabilities reduce the Product/Version health score.                                              |
| **Compliance**       | Vulnerability disposition status affects compliance evaluations (NTIA, FDA, CRA).                          |

## Best Practices

* **Prioritize by exploitability, not just severity.** Use EPSS scores and KEV status to focus on vulnerabilities most likely to be exploited. A high-EPSS, KEV-listed medium-severity vulnerability may be more urgent than a critical vulnerability with no known exploit.
* **Triage systematically.** Establish a workflow: new vulnerabilities → under investigation → affected/not affected → fixed. Record justifications for all "not affected" dispositions.
* **Use environment-aware prioritization.** A vulnerability in a `production` Environment is more urgent than the same vulnerability in `development`. Configure policies accordingly.
* **Enable "Copy VEX Across Versions on Import"** to avoid re-triaging the same vulnerabilities when SBOMs are re-uploaded.
* **Use Custom Fields** to track organization-specific metadata (e.g., assigned engineer, remediation deadline, business impact assessment).
* **Review KEV-listed vulnerabilities immediately.** The KEV catalogs contain vulnerabilities known to be actively exploited. These should be remediated with the highest priority.
* **Automate ticket creation** for vulnerabilities that match your triage thresholds (e.g., critical severity + KEV = auto-create Jira ticket).

## Common Misconfigurations

| Issue                                    | Symptom                                                   | Fix                                                                                                      |
| ---------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Vulnerability scanning disabled          | No vulnerabilities appear after upload                    | Enable "Run Vulnerability Scan" in Environment settings                                                  |
| Components lack identifiers              | Known-vulnerable components show no vulnerabilities       | Improve SBOM tooling to produce PURL/CPE identifiers                                                     |
| VEX status not preserved across versions | Triage work lost on each upload                           | Enable "Retain Vulnerability Status with Version" and "Copy VEX Across Versions on Import"               |
| EPSS/KEV data missing                    | EPSS and KEV columns empty                                | EPSS/KEV enrichment is automatic; if missing, the vulnerability may be too new or not in the KEV catalog |
| Overly broad automation rules            | Non-critical vulnerabilities generating excessive tickets | Narrow rule conditions — target specific severities, EPSS thresholds, or KEV status                      |


# API Key Management

API keys authenticate programmatic access to the Interlynk platform — from CI/CD pipelines, the `pylynk` CLI, and direct API calls. Interlynk supports two token types: **user tokens** (tied to an individual) and **service tokens** (tied to an organization).

***

## Token Types

| Property         | User Token                                      | Service Token                                                               |
| ---------------- | ----------------------------------------------- | --------------------------------------------------------------------------- |
| Bound to         | Individual user account                         | Organization                                                                |
| Permissions      | Inherits user's role                            | Assigned a specific role at creation                                        |
| Creator tracking | N/A                                             | Records who created it (`creator_id`)                                       |
| Lifecycle        | Tied to user — invalidated when user is removed | Outlives the creator — persists even if the creator leaves the organization |
| Visibility       | Visible only to the owning user                 | Admins see all; non-admins see only tokens they created                     |
| Use case         | Personal CLI/API access                         | CI/CD pipelines, automation                                                 |
| Prefix           | `lynk_live_*`                                   | `lynk_service_*`                                                            |
| Limit            | No hard limit                                   | 100 per organization                                                        |

***

## Token Creation

### When to Create Tokens

* **User tokens**: For individual developers or security engineers interacting with the API or CLI during local development.
* **Service tokens**: For CI/CD pipelines, automated SBOM uploads, scheduled jobs, or any non-interactive access.

### Required Permissions

* Creating **user tokens** requires the `manage_api_tokens` permission.
* Creating **service tokens** requires the `manage_api_tokens` permission. Any user with this permission can create service tokens and select any role available in the organization.

### Token Scopes

* **User tokens** inherit the full permission set of the user's current organization role.
* **Service tokens** are assigned a specific organization role at creation time. The creator selects the role during creation — any role in the organization can be chosen regardless of the creator's own role. Choose the most restrictive role that satisfies the token's purpose.

### Expiration Best Practices

| Environment           | Recommended Expiration |
| --------------------- | ---------------------- |
| Development           | 30 days                |
| CI/CD pipelines       | 90 days                |
| Production automation | 90–180 days            |
| Temporary/one-off     | 24 hours or 7 days     |

Tokens without an expiration date remain valid until explicitly revoked. Avoid creating non-expiring tokens for CI/CD use.

### Security Considerations

{% hint style="warning" %}
The raw token value is displayed only once at creation time. It cannot be retrieved afterward. Copy it immediately and store it in a secrets manager.
{% endhint %}

* Tokens are stored as HMAC-SHA256 digests. Interlynk cannot recover a lost token.
* All token usage is tracked with a `last_used_at` timestamp.
* Revoked or expired tokens are rejected immediately on any API call.

### Creating a User Token (UI)

1. Navigate to **Settings > Personal > Security tokens**.
2. Click the **+** button and choose **Personal Token**.
3. Enter a descriptive **Token Name** (4–128 characters). Use a name that identifies the purpose, such as `ci-sbom-upload` or `local-dev`.
4. Optionally set an **Expiration Date**. Uncheck "No Expiration" to enable the date picker.
5. Click **Create**.
6. Copy the displayed token immediately. It will not be shown again.

### Creating a Service Token (UI)

1. Navigate to **Settings > Personal > Security tokens**.
2. Click the **+** button and choose **Service Token**.
3. Enter a **Token Name**.
4. Select a **Role** to assign to the token. This determines what the token can access.
5. Optionally set an **Expiration Date**.
6. Click **Create**.
7. Copy the displayed token immediately.

***

## Token Deletion

### Revoking Tokens

Revoking a token invalidates it immediately. Any API call or CLI command using a revoked token will receive a `401 Unauthorized` response.

**To revoke a user token:**

1. Navigate to **Settings > Personal > Security tokens**.
2. Click the action menu on the token row.
3. Select **Revoke**.

**To delete a service token:**

1. Navigate to **Settings > Personal > Security tokens**.
2. Click the action menu on the token row.
3. Select **Delete**.

### Impact Analysis

Before revoking a token, consider:

| Impact          | Details                                                                          |
| --------------- | -------------------------------------------------------------------------------- |
| CI/CD pipelines | Any pipeline using the token will fail on the next run                           |
| Scheduled jobs  | Automated SBOM uploads or downloads will stop                                    |
| Integrations    | Any webhook or external system authenticating with the token will lose access    |
| Other users     | Service tokens may be shared across teams — verify no other systems depend on it |

Check the token's `last_used_at` timestamp to determine if it is actively in use before revoking.

***

## Service Tokens

### User Token vs. Service Token

Use **service tokens** for any non-interactive, system-to-system access. Service tokens are bound to the organization, not the individual — they **outlive the creator**. If the team member who created a service token leaves the organization, the token continues to function with its assigned role.

Each service token tracks who created it. This enables:

* **Admins**: Full visibility — admins see all service tokens in the organization regardless of who created them, and can revoke or delete any token.
* **Non-admins**: Scoped visibility — non-admin users see only the service tokens they personally created, and can only manage their own.

Use **user tokens** only for personal, interactive use (local CLI sessions, ad hoc API calls).

### CI/CD Usage

Service tokens are the recommended authentication method for CI/CD pipelines:

```yaml
# GitHub Actions example
env:
  INTERLYNK_SECURITY_TOKEN: ${{ secrets.INTERLYNK_SERVICE_TOKEN }}

steps:
  - name: Upload SBOM
    run: pylynk upload --prod "my-app" --sbom sbom.json
```

```yaml
# GitLab CI example
variables:
  INTERLYNK_SECURITY_TOKEN: $INTERLYNK_SERVICE_TOKEN

upload_sbom:
  script:
    - pylynk upload --prod "my-app" --sbom sbom.json
```

### Least Privilege Recommendations

| Use Case                                             | Recommended Role                                           |
| ---------------------------------------------------- | ---------------------------------------------------------- |
| SBOM upload only                                     | Viewer (with upload permission) or custom upload-only role |
| SBOM upload + vulnerability review                   | Operator                                                   |
| Full automation (policy management, user management) | Admin (use sparingly)                                      |
| Read-only dashboards / reporting                     | Viewer                                                     |

Create a custom role with only the permissions required by the automation. Assign that role to the service token.

***

## Token Usage

### curl Example

Upload an SBOM using the Interlynk GraphQL API:

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { organization { projectGroups(first: 10) { totalCount nodes { id name } } } }"
  }'
```

**Successful response:**

```json
{
  "data": {
    "organization": {
      "projectGroups": {
        "totalCount": 3,
        "nodes": [
          { "id": "abc-123", "name": "my-app" }
        ]
      }
    }
  }
}
```

**Error response (invalid token):**

```json
{
  "errors": [
    { "message": "Authentication failed. Please check your token." }
  ]
}
```

### pylynk CLI Examples

**Set the API key via environment variable (recommended):**

```bash
export INTERLYNK_SECURITY_TOKEN="lynk_service_your_token_here"
```

**Upload an SBOM:**

```bash
pylynk upload --prod "my-app" --sbom ./sbom.cdx.json
```

**Upload to a specific environment:**

```bash
pylynk upload --prod "my-app" --env "production" --sbom ./sbom.cdx.json
```

**Download an enhanced SBOM:**

```bash
pylynk download --prod "my-app" --env "production" --ver "v1.2.0" \
  --out-file enhanced-sbom.json \
  --vuln true \
  --include-support-status true
```

**Download by version ID:**

```bash
pylynk download --verId "abc-123-def" --out-file sbom.json
```

**List products:**

```bash
pylynk prods --output json
```

**List vulnerabilities:**

```bash
pylynk vulns --prod "my-app" --vuln-details --vex-details --output json
```

***

## Best Practices

### Never Hardcode Tokens

Store tokens in a secrets manager or CI/CD secret store. Never commit tokens to source control.

```bash
# Correct — use environment variable
export INTERLYNK_SECURITY_TOKEN="$VAULT_SECRET"

# Incorrect — hardcoded in script
pylynk upload --token "lynk_service_abc123" --prod "my-app" --sbom sbom.json
```

### Rotation Strategy

1. Create a new token with the same role and permissions.
2. Update all systems (CI/CD pipelines, scripts, secrets managers) to use the new token.
3. Verify the new token is functioning by checking `last_used_at`.
4. Revoke the old token.

Rotate tokens on a regular schedule (every 90 days for production service tokens) and immediately if a token may have been exposed.

### Incident Response — Token Leak

If a token is leaked (committed to a public repo, logged in plaintext, exposed in a support ticket):

1. **Revoke immediately.** Navigate to the token management page and revoke or delete the token.
2. **Audit usage.** Check the token's `last_used_at` to determine if it was used after the leak.
3. **Create a replacement.** Issue a new token with the same role.
4. **Review scope.** If the leaked token had admin permissions, audit recent changes to the organization for unauthorized modifications.
5. **Rotate related secrets.** If the token was stored alongside other secrets, rotate those as well.

***

## Common Misconfigurations

| Issue                                      | Symptom                                                   | Fix                                                                                              |
| ------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Token passed via `--token` flag in CI logs | Token visible in build logs                               | Use `INTERLYNK_SECURITY_TOKEN` env var instead                                                   |
| Service token with Admin role              | Excessive permissions for automation                      | Create a custom role with minimum required permissions                                           |
| No expiration set on service tokens        | Tokens remain valid indefinitely                          | Set 90-day expiration and rotate proactively                                                     |
| Token created by a user who left           | Token still works but the creator is no longer in the org | Admins retain full visibility and can revoke orphaned service tokens; audit during offboarding   |
| Non-admin cannot find a service token      | Non-admins only see tokens they created                   | Ask an admin to locate and manage the token, or re-create it under your own account              |
| Wrong API URL                              | `401` or connection errors                                | Verify `INTERLYNK_API_URL` is set to `https://api.interlynk.io/lynkapi` (or omit to use default) |


# User Management

Interlynk uses an invitation-based team management model. Users are invited to an organization by email, assigned a role, and gain access after accepting the invitation.

***

## Inviting Team Members

### Role Assignment at Invite Time

When inviting a user, you can optionally assign a role. If no role is specified, the user receives the default role configured for the organization. Roles determine what the user can view and modify — see [Role Management](/administration/role-management) for the full permission matrix.

### Prerequisites

* You must have the `invite_users` permission (available to Admin and Operator roles by default).
* The invited user must have a valid email address.

### Step-by-Step: Invite a User

1. Navigate to **Settings > Organization > People & access > Users**.
2. Click **Add User**.
3. Enter the user's **Email** address.
4. Select a **Role** from the dropdown (Admin, Operator, Viewer, or any custom role).
5. Click **Invite**.

The user receives an email invitation with a link to accept.

### Email Verification Flow

1. The invited user receives an email with an invitation link containing a secure token.
2. The invitation token is valid for **48 hours**. After expiry, the invitation must be resent. The validity window is shown on the invitation email and on the invite, accept, and registration screens.
3. If the user already has an Interlynk account, they can accept the invitation and immediately access the organization.
4. If the user does not have an account, the invitation link directs them to complete registration before accepting.
5. Upon acceptance, the user's status changes from **Invited** to **Accepted**.

### Pending Invitations

Invitations that have not been accepted appear with a **Pending** status in the users table. You can:

* **Resend** the invitation if it expired or the user did not receive it.
* **Remove** the pending invitation to revoke access before acceptance.

***

## Changing Team Member Roles

### Permission Model Overview

Interlynk uses a role-based access control (RBAC) model. Each user in an organization is assigned exactly one role. Roles contain a set of permissions that govern access to features.

Role changes take effect immediately — the user's next API call or page load will reflect the new permissions.

### Who Can Change Roles

* **Admin** users can assign any role, including Admin.
* **Super admins** (platform-level) can update any role assignment.
* Non-admin users cannot change roles, even their own.

### Step-by-Step: Change a User's Role

1. Navigate to **Settings > Organization > People & access > Users**.
2. Locate the user in the table.
3. Click the action menu on the user's row.
4. Select **Change Role**.
5. Choose the new role from the dropdown.
6. Confirm the change.

### Audit Logging

Role changes are tracked in the platform's activity log. The log records:

* Who made the change
* The previous role
* The new role
* Timestamp of the change

***

## Removing Team Members

### Step-by-Step: Remove a User

1. Navigate to **Settings > Organization > People & access > Users**.
2. Locate the user in the table.
3. Click the action menu on the user's row.
4. Select **Remove**.
5. Confirm the removal.

{% hint style="info" %}
You cannot remove yourself from the organization.
{% endhint %}

### What Happens to Owned Assets

When a user is removed:

* The user loses access to the organization immediately.
* SBOMs, products, and other data created by the user remain in the organization — they are not deleted.
* API tokens (user tokens) associated with the removed user are no longer valid for the organization.
* Service tokens created by the user continue to function — they are bound to the organization and outlive their creator. Admins retain full visibility over these tokens and can revoke them if needed.

### Access Revocation Timing

Removal is a soft delete. The user's access is revoked immediately:

* Active sessions are invalidated.
* API tokens for the organization stop working.
* The user no longer appears in the organization's user list.

If the user is a member of other organizations, those memberships are unaffected.

### Offboarding Checklist

When a team member leaves your organization, follow this checklist:

* [ ] Remove the user from the organization in Interlynk.
* [ ] Review and revoke any **user tokens** created by the departing member.
* [ ] Audit **service tokens** — service tokens outlive their creator and continue to function. An admin should review the departing user's service tokens (visible to all admins) and revoke any that are no longer needed.
* [ ] If the user was an Admin, review recent activity logs for any configuration changes that should be audited.
* [ ] If SSO is enabled, remove the user from your identity provider as well to prevent re-authentication.
* [ ] Update any shared documentation that references the user's personal tokens or credentials.

***

## Common Misconfigurations

| Issue                                            | Symptom                                 | Fix                                                             |
| ------------------------------------------------ | --------------------------------------- | --------------------------------------------------------------- |
| Invitation expired                               | User clicks link and gets an error      | Resend the invitation from the Users page                       |
| Wrong role assigned                              | User can access features they shouldn't | Change the role immediately — takes effect on next request      |
| Removed user's service tokens still active       | Automated pipelines continue running    | Service tokens are org-bound — revoke them separately if needed |
| SSO user removed from Interlynk but not from IdP | User can re-authenticate via SSO        | Remove the user from your identity provider as well             |
| No admin remaining                               | Cannot manage organization              | Contact Interlynk support to restore admin access               |

***

## Recommended Best Practices

* Assign the **least privileged role** at invite time. Promote to higher roles only when needed.
* Use the **Viewer** role for stakeholders who need read-only access to dashboards and reports.
* **Audit your user list** quarterly — remove inactive users and verify role assignments.
* Prefer **SSO** for organizations with more than 10 users to centralize identity management.
* Use **service tokens** instead of personal tokens for shared automation to avoid dependency on individual team members.


# Organization Profile

The settings profile is split into two sections: an **organization profile** that applies to the whole organization, and a **personal profile** for your own user details.

***

## Organization Profile

Organization profile details are editable and apply across the organization. When no organization logo is set, the organization avatar shows a building icon.

## Personal Profile

The personal profile section holds your individual user details, separate from organization-wide settings.

***

For help with organization settings, contact <support@interlynk.io>.


# Role Management

Interlynk uses role-based access control (RBAC) to govern what users and service tokens can do within an organization. Three system roles are provided by default, and administrators can create custom roles with granular permissions.

***

## Default Roles

Interlynk ships with three system roles that cannot be modified or deleted:

| Role         | Description                                                                                                      |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| **Admin**    | Full access to all features and settings. Can manage users, roles, integrations, and organization configuration. |
| **Operator** | Can manage products, SBOMs, policies, integrations, and users. Cannot delete the organization or modify billing. |
| **Viewer**   | Read-only access to products, SBOMs, vulnerabilities, policies, and user lists. Cannot make changes.             |

{% hint style="warning" %}
Permissions associated with default roles Admin, Operator, and Viewer are read-only and cannot be modified.
{% endhint %}

### Permission Matrix

The table below lists all permissions and their assignment across default roles.

| Permission                                    | Admin | Operator | Viewer |
| --------------------------------------------- | :---: | :------: | :----: |
| **Organization**                              |       |          |        |
| View organization                             |   ✓   |     ✓    |    ✓   |
| Update organization                           |   ✓   |     —    |    —   |
| Delete organization                           |   ✓   |     —    |    —   |
| **Products**                                  |       |          |        |
| View products                                 |   ✓   |     ✓    |    ✓   |
| Create products                               |   ✓   |     ✓    |    —   |
| Update products                               |   ✓   |     ✓    |    —   |
| Delete products                               |   ✓   |     ✓    |    —   |
| Edit share link                               |   ✓   |     ✓    |    —   |
| Edit product automations                      |   ✓   |     ✓    |    —   |
| Edit product policies                         |   ✓   |     ✓    |    —   |
| Edit product integrations                     |   ✓   |     ✓    |    —   |
| Edit product settings                         |   ✓   |     ✓    |    —   |
| **SBOMs**                                     |       |          |        |
| View SBOMs                                    |   ✓   |     ✓    |    ✓   |
| Update SBOMs                                  |   ✓   |     ✓    |    —   |
| Delete SBOMs                                  |   ✓   |     ✓    |    —   |
| Edit SBOM components                          |   ✓   |     ✓    |    —   |
| Edit vulnerabilities                          |   ✓   |     ✓    |    —   |
| Edit checks                                   |   ✓   |     ✓    |    —   |
| Sign SBOMs                                    |   ✓   |     ✓    |    —   |
| Reprocess SBOMs                               |   ✓   |     ✓    |    —   |
| **Users**                                     |       |          |        |
| View users                                    |   ✓   |     ✓    |    ✓   |
| Invite users                                  |   ✓   |     ✓    |    —   |
| Edit user roles                               |   ✓   |     ✓    |    —   |
| Edit teams                                    |   ✓   |     ✓    |    —   |
| Delete users                                  |   ✓   |     ✓    |    —   |
| **Vulnerabilities**                           |       |          |        |
| View vulnerabilities (`view_vulnerabilities`) |   ✓   |     ✓    |    ✓   |
| View feeds                                    |   ✓   |     ✓    |    ✓   |
| Manage feeds                                  |   ✓   |     ✓    |    —   |
| Manage lists                                  |   ✓   |     ✓    |    —   |
| Manage custom fields                          |   ✓   |     ✓    |    —   |
| **Licenses**                                  |       |          |        |
| View licenses                                 |   ✓   |     ✓    |    ✓   |
| Edit licenses                                 |   ✓   |     ✓    |    —   |
| **Policies**                                  |       |          |        |
| View policies                                 |   ✓   |     ✓    |    ✓   |
| Edit policies                                 |   ✓   |     ✓    |    —   |
| Run policy scans                              |   ✓   |     ✓    |    —   |
| Delete policies                               |   ✓   |     ✓    |    —   |
| **Support**                                   |       |          |        |
| View support                                  |   ✓   |     ✓    |    ✓   |
| Edit support                                  |   ✓   |     ✓    |    —   |
| Delete support                                |   ✓   |     ✓    |    —   |
| View support levels                           |   ✓   |     ✓    |    ✓   |
| Edit support levels                           |   ✓   |     ✓    |    —   |
| Delete support levels                         |   ✓   |     ✓    |    —   |
| **Vendor Management**                         |       |          |        |
| View requests                                 |   ✓   |     ✓    |    ✓   |
| Edit requests                                 |   ✓   |     ✓    |    —   |
| **Connections**                               |       |          |        |
| View connections                              |   ✓   |     ✓    |    ✓   |
| Edit connections                              |   ✓   |     ✓    |    —   |
| Delete connections                            |   ✓   |     ✓    |    —   |
| **Notifications**                             |       |          |        |
| View notification settings                    |   ✓   |     ✓    |    ✓   |
| Edit notification settings                    |   ✓   |     ✓    |    —   |
| **API Tokens**                                |       |          |        |
| View API tokens                               |   ✓   |     ✓    |    ✓   |
| Manage API tokens (`manage_api_tokens`)       |   ✓   |     ✓    |    —   |

{% hint style="warning" %}
`view_vulnerabilities` gates vulnerability and VEX exports, download options, and the Copy VEX action. Unlike other view permissions, it is **not** granted automatically to every role. The built-in Admin, Operator, and Viewer roles include it, but a custom role must list it explicitly or those users will see vulnerability data on screen with the export and download actions hidden.
{% endhint %}

{% hint style="info" %}
`manage_api_tokens` is a dedicated permission decoupled from `update_organization`. This means Operator and Developer roles can create and manage API tokens — including service tokens — without requiring full organization settings access. Assign this permission to CI/CD roles that need to rotate tokens but should not have access to org-level configuration.
{% endhint %}

### Use Cases for Default Roles

| Role         | Typical User                                             |
| ------------ | -------------------------------------------------------- |
| **Admin**    | Security team leads, platform owners, DevOps managers    |
| **Operator** | AppSec engineers, DevOps engineers, release managers     |
| **Viewer**   | Developers, compliance auditors, management stakeholders |

**Viewer capabilities note:** Viewers can access SBOM relationships, component relationship actions, and support level data in read-only mode. They can also edit their personal notification preferences. They cannot modify SBOMs, policies, vulnerabilities, or organization settings.

***

## Custom Roles

Custom roles allow you to define granular permission sets beyond the three defaults. Use custom roles to implement least-privilege access patterns.

### Creating Custom Roles

1. Navigate to **Settings > Organization > People & access > Roles**.
2. Click **Create Role**.
3. Enter a **Name** for the role (minimum 4 characters). Use a descriptive name like `AppSec Reviewer` or `CI Upload Agent`.
4. Select **Copy Permission From** to start with an existing role's permissions as a baseline.
5. Click **Create**.

The new role is created with the copied permission set. You can then adjust individual permissions as needed.

{% hint style="info" %}
Role names must be unique within the organization (case-insensitive).
{% endhint %}

### Deleting Custom Roles

1. Navigate to **Settings > Organization > People & access > Roles**.
2. Click the action menu on the role's row.
3. Select **Delete**.

{% hint style="warning" %}
Before deleting a custom role, reassign any users or service tokens that use it. Users with a deleted role will lose access until reassigned.
{% endhint %}

### Granular Permission Selection

Permissions are organized into categories. When creating or editing a custom role, select only the permissions required for the role's purpose. Refer to the permission matrix above for available permissions.

### Recommended Patterns

| Custom Role           | Permissions                                                                                                                       | Use Case                                                                        |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **AppSec Reviewer**   | View organization, View products, View SBOMs, View policies, View vulnerabilities, Edit vulnerabilities, View feeds, Manage feeds | Security analyst who triages vulnerabilities but does not manage infrastructure |
| **Compliance Viewer** | View organization, View products, View SBOMs, View policies, View licenses, View vulnerabilities, View feeds                      | Auditor or compliance officer with read-only access                             |
| **CI Upload Agent**   | View products, Create products, Update SBOMs, View API tokens, Manage API tokens                                                  | Service token role for CI/CD pipelines that only upload SBOMs                   |
| **Policy Manager**    | View organization, View products, View SBOMs, View policies, Edit policies, Run policy scans, Delete policies                     | User responsible for defining and maintaining security policies                 |
| **Integration Admin** | View organization, View connections, Edit connections, Delete connections, View notification settings, Edit notification settings | User responsible for managing integrations and notifications                    |

### Bulk Role Assignment

To assign a role to multiple users at once, use the **Bulk Apply** feature:

1. Navigate to **Settings > Organization > People & access > Roles**.
2. Select a role.
3. Use the bulk apply action to assign the role to selected users.

***

## Common Misconfigurations

| Issue                                      | Symptom                                                      | Fix                                                                   |
| ------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------------------- |
| Custom role missing critical permission    | User cannot perform expected action                          | Review the permission matrix and add the missing permission           |
| Custom role missing `view_vulnerabilities` | Vulnerability and VEX export and download actions are hidden | Add View Vulnerabilities to the role; it is not granted automatically |
| Service token assigned Admin role          | Excessive permissions for automation                         | Create a minimal custom role and reassign the token                   |
| All users assigned Admin                   | No effective access control                                  | Implement role separation — most users should be Operators or Viewers |
| Custom role deleted while in use           | Affected users lose all access                               | Reassign users to another role before deleting                        |
| Role name too short                        | Creation fails with validation error                         | Use at least 4 characters for role names                              |

***

## Recommended Best Practices

* Start with the **Viewer** role and add permissions incrementally — it is easier to grant access than to revoke it.
* Create **dedicated service token roles** with only the permissions CI/CD pipelines need (e.g., SBOM upload and product view).
* Review role assignments **quarterly** as part of your security hygiene.
* Use **descriptive role names** that communicate purpose (e.g., `Release Engineer` rather than `Custom Role 1`).
* Document your custom roles and their intended use cases in your team's runbook.
* Avoid creating too many custom roles — consolidate where possible to reduce management overhead.


# Integrations

Interlynk integrates with source control platforms, issue trackers, and messaging tools to embed SBOM management and vulnerability tracking into your existing workflows.

***

## Overview

| Integration                                        | Type           | Purpose                                                              |
| -------------------------------------------------- | -------------- | -------------------------------------------------------------------- |
| [GitHub](/administration/github)                   | Source Control | Repository webhooks for automated SBOM ingestion on push/PR events   |
| [GitLab](/administration/gitlab)                   | Source Control | Repository webhooks for automated SBOM ingestion on push/MR events   |
| [Bitbucket](/administration/bitbucket)             | Source Control | Repository webhooks for automated SBOM ingestion on push/PR events   |
| [Jira](/administration/jira)                       | Issue Tracking | Bidirectional vulnerability ticket management with VEX field sync    |
| [Linear](/administration/linear)                   | Issue Tracking | Vulnerability ticket creation and tracking                           |
| [Slack](/administration/slack)                     | Messaging      | Real-time notifications for vulnerability, policy, and upload events |
| [Microsoft Teams](/administration/microsoft-teams) | Messaging      | Real-time notifications via incoming webhooks                        |
| [Email](/administration/email)                     | Messaging      | Notification delivery to individual or shared mailboxes              |

## Permissions Required

Managing integrations requires the following permissions:

| Action                     | Required Permission  |
| -------------------------- | -------------------- |
| View integrations          | `view_connections`   |
| Create/update integrations | `edit_connections`   |
| Delete integrations        | `delete_connections` |

## Integration Health

Interlynk periodically checks the health of configured integrations. Each integration shows:

* **Health Status**: Whether the connection is active and functional.
* **Last Checked**: Timestamp of the most recent health check.

If an integration shows an unhealthy status, verify your credentials and network connectivity, then re-test the connection.

## Security Considerations

* All integration credentials (API tokens, webhook URLs, OAuth tokens) are encrypted at rest.
* OAuth tokens are automatically refreshed when they expire.
* Use the most restrictive scopes and permissions when connecting external services.
* Regularly audit which integrations are connected to your organization.


# GitHub

The GitHub integration connects Interlynk to your GitHub repositories, enabling automated SBOM processing triggered by repository events.

***

## Purpose

* Automatically ingest SBOMs when code is pushed or pull requests are created/merged.
* Map repository branches to Interlynk environments using environment rules.
* Enable PR comments with SBOM analysis results.

## Setup Steps

### GitHub App (Recommended)

Interlynk uses a GitHub App for OAuth-based authentication. This provides fine-grained repository access without personal access tokens.

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **GitHub**.
3. You will be redirected to GitHub to authorize the Interlynk GitHub App.
4. Select the **repositories** or **organization** to grant access to.
5. Complete the authorization. You will be redirected back to Interlynk.
6. The integration displays your GitHub **username** and connection status.

### Repository Selection

After authorization, configure which repositories trigger SBOM processing:

* Set up **environment rules** (see [Environment Rules](/administration/environment-rules)) to map branches to Interlynk environments.
* Configure webhook triggers for the events you want to respond to.

## Supported Events

| Event                    | Trigger                               |
| ------------------------ | ------------------------------------- |
| `push`                   | Code pushed to a branch               |
| `pull_request` (created) | New pull request opened               |
| `pull_request` (merged)  | Pull request merged                   |
| `pull_request` (updated) | Pull request updated with new commits |

## Required Permissions

The GitHub App requests the following permissions:

| Scope                      | Purpose                                |
| -------------------------- | -------------------------------------- |
| Repository contents (read) | Read SBOM files from repositories      |
| Pull requests (read/write) | Post PR comments with analysis results |
| Webhooks (read/write)      | Receive push and PR events             |

## Security Notes

* The OAuth connection uses token refresh — tokens are automatically re-issued when they expire.
* Interlynk stores only the OAuth token, not your GitHub password.
* You can revoke access at any time from GitHub's **Settings > Applications > Authorized GitHub Apps**.

## Troubleshooting

| Issue                       | Cause                                                  | Resolution                                                 |
| --------------------------- | ------------------------------------------------------ | ---------------------------------------------------------- |
| Webhook events not received | GitHub App not installed on the repository             | Verify the app is installed and the repository is selected |
| PR comments not appearing   | Missing pull request write permission                  | Re-authorize the GitHub App with the correct permissions   |
| OAuth token expired         | Token refresh failed                                   | Disconnect and reconnect the GitHub integration            |
| Wrong repositories visible  | App installed at organization level with limited repos | Update repository access in GitHub App settings            |


# GitLab

The GitLab integration connects Interlynk to your GitLab groups and projects, enabling automated SBOM processing triggered by repository events.

***

## Purpose

* Automatically ingest SBOMs on push and merge request events.
* Map GitLab branches to Interlynk environments.
* Support both GitLab.com (SaaS) and self-managed GitLab instances.

## Setup Steps

Interlynk connects to GitLab via OAuth.

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **GitLab**.
3. You will be redirected to GitLab to authorize the Interlynk application.
4. Complete the authorization.
5. After redirect, select the **Workspace/Group** from the dropdown to scope the integration.
6. Click **Save**.

### Group vs. Project Setup

* **Group-level**: Grants access to all projects within the group. Recommended for organizations that want full coverage.
* **Project-level**: Limit the integration to specific projects by selecting the appropriate group and configuring environment rules per project.

## Supported Events

| Event                     | Trigger                  |
| ------------------------- | ------------------------ |
| `push`                    | Code pushed to a branch  |
| `merge_request` (created) | New merge request opened |
| `merge_request` (merged)  | Merge request merged     |
| `merge_request` (updated) | Merge request updated    |

## Required Permissions

The OAuth application requests:

| Scope              | Purpose                                  |
| ------------------ | ---------------------------------------- |
| `read_repository`  | Access repository contents               |
| `read_api`         | Query project and group metadata         |
| `write_repository` | Post merge request comments (if enabled) |

## Security Notes

* OAuth tokens are encrypted at rest and automatically refreshed on expiry.
* For self-managed GitLab instances, verify your instance URL is accessible from the Interlynk platform.
* Revoke access from GitLab's **User Settings > Applications** if needed.

## Troubleshooting

| Issue                             | Cause                               | Resolution                                                           |
| --------------------------------- | ----------------------------------- | -------------------------------------------------------------------- |
| No groups visible after auth      | Token scope too narrow              | Re-authorize with broader group access                               |
| Events not triggering             | Webhook not registered on project   | Verify the workspace/group selection matches your target projects    |
| Self-managed instance unreachable | Network/firewall restriction        | Ensure your GitLab instance is accessible from Interlynk's IP ranges |
| Token refresh failures            | OAuth application revoked on GitLab | Disconnect and reconnect the integration                             |


# Bitbucket

The Bitbucket integration connects Interlynk to your Bitbucket workspaces, enabling automated SBOM processing triggered by repository events.

***

## Purpose

* Automatically ingest SBOMs on push and pull request events from Bitbucket repositories.
* Map Bitbucket branches to Interlynk environments.

## Setup Steps

Interlynk connects to Bitbucket via OAuth.

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **Bitbucket**.
3. You will be redirected to Bitbucket to authorize the Interlynk application.
4. Complete the authorization.
5. After redirect, select the **Workspace** from the dropdown.
6. Click **Save**.

## Supported Events

| Event                   | Trigger                 |
| ----------------------- | ----------------------- |
| `repo:push`             | Code pushed to a branch |
| `pullrequest:created`   | New pull request opened |
| `pullrequest:fulfilled` | Pull request merged     |
| `pullrequest:updated`   | Pull request updated    |

## Required Scopes

| Scope              | Purpose                                 |
| ------------------ | --------------------------------------- |
| Repository read    | Access repository contents and metadata |
| Pull request read  | Read pull request details               |
| Webhook read/write | Register and manage webhooks            |

## Security Notes

* OAuth tokens are encrypted at rest and refreshed automatically.
* The integration only accesses repositories within the selected workspace.
* Revoke access from Bitbucket's **Personal Settings > App authorizations** if needed.

## Troubleshooting

| Issue                            | Cause                                | Resolution                                             |
| -------------------------------- | ------------------------------------ | ------------------------------------------------------ |
| No workspaces visible            | OAuth scope too narrow               | Re-authorize the Bitbucket integration                 |
| Push events not triggering       | Webhook not registered on repository | Verify workspace selection and re-save the integration |
| Token expired and not refreshing | Refresh token revoked                | Disconnect and reconnect the Bitbucket integration     |


# Jira

The Jira integration provides enterprise-grade, bidirectional vulnerability management between Interlynk and Jira. It supports automatic ticket creation, VEX field synchronization, and status tracking across both platforms.

***

## Purpose

* Create Jira tickets for vulnerabilities discovered in SBOMs — manually or automatically via policy violations.
* Synchronize VEX (Vulnerability Exploitability eXchange) status bidirectionally between Interlynk and Jira.
* Map vulnerability severity to Jira priority and custom fields.
* Track remediation progress across both platforms.

***

## Setup Steps

### Step 1: Connect Jira

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **Jira**.
3. Enter the following:
   * **Jira Host URL**: Your Jira instance URL (e.g., `https://yourcompany.atlassian.net`).
   * **User Email**: The email of the Jira user account that Interlynk will use.
   * **API Token**: A Jira API token generated for the user account.
4. Click **Verify** to test the connection.
5. On success, the verification panel displays: account name, account ID, account type, Jira URL, version, deployment type, and server title.
6. Click **Save**.

### Step 2: Provision Vulnerability Management

After connecting Jira, set up the vulnerability management configuration to enable custom field mapping and bidirectional sync.

1. Navigate to **Settings > Organization > Integrations > Connections > Jira Vulnerability Management**.
2. Click **Initialize**.
3. Interlynk provisions the following resources in your Jira instance (8-step process):
   1. Custom issue type (`InterlynkVuln`)
   2. Issue type scheme
   3. Custom fields (11 VEX-related fields)
   4. Workflow
   5. Workflow scheme
   6. Screen with fields
   7. Screen scheme
   8. Issue type screen scheme
4. Wait for provisioning to complete. Status is displayed as **In Progress**, **Completed**, or **Failed** (with the specific step that failed).

### Step 3: Associate Jira Projects

After provisioning, associate Jira projects with the vulnerability management configuration:

1. Select the Jira **project** from the dropdown.
2. The issue type scheme and screen scheme are applied to the project.
3. Repeat for each project that should receive vulnerability tickets.

### Step 4: Configure Per-Product Settings

For each Interlynk product that should create Jira tickets:

1. Navigate to **Settings > Organization > Integrations > Ticketing**.
2. Locate the product and expand its settings.
3. Configure:
   * **Jira Project**: The target Jira project for tickets.
   * **Work Type (Issue Type)**: Select from issue types available in your Jira project. Interlynk queries your Jira project's create metadata and only renders issue types that project actually supports. Select **InterlynkVuln** for full VEX field support (requires provisioning to be completed first).
   * **Epic**: Link new tickets to an existing Jira Epic (optional). The dropdown lists Epics in the selected project.
   * **Default Assignee**: The Jira user who receives new tickets (optional).
   * **Default Reporter**: The Jira user listed as reporter (optional, required by some Jira projects).
   * **Components**: Route tickets to specific Jira Components within the project (optional). The field appears only when the selected project and issue type support a Components field.
   * **Bi-directional Sync**: Toggle two-way synchronization between Jira and Interlynk.

### Step 5: Test Your Integration

After configuring per-product settings, create a test ticket to verify the connection and field mapping before enabling automatic ticket creation:

1. In the per-product Jira settings, ensure **Project** and **Work Type** are selected.
2. Click **Create Test Ticket**.
3. A sample ticket is created in Jira using the current configuration. Verify it appears in the correct project with the expected fields populated.
4. To test specific field mappings without saving them, pass Jira field overrides when sending the test ticket. Inline-selected fields are reflected in the created test ticket, so you can confirm a mapping before applying it to the saved configuration.
5. Delete the test ticket from Jira after verification.

***

## Ticket Creation

### Manual Ticket Creation

Create Jira tickets for individual or multiple vulnerabilities:

1. Navigate to a product's vulnerability view.
2. Select one or more vulnerabilities.
3. Click **Create Jira Issue**.
4. The issue creation modal displays:
   * Pre-populated fields based on the vulnerability (summary, description, severity, affected package).
   * Standard fields: project, issue type, assignee, reporter, priority, labels.
   * VEX fields: status, justification, action response, impact statement, notes, action statement.
5. Click **Create** to submit.

**Bulk creation** supports up to 50 issues per request.

### Ticket Title Format

Auto-created tickets use the format:

```
Policy Violation: <product-name> (<environment>): <vulnerability-id> in <package-name>
```

This makes it immediately clear which product and environment the violation came from without opening the ticket.

### Automatic Ticket Creation

Automatic ticket creation is driven by **policy violations**:

1. Define a policy with vulnerability conditions and enable **Create Ticket** on the policy.
2. When a policy scan produces violations, the `BulkAutoTicketCreationJob` processes them.
3. Tickets are created in batches of 50 per Jira project.
4. Each violation is linked to its Jira ticket. Duplicate tickets are not created for existing links.

Policy-driven tickets use the Jira configuration of the product context the violation came from, rather than a single organization-wide setting.

***

## Ticket Reuse

The same vulnerability usually reappears when a new SBOM version is uploaded, and often in a second Environment of the same Product. Rather than opening a fresh ticket each time, Interlynk can link the existing one.

Two Environment settings control this, both on the Environment's **Settings > Import & defaults > Version lifecycle** page:

| Setting                                             | Scope                                       | Default |
| --------------------------------------------------- | ------------------------------------------- | ------- |
| **Reuse Jira tickets for matching vulnerabilities** | Other SBOM versions in the same Environment | On      |
| **Reuse Jira tickets across environments**          | Other Environments of the same Product      | Off     |

Cross-Environment reuse has additional conditions:

* The setting is Product-wide. Toggling it writes the same value to every Environment in the Product, and reuse only applies when all of them agree.
* The source and destination Environments must point at the **same Jira project**. Environments configured against a different Jira project are skipped.

When a ticket is reused, the reused issue is updated with the SBOM versions it now covers, and stale links from deleted or superseded SBOMs are cleared first so a ticket is never linked to a version that no longer exists.

### Audit Trail

Each reuse is recorded on the vulnerability's Change Log as an `existing_jira_ticket_linked` entry, naming the issue key and the Environment and version it was reused from.

***

## Field Mapping

### Standard Fields

| Interlynk Field  | Jira Field            | Notes                                                                 |
| ---------------- | --------------------- | --------------------------------------------------------------------- |
| Vulnerability ID | Summary (title)       | Format: `Policy Violation: <product> (<env>): <vuln-id> in <package>` |
| Description      | Description           | Includes component details, severity level, and CVSS score            |
| Severity         | Priority              | Mapped via priority mapping (see below)                               |
| Affected package | Labels / Custom field | Configurable                                                          |
| SBOM version     | Affected Versions     | Automatically included from SBOM metadata                             |
| Components       | Jira Components       | Routes to the Jira component(s) configured in product settings        |

### VEX Custom Fields

The following VEX fields are synced bidirectionally as Jira custom fields:

| Custom Field             | Type   | Description                                                                                                                      |
| ------------------------ | ------ | -------------------------------------------------------------------------------------------------------------------------------- |
| Vulnerability ID         | Text   | CVE or vulnerability identifier                                                                                                  |
| Affected Package         | Text   | Package name                                                                                                                     |
| Affected Package Version | Text   | Package version                                                                                                                  |
| VEX Status               | Select | `affected`, `not_affected`, `fixed`, `in_triage`                                                                                 |
| VEX Justification        | Select | `code_not_reachable`, `code_not_present`, `requires_configuration`, `requires_dependency`, and more                              |
| VEX Action Response      | Select | `can_not_fix`, `will_not_fix`, `update`, `rollback`, `workaround_available`                                                      |
| VEX Impact Statement     | Text   | Freeform impact description                                                                                                      |
| VEX Internal Notes       | Text   | Internal team notes                                                                                                              |
| VEX Action Statement     | Text   | Remediation action description — also pushed to Jira when updated in Interlynk                                                   |
| CVSS Score               | Number | CVSS vulnerability score                                                                                                         |
| Severity                 | Select | `critical`, `high`, `medium`, `low`                                                                                              |
| EPSS Score               | Number | Exploit Prediction Scoring System score                                                                                          |
| Fix Available            | Select | Whether a fix is available. Set automatically to `Yes` when the advisory lists a fixed version for the component, otherwise `No` |
| Interlynk SBOM Link      | URL    | Link back to the SBOM in Interlynk                                                                                               |

### Severity to Priority Mapping

| Interlynk Severity | Jira Priority |
| ------------------ | ------------- |
| Critical           | Highest       |
| High               | High          |
| Medium             | Medium        |
| Low                | Low           |
| Unknown            | Lowest        |

***

## Bidirectional Synchronization

### Jira to Interlynk (Pull Sync)

Interlynk polls Jira on a schedule to pull updates from Jira tickets back into vulnerability records.

**What syncs from Jira to Interlynk:**

* VEX Status changes
* VEX Justification updates
* VEX Action Response
* Impact and action statements
* Internal notes

**How it works:**

1. The `JiraVulnSyncJob` runs on a schedule for organizations with the feature enabled.
2. The job fetches Jira tickets in batches of 50 using JQL queries.
3. For each ticket, the sync handler compares field values between Jira and Interlynk.
4. Changed fields are applied to the corresponding Interlynk vulnerability record.
5. A `ComponentVulnLog` entry is created for audit purposes.

**Manual sync:** You can trigger an immediate sync from **Settings > Organization > Integrations > Ticketing** by clicking the sync button.

### Interlynk to Jira (Push Sync)

When VEX dispositions are updated in Interlynk, changes are pushed to the corresponding Jira ticket.

**What syncs from Interlynk to Jira:**

* VEX Status
* VEX Justification
* VEX Action Response
* Impact and action statements
* A comment is added to the Jira ticket documenting the change

**How it works:**

1. When a vulnerability disposition is updated in Interlynk, the `JiraVexPushJob` is triggered.
2. The reverse field mapper converts Interlynk values to Jira custom field option IDs.
3. The Jira ticket is updated via the Jira REST API.
4. A comment is added to the ticket for audit trail.

### Sync Configuration

| Setting                   | Description                                       |
| ------------------------- | ------------------------------------------------- |
| Enable Sync (per product) | Toggles bidirectional sync for a specific product |
| Last Synced At            | Timestamp of the most recent sync                 |
| Last Sync Status          | Success or failure (with error details)           |

{% hint style="info" %}
Bidirectional sync works across all configured Jira issue types, not just **InterlynkVuln**. If you use standard issue types (task, bug, story), VEX field sync operates on whichever custom fields those issue types expose.
{% endhint %}

***

## Organization-Level Jira Defaults

Set default Jira configuration for all products in the organization, so new products inherit sensible settings without manual per-product configuration:

1. Navigate to **Settings > Organization > Environments > Defaults**.
2. Find the **Jira Defaults** section.
3. Configure defaults for: Project, Work Type (Issue Type), Epic, Assignee, Reporter, and Components.
4. Choose whether to apply defaults to **all existing projects** or only **future projects**.

Per-product settings override organization defaults. If a product has no Jira configuration set, it inherits the organization defaults.

***

## Required Permissions

### Jira User Permissions

The Jira user account used for the integration requires:

| Permission             | Purpose                                                         |
| ---------------------- | --------------------------------------------------------------- |
| Browse Projects        | Read project metadata and issue types                           |
| Create Issues          | Create vulnerability tickets                                    |
| Edit Issues            | Update ticket fields during sync                                |
| Add Comments           | Add sync comments to tickets                                    |
| Manage Schemes (Admin) | Required for provisioning custom fields, workflows, and schemes |

### Interlynk Permissions

| Permission           | Purpose                                |
| -------------------- | -------------------------------------- |
| `view_connections`   | View Jira integration settings         |
| `edit_connections`   | Configure Jira connection and settings |
| `delete_connections` | Remove the Jira integration            |

### Permission Health Checks

Interlynk proactively checks the Jira user's permissions and reports any that are missing, so integration failures surface early rather than during ticket creation or sync.

***

## Security Notes

* Jira API tokens are encrypted at rest.
* The integration uses Jira REST API v3 — no webhooks are required. All synchronization is poll-based.
* Use a **dedicated Jira service account** rather than a personal account to avoid disruption if a team member leaves.
* Grant the Jira service account only the permissions listed above.
* The provisioning step creates resources in your Jira instance — coordinate with your Jira admin before initializing.

***

## Troubleshooting

| Issue                                      | Cause                                                           | Resolution                                                                                 |
| ------------------------------------------ | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| Connection verification fails              | Invalid URL, email, or API token                                | Re-check the Jira Host URL, email, and generate a new API token                            |
| Provisioning fails at a step               | Insufficient Jira admin permissions                             | Ensure the Jira user has scheme management permissions                                     |
| Tickets not created automatically          | Policy does not have "Create Ticket" enabled                    | Enable the flag on the policy and ensure the product has a Jira project configured         |
| Sync not updating Interlynk                | Sync disabled for the product                                   | Enable sync in the ticketing settings for the product                                      |
| VEX fields missing on Jira ticket          | Provisioning not completed                                      | Complete the provisioning process or re-initialize                                         |
| Duplicate tickets                          | Multiple policies triggering for the same vulnerability         | Consolidate policies or use exclusion rules                                                |
| Sync shows errors                          | Jira API rate limits or network issues                          | Check the `last_sync_status` for error details; retry later                                |
| Components field not appearing in settings | Selected project or issue type does not have a Components field | Verify the Jira project has a Components field enabled for the chosen issue type           |
| Test ticket creation disabled              | No project or issue type selected                               | Select both Project and Work Type before using Create Test Ticket                          |
| Duplicate Jira connection                  | Attempting to add a second Jira connection for the same org     | Only one Jira connection is allowed per organization; edit the existing connection instead |

***

## Common Misconfigurations

| Issue                                 | Symptom                                         | Fix                                                             |
| ------------------------------------- | ----------------------------------------------- | --------------------------------------------------------------- |
| Personal Jira account used            | Integration breaks when employee leaves         | Use a dedicated service account                                 |
| Jira project not associated           | Tickets fail to create                          | Associate the Jira project with vulnerability management config |
| Issue type not configured per product | Default issue type may not have required fields | Configure the correct issue type in ticketing settings          |
| Sync enabled but no project key set   | Sync job runs but finds nothing to sync         | Set the Jira project key for each product                       |

***

## Recommended Best Practices

* Use a **dedicated Jira service account** with scoped permissions.
* Enable **bidirectional sync** only for products actively being triaged — unnecessary sync adds API load.
* Use the **InterlynkVuln** issue type (created during provisioning) for full VEX field support.
* Configure **automatic ticket creation** via policies to reduce manual effort for high-severity vulnerabilities.
* Review **sync status** regularly in the ticketing settings to catch failed syncs early.
* Coordinate with your Jira admin before provisioning to avoid conflicts with existing schemes.


# Linear

The Linear integration connects Interlynk to your Linear workspace for vulnerability ticket creation and tracking.

***

## Purpose

* Create Linear issues for vulnerabilities discovered in SBOMs.
* Track remediation progress from within your existing Linear workflow.

## Setup Steps

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **Linear**.
3. Enter the following:
   * **Linear Host URL**: Pre-filled with the Linear API URL (not editable).
   * **API Token**: A Linear personal API key. Generate one from **Linear > Settings > API > Personal API keys**.
4. Click **Verify** to test the connection.
5. On success, the verification panel displays: account name, email, and account ID.
6. Click **Save**.

## Configuration

After connecting Linear, configure per-product settings in **Settings > Organization > Integrations > Ticketing**:

* **Provider**: Select Linear.
* **Project Key**: Map to a Linear project.
* **Issue Type**: Select the issue type for vulnerability tickets.

## Required Permissions

### Linear API Key Permissions

The API key should have access to:

| Scope         | Purpose                             |
| ------------- | ----------------------------------- |
| Read projects | List available projects for mapping |
| Create issues | Create vulnerability tickets        |
| Read issues   | Track ticket status                 |

### Interlynk Permissions

| Permission           | Purpose                          |
| -------------------- | -------------------------------- |
| `view_connections`   | View Linear integration settings |
| `edit_connections`   | Configure Linear connection      |
| `delete_connections` | Remove the Linear integration    |

## Security Notes

* The Linear API token is encrypted at rest.
* Use a **service account** API key if available, rather than a personal key tied to an individual.
* Rotate the API key periodically and update the integration configuration.

## Troubleshooting

| Issue               | Cause                                      | Resolution                                  |
| ------------------- | ------------------------------------------ | ------------------------------------------- |
| Verification fails  | Invalid API token                          | Generate a new API key from Linear settings |
| Cannot see projects | Token lacks project read access            | Verify the API key has the correct scopes   |
| Tickets not created | Product not configured with Linear project | Set the project key in ticketing settings   |


# Slack

The Slack integration delivers real-time notifications from Interlynk to your Slack channels via incoming webhooks.

***

## Purpose

* Receive notifications for vulnerability discoveries, policy violations, license issues, and SBOM uploads.
* Route notifications to specific channels based on severity or event type.

## Setup Steps

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **Slack**.
3. Click **Add New** to add a Slack webhook configuration.
4. Enter:
   * **Slack Webhook URL**: An incoming webhook URL from your Slack workspace.
   * **Notification Type**: Select the notification level:
     * **All** — Receive all notifications.
     * **Alert** — Only alert-level notifications.
     * **Warning** — Only warning-level notifications.
     * **Info** — Only informational notifications.
   * **Frequency**: Currently supports **Instant** delivery.
5. Click **Save**.

### Multiple Channels

You can add multiple Slack webhook configurations to route different notification types to different channels. For example:

* `#security-alerts` — Alert notifications only
* `#sbom-updates` — Info notifications for uploads
* `#all-interlynk` — All notifications

Click **Add New** to add additional rows.

## Channel Configuration

### Creating a Slack Webhook URL

1. In Slack, navigate to **Apps > Manage > Custom Integrations > Incoming Webhooks** (or use the Slack API at `api.slack.com/apps`).
2. Create a new incoming webhook.
3. Select the target channel.
4. Copy the generated webhook URL (format: `https://hooks.slack.com/services/T.../B.../...`).
5. Paste the URL into the Interlynk Slack integration configuration.

## Event Types

Notifications are categorized into the following types:

| Category        | Examples                                                    |
| --------------- | ----------------------------------------------------------- |
| Vulnerabilities | New critical/high vulnerability discovered, severity change |
| Licenses        | License compliance violation detected                       |
| Policies        | Policy scan completed with failures                         |
| Uploads         | SBOM uploaded and processed                                 |

## Message Formatting

Slack messages from Interlynk include:

* Event type and severity level
* Affected product and environment
* Summary of the event (e.g., vulnerability ID, component name)
* Link back to the relevant Interlynk dashboard page

## Required Permissions

### Slack Workspace

* Permission to create incoming webhooks in the target workspace.

### Interlynk

| Permission           | Purpose                             |
| -------------------- | ----------------------------------- |
| `view_connections`   | View Slack integration settings     |
| `edit_connections`   | Add or update Slack webhooks        |
| `delete_connections` | Remove Slack webhook configurations |

## Security Notes

* Webhook URLs are encrypted at rest.
* Slack webhook URLs are secret — treat them like API tokens. Do not commit them to source control.
* Validate that the webhook URL points to your intended Slack workspace before saving.
* If a webhook URL is compromised, regenerate it in Slack and update the Interlynk configuration.

## Troubleshooting

| Issue                           | Cause                                    | Resolution                                                    |
| ------------------------------- | ---------------------------------------- | ------------------------------------------------------------- |
| No messages in channel          | Invalid webhook URL                      | Verify the URL is correct and the webhook is active in Slack  |
| Messages going to wrong channel | Webhook configured for different channel | Create a new webhook for the correct channel                  |
| Duplicate notifications         | Multiple webhook configs with same URL   | Remove duplicate entries in the integration settings          |
| Webhook URL rejected            | URL format invalid                       | Ensure the URL matches `https://hooks.slack.com/services/...` |


# Microsoft Teams

The Microsoft Teams integration delivers real-time notifications from Interlynk to your Teams channels via incoming webhooks.

***

## Purpose

* Receive notifications for vulnerability discoveries, policy violations, license issues, and SBOM uploads in Microsoft Teams channels.
* Route notifications by severity level.

## Webhook Setup

### Creating a Teams Incoming Webhook

1. In Microsoft Teams, navigate to the target channel.
2. Click the channel name > **Manage channel** > **Connectors** (or **Apps** > search for "Incoming Webhook").
3. Click **Configure** on the Incoming Webhook connector.
4. Enter a name (e.g., "Interlynk Notifications") and optionally upload an icon.
5. Click **Create**.
6. Copy the generated webhook URL.

### Configuring in Interlynk

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **Microsoft Teams**.
3. Click **Add New** to add a webhook configuration.
4. Enter:
   * **Teams Webhook URL**: The incoming webhook URL from your Teams channel.
   * **Notification Type**: Select the notification level (**All**, **Alert**, **Warning**, or **Info**).
   * **Frequency**: Currently supports **Instant** delivery.
5. Click **Save**.

You can add multiple webhook configurations for different channels or notification levels.

## Message Types

Teams notifications include the same event categories as other messaging integrations:

| Category        | Examples                                   |
| --------------- | ------------------------------------------ |
| Vulnerabilities | New critical/high vulnerability discovered |
| Licenses        | License compliance violation detected      |
| Policies        | Policy scan completed with failures        |
| Uploads         | SBOM uploaded and processed                |

Messages are formatted as adaptive cards or connector cards with:

* Event summary and severity
* Affected product and environment
* Link to the relevant Interlynk dashboard page

## Required Permissions

### Microsoft Teams

* Permission to manage connectors/webhooks in the target channel.

### Interlynk

| Permission           | Purpose                             |
| -------------------- | ----------------------------------- |
| `view_connections`   | View Teams integration settings     |
| `edit_connections`   | Add or update Teams webhooks        |
| `delete_connections` | Remove Teams webhook configurations |

## Security Notes

* Webhook URLs are encrypted at rest.
* Teams webhook URLs are secret — do not share them publicly or commit to source control.
* If a webhook URL is compromised, delete the connector in Teams and create a new one.

## Troubleshooting

| Issue                 | Cause                             | Resolution                                                             |
| --------------------- | --------------------------------- | ---------------------------------------------------------------------- |
| No messages appearing | Invalid or expired webhook URL    | Verify the webhook is still active in Teams channel settings           |
| Connector removed     | Teams admin deleted the connector | Re-create the incoming webhook in Teams and update the URL             |
| Messages delayed      | Teams webhook rate limits         | Reduce notification frequency or filter to higher-severity events only |


# Email

The Email integration sends Interlynk notifications directly to email addresses — individual inboxes, shared mailboxes, or distribution lists.

***

## Purpose

* Deliver vulnerability, policy, license, and upload notifications via email.
* Reach team members who may not have access to Slack or Teams.
* Send to shared mailboxes or distribution lists for team-wide visibility.

## Setup Steps

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **Email**.
3. Click **Add New** to add an email notification configuration.
4. Enter:
   * **Email Address**: The target email address.
   * **Notification Type**: Select the notification level (**All**, **Alert**, **Warning**, or **Info**).
   * **Frequency**: Currently supports **Instant** delivery.
5. Click **Save**.

You can add multiple email configurations to route notifications to different addresses with different severity filters.

## Organization Notifications

Email notifications at the organization level are delivered for events across all products and environments. Configure organization-wide defaults in **Settings > Organization > Notifications** to control which event types generate emails.

## Delivery Failures

If email delivery fails:

* Verify the email address is correct and the mailbox is active.
* Check your organization's spam/junk filters for messages from Interlynk.
* If using a distribution list, ensure external senders are allowed.
* Contact Interlynk support if delivery issues persist.

## DMARC/SPF Recommendations

To ensure Interlynk emails are not rejected or marked as spam by your mail server:

* **Allowlist** the Interlynk sending domain in your email gateway.
* If your organization enforces strict **DMARC** policies, add the Interlynk sending domain to your SPF record or configure an exception.
* Check your **quarantine/junk folder** if notifications are not arriving.

{% hint style="info" %}
Interlynk sends emails from its own mail infrastructure. Contact Interlynk support for the current sending domain and IP ranges if needed for allowlisting.
{% endhint %}

## Required Permissions

### Interlynk

| Permission           | Purpose                            |
| -------------------- | ---------------------------------- |
| `view_connections`   | View email integration settings    |
| `edit_connections`   | Add or update email configurations |
| `delete_connections` | Remove email configurations        |

## Security Notes

* Email addresses are encrypted at rest.
* Be cautious when adding external email addresses — notifications may contain vulnerability details.
* Use distribution lists or shared mailboxes instead of personal addresses for team notifications to avoid disruption when team members leave.

## Troubleshooting

| Issue                                | Cause                                    | Resolution                                              |
| ------------------------------------ | ---------------------------------------- | ------------------------------------------------------- |
| Emails not received                  | Address typo or mailbox full             | Verify the email address and mailbox status             |
| Emails in spam/junk                  | Sender not allowlisted                   | Add Interlynk sending domain to your allowlist          |
| Duplicate emails                     | Multiple email configs with same address | Remove duplicate entries in integration settings        |
| External distribution list rejecting | List does not accept external senders    | Update the distribution list to allow external messages |


# SSO

Interlynk supports SAML 2.0-based single sign-on (SSO) for centralized identity management. This allows users to authenticate through your organization's identity provider (IdP) instead of managing separate credentials.

***

## Supported Identity Providers

Interlynk's SAML implementation is built on the OneLogin SAML toolkit and is compatible with any SAML 2.0 identity provider. The primary documented setup is for **Azure Entra ID** (formerly Azure Active Directory).

***

## SAML Setup with Azure Entra ID

### Prerequisites

* An Azure Entra ID tenant with administrative access.
* An Interlynk organization with Admin permissions.
* The ability to create Enterprise Applications in Azure Entra ID.

### Step 1: Create an Enterprise Application in Azure

1. Sign in to the [Azure Entra ID portal](https://entra.microsoft.com).
2. Navigate to **Enterprise Applications > New Application > Create your own application**.
3. Name the application (e.g., "Interlynk SSO").
4. Select **Integrate any other application you don't find in the gallery (Non-gallery)**.
5. Click **Create**.

### Step 2: Configure SAML in Azure

1. In the application, navigate to **Single sign-on > SAML**.
2. Configure the **Basic SAML Configuration**:

| Field                  | Value                                                                                         |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| Identifier (Entity ID) | Enter the value from the Interlynk SSO configuration modal                                    |
| Reply URL (ACS URL)    | Auto-generated in Interlynk: `https://api.interlynk.io/auth/saml/callback?tenant=YOUR_TENANT` |
| Sign on URL            | (Optional) Your Interlynk dashboard URL                                                       |

3. Configure **Attributes & Claims** (see attribute mapping table below).
4. Download the **App Federation Metadata URL** from the SAML Signing Certificate section.

### Step 3: Configure SAML in Interlynk

1. Navigate to **Settings > Organization > Integrations > Connections**.
2. Click **SSO**.
3. Fill in the following fields:

| Field                           | Description                                                                                  |
| ------------------------------- | -------------------------------------------------------------------------------------------- |
| **Tenant**                      | A unique identifier for your organization's SAML tenant (e.g., your domain name)             |
| **Identifier / Entity ID**      | The entity ID configured in Azure (must match exactly)                                       |
| **Reply URL / ACS URL**         | Auto-generated: `https://api.interlynk.io/auth/saml/callback?tenant=YOUR_TENANT` (read-only) |
| **App Federation Metadata URL** | The metadata URL from Azure Entra ID                                                         |
| **Default User Role**           | The role assigned to users who authenticate via SSO for the first time                       |

4. Click **Save**.

### Step 4: Test SSO

1. After configuration, attempt to sign in using SSO.
2. You will be redirected to your Azure Entra ID login page.
3. After successful authentication, you will be redirected back to Interlynk.
4. Verify that the user's name, email, and role are populated correctly.

***

## SAML Attribute Mapping

Interlynk requires the following attributes in the SAML assertion:

| SAML Attribute                                                       | Interlynk Field | Required    | Description                                          |
| -------------------------------------------------------------------- | --------------- | ----------- | ---------------------------------------------------- |
| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name`         | Name            | Yes         | User's full display name                             |
| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` | Email           | Yes         | User's email address (used as the unique identifier) |
| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname`    | First Name      | Recommended | User's first name                                    |
| `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname`      | Last Name       | Recommended | User's last name                                     |

### Azure Entra ID Default Claims

Azure Entra ID provides these attributes by default. Verify they are included in the **Attributes & Claims** section of your Enterprise Application:

| Claim Name     | Source Attribute                        |
| -------------- | --------------------------------------- |
| `name`         | `user.displayname`                      |
| `emailaddress` | `user.mail` or `user.userprincipalname` |
| `givenname`    | `user.givenname`                        |
| `surname`      | `user.surname`                          |

***

## Auto-Registration

When a user authenticates via SSO for the first time and does not have an existing Interlynk account:

1. An Interlynk account is automatically created using the email and name from the SAML assertion.
2. The user is automatically associated with the organization linked to the SAML tenant.
3. The user is assigned the **Default User Role** configured in the SSO settings.
4. No separate invitation is required.

{% hint style="info" %}
Auto-registration is enabled by default when SSO is configured.
{% endhint %}

***

## Enforcing SSO

To enforce SSO as the only authentication method:

1. Configure and test SSO as described above.
2. Verify that all team members can successfully authenticate via SSO.
3. Contact Interlynk support to disable password-based login for your organization.

{% hint style="warning" %}
Before enforcing SSO, ensure at least one admin user has been verified through the SSO flow. If SSO is misconfigured after enforcement, admin users will be locked out.
{% endhint %}

***

## Recovery Plan if Misconfigured

If SSO is misconfigured and users cannot sign in:

1. **If password login is still enabled**: Sign in with email and password, then correct the SAML configuration.
2. **If SSO is enforced**: Contact Interlynk support to temporarily disable SSO enforcement so you can reconfigure.
3. **Common fixes**:
   * Verify the **Tenant** value matches exactly between Azure and Interlynk.
   * Verify the **Entity ID** matches exactly.
   * Ensure the **ACS URL** is correctly configured in Azure.
   * Re-download and re-enter the **App Federation Metadata URL** if the certificate was rotated.

***

## Security Best Practices

* **Use a strong default role**: Set the default SSO user role to **Viewer** to follow least-privilege principles. Promote users to higher roles after onboarding.
* **Require MFA in your IdP**: Interlynk defers authentication to your identity provider — enable MFA in Azure Entra ID for an additional security layer.
* **Audit SSO users**: Periodically review the user list to ensure only authorized personnel have access.
* **Certificate rotation**: When rotating SAML signing certificates in Azure, update the metadata URL or re-import the metadata in Interlynk.
* **Separate admin access**: Maintain at least one admin user with password-based login as a break-glass account in case SSO fails.

***

## Common Misconfigurations

| Issue                     | Symptom                                     | Fix                                                                      |
| ------------------------- | ------------------------------------------- | ------------------------------------------------------------------------ |
| Tenant mismatch           | SSO redirects but authentication fails      | Ensure the tenant value in Interlynk matches the Azure configuration     |
| Entity ID mismatch        | SAML assertion rejected                     | Verify the Identifier/Entity ID is identical in both Azure and Interlynk |
| ACS URL wrong             | Azure returns an error after authentication | The ACS URL is auto-generated — verify the tenant is correct             |
| Missing email claim       | User created without email                  | Ensure `emailaddress` claim is mapped in Azure Attributes & Claims       |
| Certificate expired       | SAML assertion signature validation fails   | Rotate the certificate in Azure and update the metadata URL in Interlynk |
| Default role set to Admin | All new SSO users get admin access          | Change the default SSO user role to Viewer                               |


# Health Scoring

Interlynk calculates a health score (0–100) for each component in your SBOMs based on three weighted factors: **age**, **community**, and **security**. Administrators can customize the weights and thresholds to align scoring with their organization's risk tolerance.

{% hint style="info" %}
Health score customization is available on the Enterprise tier.
{% endhint %}

***

## How Health Scores Work

The health score evaluates component risk across three dimensions:

| Factor        | What It Measures                                                                                     | Default Weight |
| ------------- | ---------------------------------------------------------------------------------------------------- | -------------- |
| **Age**       | How recently the component was updated, whether the package or repository shows signs of abandonment | 30%            |
| **Community** | Number of active contributors to the component's repository                                          | 30%            |
| **Security**  | OpenSSF Scorecard results, known vulnerabilities, support status (EOL, deprecated)                   | 40%            |

The final score is a weighted combination: `score = (age_score × age_weight) + (community_score × community_weight) + (security_score × security_weight)`

### Scoring Factors in Detail

**Age Score** considers:

* Days since the last package version was published
* Days since the last repository commit
* Whether the package version is archived or pre-release

**Community Score** considers:

* Number of contributors to the repository
* Whether the contributor count falls below the minimum threshold (weak community) or exceeds the maximum threshold (strong community)

**Security Score** considers:

* OpenSSF Scorecard score (if available)
* Whether the repository is archived
* Support status: end-of-support (EOS), end-of-life (EOL), deprecated
* Package-level deprecation or outdated status

### Non-Identifiable Components

Components without a package URL (purl) or repository URL receive a reduced score because they cannot be enriched with package manager or repository metadata.

***

## Customizing Health Score

### Accessing the Configuration

1. Navigate to **Settings > Organization > Compliance & scoring > Health score**.
2. The configuration page displays three sections: **Relative Weights**, **Age Score**, and **Community Score**.

### Relative Weights

Adjust the percentage contribution of each factor to the overall health score. The three weights must sum to exactly **100%**.

| Field                | Description                    | Default | Range |
| -------------------- | ------------------------------ | ------- | ----- |
| Age Weight (%)       | Weight of the age factor       | 30      | 0–100 |
| Community Weight (%) | Weight of the community factor | 30      | 0–100 |
| Security Weight (%)  | Weight of the security factor  | 40      | 0–100 |

Example configurations:

| Profile             | Age | Community | Security | Use Case                                                     |
| ------------------- | --- | --------- | -------- | ------------------------------------------------------------ |
| Default             | 30% | 30%       | 40%      | Balanced assessment                                          |
| Security-first      | 10% | 10%       | 80%      | Organizations prioritizing vulnerability exposure            |
| Maintenance-focused | 50% | 30%       | 20%      | Organizations concerned about abandoned dependencies         |
| Community-driven    | 20% | 50%       | 30%      | Open-source-heavy stacks where community health matters most |

### Age Score Thresholds

Configure how long a component can be inactive before it is considered unmaintained.

| Field                                         | Description                                     | Default  | Range        |
| --------------------------------------------- | ----------------------------------------------- | -------- | ------------ |
| Mark Repository Unmaintained After Inactivity | Days of repository inactivity before flagging   | 365 days | 1–3,650 days |
| Mark Package Unmaintained After Inactivity    | Days since last package release before flagging | 365 days | 1–3,650 days |

Lower values are stricter — components will be flagged sooner. Higher values are more lenient.

### Community Score Thresholds

Configure the contributor count range that defines community health using a range slider.

| Field                | Description                                          | Default | Range |
| -------------------- | ---------------------------------------------------- | ------- | ----- |
| Minimum Contributors | Below this count, the community is considered weak   | 5       | 0–100 |
| Maximum Contributors | Above this count, the community is considered strong | 20      | 0–100 |

Components with contributor counts between the minimum and maximum receive a proportional score. Below the minimum scores poorly; above the maximum scores well.

### Saving Changes

1. Adjust the weights and thresholds.
2. Click **Update**.
3. Health scores are recalculated for all components across the organization in the background.

{% hint style="info" %}
Recalculation runs as a background job. Updated scores will appear on dashboards within a few minutes depending on the number of components.
{% endhint %}

***

## Impact on Dashboards

Health scores are displayed throughout the platform:

* **Component details**: Individual component health score with a breakdown showing age, community, and security sub-scores.
* **Product dashboards**: Aggregated health score distributions.
* **SBOM views**: Component-level health indicators.
* **Policy rules**: Health scores can be used as conditions in policy rules (e.g., fail if any component has a health score below 30).

The health score is visualized as a gradient bar (red to green) with a tooltip breakdown showing the contribution of each factor.

***

## Best Practice Scoring Models

### Recommended Starting Configuration

Start with the default weights (30/30/40) and adjust based on the types of issues your organization encounters most frequently.

### When to Adjust Weights

| Scenario                                      | Recommended Adjustment                                                  |
| --------------------------------------------- | ----------------------------------------------------------------------- |
| Frequent incidents from outdated dependencies | Increase Age Weight to 50%                                              |
| Using many small/single-maintainer libraries  | Increase Community Weight to 40-50%                                     |
| Compliance-driven organization                | Increase Security Weight to 60-80%                                      |
| Internal/proprietary components dominate      | Lower Community Weight (internal repos have few contributors by design) |

### Threshold Guidance

| Environment           | Repository Inactivity | Package Inactivity | Min Contributors |
| --------------------- | --------------------- | ------------------ | ---------------- |
| Strict (regulated)    | 180 days              | 180 days           | 10               |
| Moderate              | 365 days (default)    | 365 days           | 5                |
| Lenient (early stage) | 730 days              | 730 days           | 2                |

***

## Governance Recommendations

* **Establish baseline scores** before customizing weights. Review the current distribution of scores to understand the impact of changes.
* **Communicate changes** to your team when adjusting weights — score changes affect dashboards and may trigger policy violations.
* **Use policies** to enforce minimum health score thresholds (e.g., block releases if any critical component scores below 40).
* **Review quarterly**: Revisit your weight configuration as your tech stack and risk profile evolve.

***

## Common Misconfigurations

| Issue                                 | Symptom                                          | Fix                                                      |
| ------------------------------------- | ------------------------------------------------ | -------------------------------------------------------- |
| Weights do not sum to 100%            | Update button disabled, validation error shown   | Adjust weights to total exactly 100                      |
| Age threshold too low (e.g., 30 days) | Most components flagged as unmaintained          | Increase to 180+ days for realistic results              |
| Community min set to 0                | All components pass community threshold          | Set minimum to at least 2–5                              |
| Security weight set to 0%             | Vulnerable components receive high health scores | Security weight should be at least 20%                   |
| All weights equal (33/33/34)          | No factor differentiated                         | Prioritize the factor most relevant to your risk profile |


# Vulnerability Custom Fields

Custom fields allow you to attach organization-specific metadata to vulnerabilities. Use them to track risk dimensions, compliance mappings, or internal classification data that is not captured by standard vulnerability attributes.

{% hint style="info" %}
Custom fields are available on paid tiers. Free-tier organizations do not have access to this feature.
{% endhint %}

***

## Creating Custom Fields

### Step-by-Step

1. Navigate to **Settings > Organization > Custom & risk fields > Custom fields**.
2. Click **Add Fields**.
3. Fill in the following:

| Field             | Description                                                                          | Required    |
| ----------------- | ------------------------------------------------------------------------------------ | ----------- |
| **Display Name**  | Human-readable name shown in the UI                                                  | Yes         |
| **Internal Name** | Machine-readable identifier used in policies and API calls (unique per organization) | Yes         |
| **Field Type**    | `TEXT` or `RANGE`                                                                    | Yes         |
| **Min Value**     | Minimum allowed value (RANGE type only, max 100)                                     | Conditional |
| **Max Value**     | Maximum allowed value (RANGE type only, max 100)                                     | Conditional |

4. Click **Save**.

{% hint style="info" %}
The field type cannot be changed after creation. To change the type, delete the field and create a new one.
{% endhint %}

### Limits

* Maximum of **2 custom fields** per organization (one TEXT, one RANGE).

***

## Field Types Supported

| Type      | Description                          | Validation                                                               | Example Use                                     |
| --------- | ------------------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------- |
| **TEXT**  | Freeform text value                  | No constraints                                                           | Risk region, business unit, compliance tag      |
| **RANGE** | Numeric value within a defined range | Must be between `min_value` and `max_value`; max value cannot exceed 100 | Risk score, impact rating, exploitability index |

### RANGE Field Constraints

* `min_value` must be less than `max_value`.
* `min_value` and `max_value` cannot be equal.
* Maximum value is capped at 100.

***

## Usage in Dashboards

Custom field values are displayed on vulnerability detail views. Once a custom field is defined, it appears as an additional column or attribute when viewing vulnerability data for any SBOM in the organization.

***

## Usage in Ticket Sync

Custom field values can flow into Jira tickets when the Jira integration is configured. If a custom field maps to a Jira custom field, its value is included in ticket creation and synchronization.

***

## Usage in Policies

Custom fields can be used as **policy rule subjects**, enabling policy-based automation and enforcement.

### Policy Rule Subjects

| Subject Pattern                         | Field Type         | Operators                              |
| --------------------------------------- | ------------------ | -------------------------------------- |
| `VULN_CUSTOM_FIELD_{INTERNAL_NAME}`     | TEXT               | `IS`, `IS_NOT`, `EXISTS`, `NOT_EXISTS` |
| `VULN_CUSTOM_FIELD_{INTERNAL_NAME}`     | RANGE              | `LESS_THAN`, `MORE_THAN`, `RANGE`      |
| `VULN_CUSTOM_FIELD_{INTERNAL_NAME}_AGE` | TEXT (age-tracked) | `LESS_THAN`, `MORE_THAN`, `RANGE`      |

**Example policy rule:**

> Fail if `VULN_CUSTOM_FIELD_risk_score` is `MORE_THAN` 80.

This creates a policy that flags vulnerabilities with a custom risk score above 80.

{% hint style="info" %}
Age tracking (the `_AGE` suffix) is currently supported only for the `risk_region` internal name. This creates a virtual field that tracks how long a vulnerability has had a specific value.
{% endhint %}

***

## Compliance Mapping

Custom fields can be used to map vulnerabilities to internal compliance categories:

* **Risk classification**: Use a TEXT field (e.g., `risk_region`) to tag vulnerabilities by geographic or regulatory scope.
* **Impact scoring**: Use a RANGE field (e.g., `impact_rating`) to assign a numeric impact score aligned with your compliance framework.
* **Audit evidence**: Custom field values are included in exports and can serve as evidence for compliance audits.

***

## Best Practices for Standardization

* **Use consistent internal names**: Choose descriptive, lowercase, underscore-separated names (e.g., `risk_region`, `impact_score`). These names are used in policy rules and cannot be changed after creation.
* **Document your fields**: Maintain internal documentation of what each custom field represents, who is responsible for populating it, and how it maps to compliance or risk frameworks.
* **Populate fields consistently**: Incomplete data reduces the value of custom fields in dashboards and policies. Establish a process for populating fields during vulnerability triage.
* **Use RANGE fields for quantitative risk**: Numeric ranges integrate cleanly with policy rules (threshold-based enforcement) and provide sortable/filterable data in dashboards.
* **Plan before creating**: With a limit of 2 custom fields, choose carefully. Prioritize fields that support your most critical compliance or risk management workflows.

***

## Common Misconfigurations

| Issue                                               | Symptom                                                       | Fix                                                                               |
| --------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Internal name contains spaces or special characters | Policy rule references fail                                   | Use lowercase letters, numbers, and underscores only                              |
| Min and max values are equal (RANGE)                | Validation error on save                                      | Set distinct min and max values                                                   |
| Field type set incorrectly                          | Cannot use numeric operators on TEXT field                    | Delete and recreate the field with the correct type                               |
| Both fields used, need a third                      | "Add Fields" button disabled                                  | Evaluate whether an existing field can be repurposed                              |
| Field deleted while referenced in policies          | Policy rules referencing the field may not evaluate correctly | Update or remove policy rules that reference the deleted field before deleting it |


# Notification Management

Interlynk provides a two-tier notification system: **organization-level** defaults and **user-level** overrides. Notifications can be delivered via Slack, Microsoft Teams, and email through configured integrations.

***

## Organization-Level Notifications

Organization-level notification settings define the baseline notification behavior for all users and integrations.

### Configuring Defaults

1. Navigate to **Settings > Organization > Notifications**.
2. The notification table displays all available notification types, each with:

| Column           | Description                                         |
| ---------------- | --------------------------------------------------- |
| **Active**       | Toggle to enable or disable the notification type   |
| **Notification** | Name of the notification event                      |
| **Description**  | What triggers this notification                     |
| **Level**        | Severity level: **Alert**, **Warning**, or **Info** |

3. Toggle individual notifications on or off.
4. Changes are saved automatically via bulk update.

### Severity Thresholds

Notification levels control the urgency of the message:

| Level       | Color  | Purpose                                                                                      |
| ----------- | ------ | -------------------------------------------------------------------------------------------- |
| **Alert**   | Orange | High-priority events requiring immediate attention (e.g., critical vulnerability discovered) |
| **Warning** | Red    | Significant events that should be reviewed soon (e.g., policy violation)                     |
| **Info**    | Blue   | Informational events for awareness (e.g., SBOM upload completed)                             |

Organization admins set the default level for each notification type. Users can override these at the personal level.

### Integration-Based Notifications

Organization-level notifications are delivered through all configured integrations:

* **Slack**: Messages sent to configured webhook channels.
* **Microsoft Teams**: Messages sent to configured webhook channels.
* **Email**: Messages sent to configured email addresses.

Each integration can be configured with its own notification type filter (All, Alert, Warning, Info) — see [Integrations](/administration/integrations) for details.

***

## User-Level Notifications

Users can customize their personal notification preferences to override organization defaults.

### Personal Notification Settings

1. Navigate to **Settings > Personal > Notifications**.
2. The **Messages** tab displays the same notification types as the organization settings.
3. Toggle individual notifications on or off for your account.
4. Your personal settings override the organization defaults for notifications delivered to your personal channels.

### Project-Specific Preferences

The **Preferences** tab allows fine-grained control over which products and categories trigger notifications:

1. Navigate to **Settings > Personal > Notifications > Preferences**.
2. The table is organized by **product group** (expandable rows).
3. For each product/environment, select the notification categories:

| Category            | Events Covered                                     |
| ------------------- | -------------------------------------------------- |
| **All**             | All notification categories                        |
| **Vulnerabilities** | New vulnerabilities, severity changes, VEX updates |
| **Licenses**        | License compliance violations                      |
| **Policies**        | Policy scan results, violations                    |
| **Uploads**         | SBOM uploads, processing completions               |
| **None**            | Suppress all notifications for this product        |

4. Click **Save** for each product to apply preferences.

### Email vs. Integration Preferences

* **Personal email notifications**: Controlled by the email integration at the organization level and user notification settings.
* **Slack/Teams notifications**: Controlled by the organization's webhook configurations — these are channel-level, not user-level.
* **In-app notifications**: Controlled by the user's personal notification preferences.

Users who want to receive notifications only for specific products should use the **Preferences** tab to select categories per product rather than disabling notifications globally.

### Digest vs. Real-Time

* **Instant**: Notifications are sent as soon as the event occurs. This is the current default delivery frequency for most events.
* Integration connections (Slack, Teams, Email) support a frequency setting, currently set to **Instant**.

***

## Digest Notifications

Two digest types consolidate notifications to reduce inbox noise.

### Weekly Compliance Email Digest

A weekly email summarizing compliance status is sent automatically to organization admins every Monday. The digest includes:

* Compliance scores for each product, compared against the previous week.
* A week-over-week delta so admins can spot regressions at a glance.

This digest is delivered via email regardless of Slack or Teams integration status. No configuration is required — it is sent automatically to all admin users in the organization.

### Vulnerability Scan Notification Digest

When an SBOM with Parts (composed of multiple product versions) finishes vulnerability scanning, results from all parts are consolidated into a single notification rather than sending separate alerts per part. This avoids notification storms for large SBOM compositions.

The digest fires once all part scans within a batch have completed, and includes:

* Total new vulnerability count across all parts.
* A link back to the parent SBOM's vulnerability view.

### Repeated Same-Version Alerts

Re-uploading an SBOM for a version that already exists produces a new SBOM that replaces the previous one. Vulnerabilities that were already present in the replaced SBOM are not re-announced, so only genuinely new findings generate a notification.

This applies only when the replaced SBOM belongs to the same product and the same version, is the direct predecessor of the new one, and had already finished its vulnerability scan. A new version, or a first scan, notifies on everything it finds.

***

## Common Misconfigurations

| Issue                                   | Symptom                                             | Fix                                                                       |
| --------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------- |
| All notifications disabled at org level | No one receives any notifications                   | Re-enable critical notification types in org settings                     |
| User overrides not taking effect        | User still receives notifications they disabled     | Verify the user's personal settings are saved correctly                   |
| Slack/Teams notifications but no email  | Email integration not configured                    | Add an email connection in the integrations settings                      |
| Too many notifications                  | Notification fatigue                                | Use category-based filtering per product and raise the severity threshold |
| Notifications for irrelevant products   | User receives alerts for products they don't manage | Configure product-specific preferences in the Preferences tab             |

***

## Recommended Best Practices

* **Enable alerts for critical events** at the organization level (e.g., critical vulnerabilities, policy failures) and allow users to opt into informational notifications.
* **Use product-specific preferences** to reduce noise — team members should only receive notifications for products they own.
* **Configure at least two delivery channels** (e.g., Slack + email) for critical alerts to ensure delivery even if one channel has issues.
* **Review notification settings quarterly** as team membership and product ownership change.
* **Avoid the "All" notification type** on high-volume Slack channels — filter to Alert or Warning to prevent channel overload.


# Environment Rules

Environment rules map incoming repository events (pushes, pull requests) to Interlynk environments based on branch patterns. They control which environment an SBOM is assigned to when it arrives via a source control integration.

***

## How Environment Rules Work

When a webhook event arrives from GitHub, GitLab, or Bitbucket, Interlynk evaluates environment rules to determine the target environment:

```
Webhook Event → Match Event Type → Match Branch Pattern → Assign Target Environment
```

**Resolution order:**

1. **Project-level rules** are evaluated first (highest priority).
2. If no project-level rule matches, **organization-level rules** are evaluated.
3. If no rule matches, the SBOM is assigned to the `default` environment.

Within each level, rules are evaluated by **priority** (lower number = higher priority), then by **rule ID** as a tiebreaker.

***

## Default Rules (Auto-Created)

When you connect a source control integration (GitHub, GitLab, or Bitbucket) via OAuth, Interlynk automatically creates a set of organization-level environment rules. These defaults cover the most common branching workflows out of the box.

| Priority | Event Type           | Branch Pattern | Target Environment |
| -------- | -------------------- | -------------- | ------------------ |
| 1        | `PullRequestMerged`  | `main`         | `production`       |
| 2        | `PullRequestMerged`  | `develop`      | `development`      |
| 3        | `PullRequestMerged`  | `*`            | `default`          |
| 4        | `PullRequestCreated` | `main`         | `production`       |
| 5        | `PullRequestCreated` | `develop`      | `development`      |
| 6        | `PullRequestCreated` | `*`            | `default`          |
| 7        | `PullRequestUpdated` | `main`         | `production`       |
| 8        | `PullRequestUpdated` | `develop`      | `development`      |
| 9        | `PullRequestUpdated` | `*`            | `default`          |
| 10       | `RepositoryPush`     | `NA`           | `default`          |

**What this means in practice:**

* Merges, opens, or updates targeting `main` route SBOMs to **production**.
* Merges, opens, or updates targeting `develop` route SBOMs to **development**.
* All other PR activity falls through to **default**.
* Repository push events (without a PR context) go to **default**.

{% hint style="info" %}
These defaults assume a workflow where `main` is the production branch and `develop` is the development branch. If your team uses a different branching model (e.g., `master`, `trunk`, GitFlow with `release/*`), edit the auto-created rules or add project-level overrides to match your workflow.
{% endhint %}

***

## Matching Algorithm

When a webhook event arrives, Interlynk resolves the target environment using the following algorithm:

```
1. Collect applicable rules (project-level first, then organization-level)
2. Sort rules by priority (lower number = higher priority)
3. For each rule, check if the event type matches
4. If the event type matches, evaluate the branch pattern:
   a. Exact match   — pattern equals the branch name (e.g., "main" = "main")
   b. Glob match     — pattern contains a wildcard (e.g., "feature/*" matches "feature/login")
   c. Wildcard match — pattern is "*" (matches any branch)
5. Return the target environment of the first matching rule
6. If no rule matches, return "default"
```

**Key points:**

* For `RepositoryPush` events, the branch pattern is matched against `NA` rather than the branch name.
* Exact matches are evaluated before glob and wildcard patterns at the same priority level.
* The fallback to `default` ensures every event is routed to an environment, even if no rules are configured.

***

## Creating Environment Rules

### Organization-Level Rules

Organization rules apply across all products unless overridden by project-level rules.

1. Navigate to **Settings > Organization > Environments > Rules**.
2. The rules table displays:

| Column                 | Description                              |
| ---------------------- | ---------------------------------------- |
| **Active**             | Whether the rule is enabled              |
| **Event Type**         | The webhook event that triggers the rule |
| **Target Branch**      | Branch pattern to match against          |
| **Target Environment** | The Interlynk environment to assign      |

### Supported Event Types

| Event Type           | Description                                                |
| -------------------- | ---------------------------------------------------------- |
| `RepositoryPush`     | Code pushed to a branch                                    |
| `PullRequestCreated` | A new pull request / merge request is opened               |
| `PullRequestMerged`  | A pull request / merge request is merged                   |
| `PullRequestUpdated` | A pull request / merge request is updated with new commits |

### Branch Pattern Matching

Branch patterns support the following syntax:

| Pattern       | Matches                                          | Example                              |
| ------------- | ------------------------------------------------ | ------------------------------------ |
| Exact         | Single specific branch                           | `main`, `master`, `develop`          |
| Glob wildcard | Branches matching a prefix/suffix                | `feature/*`, `release/*`, `hotfix/*` |
| Wildcard      | All branches                                     | `*`                                  |
| `NA`          | Events without a branch (e.g., some push events) | `NA`                                 |

### Target Environments

Target environments map to Interlynk environment names:

| Environment   | Typical Use                          |
| ------------- | ------------------------------------ |
| `development` | Feature branches, development builds |
| `production`  | Main/master branch, release tags     |
| `default`     | Catch-all for unmatched events       |

### Project-Level Rules

Project-level rules override organization rules for specific products. They are configured per project and do not have an explicit target environment — the project name is used as the environment identifier.

{% hint style="info" %}
Duplicate rules across sibling projects in the same product group are not allowed.
{% endhint %}

### Priority

Rules within the same level are evaluated by priority number. **Lower numbers are evaluated first.** If two rules could match the same event, the higher-priority (lower number) rule wins.

***

## Example Configuration

### Production Stricter Than Development

A common pattern: route `main` branch pushes to `production` and everything else to `development`.

| Priority | Event Type         | Branch Pattern | Target Environment |
| -------- | ------------------ | -------------- | ------------------ |
| 1        | RepositoryPush     | `main`         | production         |
| 2        | PullRequestMerged  | `main`         | production         |
| 3        | RepositoryPush     | `release/*`    | production         |
| 4        | PullRequestCreated | `*`            | development        |
| 5        | RepositoryPush     | `*`            | development        |

With this configuration:

* Pushes to `main` → production environment (strictest policies)
* Merges to `main` → production environment
* Pushes to `release/1.0` → production environment
* Pull requests from any branch → development environment
* Pushes to any other branch → development environment

### CI Enforcement Workflow

Combine environment rules with environment-specific policies to enforce different standards:

1. **Create environment rules** that route branches to the correct environment.
2. **Configure environment defaults** (see [Environment Defaults](/administration/environment-defaults)) with appropriate scanning settings per environment.
3. **Create policies** with environment-specific conditions:
   * Development: Warn on critical vulnerabilities.
   * Production: Fail on critical and high vulnerabilities.
4. **Enable PR comments** in environment defaults so policy results are posted on pull requests.

```
Developer pushes to feature/xyz
  → Environment rule matches: RepositoryPush + feature/* → development
  → Development policies applied (warn-only)
  → SBOM processed with development settings

Developer merges PR to main
  → Environment rule matches: PullRequestMerged + main → production
  → Production policies applied (fail on critical/high)
  → Stricter scanning and compliance checks
```

***

## Common Misconfigurations

| Issue                              | Symptom                                                     | Fix                                                                  |
| ---------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------- |
| No rules configured                | All SBOMs go to `default` environment                       | Create rules mapping your primary branches to environments           |
| Wildcard rule has highest priority | All events match the wildcard, specific rules never trigger | Set the wildcard rule to the lowest priority (highest number)        |
| Duplicate rules across projects    | Validation error when saving                                | Each project in a product group must have unique rules               |
| `main` branch not matched          | Production SBOMs appear in default environment              | Add a rule for `main` (or `master`) → production                     |
| PR events not triggering           | Pull request SBOMs not processed                            | Add rules for `PullRequestCreated` and/or `PullRequestMerged` events |

***

## Recommended Best Practices

* **Always create explicit rules for `main`/`master`** mapped to `production` to ensure production SBOMs are correctly categorized.
* **Use glob patterns** (`feature/*`, `release/*`) rather than listing individual branches.
* **Set wildcard (`*`) rules at the lowest priority** as a catch-all for unmatched branches.
* **Match your branching strategy**: If your team uses GitFlow, create rules for `develop`, `release/*`, `hotfix/*`, and `main`.
* **Use project-level rules** when specific products need different branch-to-environment mapping than the organization default.
* **Test your rules** by pushing to a branch and verifying the SBOM appears in the expected environment.


# Environment Defaults

Environment defaults define the baseline scanning and processing behavior applied to new projects in your organization. These settings control what happens when an SBOM is uploaded or ingested — which checks run, how data is retained, and what automation is applied.

***

## Default Settings

The following settings can be configured as organization-wide defaults. When a new project is created, it inherits these values.

### Import Actions

| Setting                                        | Description                                                                                                  | Default |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------- |
| **Run SBOM Checks**                            | Execute quality and compliance checks on uploaded SBOMs                                                      | Off     |
| **Always Use Latest Parts**                    | Keep component information updated with the latest available data                                            | Off     |
| **Run Internal Labeling**                      | Identify and label internal components                                                                       | Off     |
| **Run Auto Archive**                           | Automatically archive old SBOM versions                                                                      | Off     |
| **Apply Automation Rules**                     | Execute configured automation rules on upload                                                                | Off     |
| **Run Vulnerability Scan**                     | Scan components for known vulnerabilities                                                                    | Off     |
| **Run Component Support Analysis**             | Evaluate component support status (EOL, deprecated, maintained)                                              | Off     |
| **Retain Vulnerability Status with Version**   | Preserve VEX status when a new version of an SBOM is uploaded                                                | Off     |
| **Interpret License List as "AND" expression** | Treat multi-license declarations as requiring all listed licenses                                            | Off     |
| **Copy VEX Across Versions on Import**         | Carry forward VEX dispositions from previous SBOM versions to new imports                                    | Off     |
| **Copy Tickets Across Versions**               | Reuse an existing Jira ticket when the same vulnerability appears in a new SBOM version                      | On      |
| **Copy Tickets Across Environments**           | Reuse an existing Jira ticket when the same vulnerability appears in another Environment of the same Product | Off     |
| **Enable PR Comments**                         | Post SBOM analysis results as comments on pull requests                                                      | Off     |

### Data Retention

| Setting                   | Description                                                                                       | Default     |
| ------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
| **Data Retention (days)** | Number of days to retain SBOM versions before archiving. Options: 1, 30, 90, 365, or Forever (0). | Forever (0) |

***

## Configuring Defaults

### Setting Organization Defaults

1. Navigate to **Settings > Organization > Environments > Defaults**.
2. Toggle the desired import actions on or off.
3. Select a **Data Retention** period from the dropdown.
4. Click **Save for Future Projects** to apply the settings to newly created projects going forward.

### Applying to All Existing Projects

To retroactively apply the current defaults to all existing projects:

1. Configure the desired settings.
2. Click **Apply to All Projects**.
3. Confirm the action in the confirmation dialog.

{% hint style="warning" %}
This overwrites the individual settings of all existing projects. Any per-project customizations will be lost.
{% endhint %}

***

## Inheritance Rules

Environment defaults follow a top-down inheritance model:

```
Organization Defaults
  └── Project Settings (per project)
```

1. **Organization defaults** are the baseline. They define the starting configuration for all new projects.
2. **Project settings** are initialized from organization defaults when a project is created.
3. After creation, project settings are **independent** — changing organization defaults does not automatically propagate to existing projects unless you explicitly click "Apply to All Projects."

### Overriding Logic

To customize a specific project's settings:

1. Navigate to the project's settings page.
2. Modify the desired settings.
3. Save.

The project's settings will diverge from the organization defaults. Future changes to organization defaults will not affect this project unless explicitly applied.

***

## Common Misconfigurations

| Issue                                                 | Symptom                                         | Fix                                                        |
| ----------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------- |
| Vulnerability scanning disabled by default            | New projects don't show vulnerability data      | Enable "Run Vulnerability Scan" in defaults                |
| SBOM checks disabled                                  | Quality/compliance scores not generated         | Enable "Run SBOM Checks" in defaults                       |
| Data retention set to 1 day                           | SBOM history lost almost immediately            | Increase retention to 90+ days or Forever                  |
| "Apply to All Projects" clicked accidentally          | All project-specific customizations overwritten | Re-configure individual projects as needed                 |
| PR comments enabled but no source control integration | Comments not posted                             | Configure a GitHub, GitLab, or Bitbucket integration first |
| VEX status not preserved between versions             | Triage work lost on SBOM re-upload              | Enable "Retain Vulnerability Status with Version"          |

***

## Recommended Best Practices

* **Enable vulnerability scanning and SBOM checks by default** — these are the core value-add features and should be active for most projects.
* **Enable "Retain Vulnerability Status with Version"** to avoid re-triaging vulnerabilities when SBOMs are re-uploaded.
* **Set data retention to at least 90 days** for audit trail purposes. Use "Forever" if storage is not a concern.
* **Enable "Copy VEX Across Versions on Import"** if your workflow involves frequent SBOM updates and you want to preserve triage decisions.
* **Enable PR comments** for projects using source control integrations — this provides immediate feedback to developers on pull requests.
* **Review defaults when onboarding a new team** to ensure they align with the team's security requirements.
* Use **"Save for Future Projects"** when adjusting defaults, and only use **"Apply to All Projects"** when you intentionally want to standardize all projects.


# Compliance

Interlynk supports multiple compliance frameworks to help organizations align SBOM practices with regulatory and industry standards. Administrators can enable frameworks, configure SBOM quality scoring, and manage compliance check rules.

***

## Supported Compliance Frameworks

| Framework                           | Description                                                                                                                 |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **FDA**                             | U.S. Food and Drug Administration requirements for medical device software                                                  |
| **NTIA Minimum Elements 2021**      | National Telecommunications and Information Administration minimum elements for SBOMs, scored against the 6.3.1 element set |
| **BSI TR-03183-2 v1.1**             | German Federal Office for Information Security (BSI) technical guideline for SBOM content                                   |
| **BSI TR-03183-2 v2.1.0**           | Updated BSI guideline (v2.1.0) with expanded SBOM quality requirements for European regulatory alignment                    |
| **OpenChain Telco SBOM Guide v1.1** | OpenChain working group guide for telecom-sector SBOM requirements                                                          |
| **PCI**                             | Payment Card Industry Data Security Standard                                                                                |
| **SOC2**                            | Service Organization Control 2 compliance                                                                                   |
| **ISO 27001**                       | International standard for information security management systems                                                          |
| **NIST**                            | National Institute of Standards and Technology cybersecurity framework                                                      |

### Enabling Compliance Frameworks

1. Navigate to **Settings > Organization > Compliance & scoring > Compliance**.
2. Click the compliance configuration.
3. In the **Applicable Compliance** dropdown, select one or more frameworks.
4. Click **Save**.

You can enable multiple frameworks simultaneously. Each framework contributes its own set of check rules to SBOM analysis.

### SBOM Quality Score

One compliance framework can be designated as the primary scoring framework:

1. Navigate to the **SBOM Quality Score** configuration.
2. Select a framework from the dropdown. The list contains the frameworks configured for your organization, plus **None**.
3. Click **Save**.

{% hint style="info" %}
Only one framework can be the active quality scorer at a time. Selecting **None** turns quality scoring off.
{% endhint %}

***

## Mapping Vulnerabilities to Compliance Controls

Compliance frameworks define check rules that evaluate SBOMs against framework-specific requirements. These checks verify:

* Required SBOM fields are present (supplier, version, timestamps).
* Component identification meets minimum standards (package URLs, CPE identifiers).
* Vulnerability data meets disclosure and tracking requirements.
* License information is complete and accurate.

### Compliance Check Rules

Each framework includes a set of predefined check rules. Administrators can manage these rules:

1. Navigate to **Settings > Organization > Compliance & scoring > Compliance** and scroll to the **Checks** table.
2. The checks table displays:

| Column          | Description                                            |
| --------------- | ------------------------------------------------------ |
| **Active**      | Toggle to enable or disable individual checks          |
| **Check ID**    | Numeric identifier for the check rule                  |
| **Description** | Short and long description of what the check evaluates |
| **Severity**    | Impact level: Critical, High, Medium, Low              |

3. Toggle checks on or off to include or exclude them from SBOM analysis.
4. Change the severity level of a check by clicking the severity dropdown.

### Severity Levels

| Level        | Description                                 | Use When                                          |
| ------------ | ------------------------------------------- | ------------------------------------------------- |
| **Critical** | SBOM fails a fundamental requirement        | Missing mandatory fields, no supplier information |
| **High**     | Significant gap in SBOM quality             | Missing package identifiers for most components   |
| **Medium**   | Moderate quality issue                      | Incomplete license data, missing timestamps       |
| **Low**      | Minor issue or best-practice recommendation | Optional fields not populated                     |

***

## Reporting

### SBOM Compliance Reports

Compliance check results are available at the SBOM level:

* Each SBOM shows its compliance score as a percentage.
* Individual check results (pass/fail) are listed with descriptions.
* Failed checks include guidance on what is missing or incorrect.
* Selected failing checks can be corrected and re-evaluated in place, without leaving the Checks tab. See [Fixing a Failed Check](/product-guides/sbom-management/versions#fixing-a-failed-check).

Results are grouped into **SBOM details** and **Component details**, and each row shows a **Requirement** level and a **Coverage** percentage.

### Requirement Levels

The requirement level tells you whether a row is mandatory under the selected framework or only recommended.

| Framework                  | Mandatory  | Recommended |
| -------------------------- | ---------- | ----------- |
| NTIA Minimum Elements 2021 | `SHALL`    | `SHOULD`    |
| BSI TR-03183-2 v2.1.0      | `SHALL`    | `MAY`       |
| All other frameworks       | `Required` | `MAY`       |

Recommended rows are reported alongside mandatory ones so you can see coverage of the optional requirements, but they are scored separately from the mandatory set.

### NTIA Minimum Elements

NTIA compliance is scored against the 6.3.1 element set. The report covers these elements:

| Element                       | Section           | What it evaluates                                 |
| ----------------------------- | ----------------- | ------------------------------------------------- |
| Author of SBOM Data           | SBOM details      | The document author                               |
| Timestamp                     | SBOM details      | The document creation timestamp                   |
| Lifecycle Phase               | SBOM details      | The SBOM lifecycle phase                          |
| Supplier Name                 | Component details | SBOM-level supplier plus component-level supplier |
| Component Name                | Component details | Component name                                    |
| Component Version             | Component details | Component version                                 |
| Other Unique Identifiers      | Component details | Document identifier plus component identifiers    |
| Dependency Relationship       | Component details | Component relationships                           |
| Other Component Relationships | Component details | Component relationship coverage                   |
| Hash of the Component         | Component details | Component checksums                               |
| License Information           | Component details | Component licenses                                |

Supplier and unique-identifier elements combine document-level and component-level evidence into one score. For component identifiers, a component passes when it carries at least one identifier type enabled by your organization's rules.

{% hint style="info" %}
NTIA scores changed with the move to the 6.3.1 element set. A score recorded before the change is not directly comparable to one recorded after it, in either direction. Re-run checks on SBOMs you are tracking over time before reading a delta as a real change in SBOM quality.
{% endhint %}

### Organization-Level Reporting

Organization dashboards aggregate compliance data across all products:

* Overall compliance posture by framework.
* Trend data showing compliance improvement over time.
* Products with the lowest compliance scores.

***

## Audit Exports

Compliance data can be exported for audit purposes:

* **SBOM downloads** include compliance metadata when downloaded in CycloneDX or SPDX format.
* **Vulnerability data** with VEX status, justification, and custom field values can be exported.
* **Check results** provide evidence of SBOM quality for auditors.

To export SBOM data with compliance information:

```bash
# Download an enhanced SBOM with vulnerability data
pylynk download --prod "my-app" --env "production" --ver "v1.0.0" \
  --out-file audit-sbom.json \
  --vuln true \
  --include-support-status true
```

### Export Profiles

When downloading an SBOM you can pick an **Export Profile**, which constrains the output to what a framework expects rather than the full Interlynk representation.

| Profile                        | Output                                                                                                                                                                                             |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Interlynk Profile**          | The default. All download options are available.                                                                                                                                                   |
| **NTIA Minimum Elements 2021** | Pruned to the NTIA minimum elements. Parts, file artifacts, vulnerability data, and support status are excluded.                                                                                   |
| **BSI TR-03183-2 v2.1.0**      | CycloneDX 1.7 or SPDX 3.0.1 JSON, with file artifacts and parts included and declared and concluded licenses kept distinguishable. Vulnerability data, support status, and redaction are excluded. |

Both framework profiles fix the content options rather than letting you set them, so an export produced under a profile is reproducible and cannot be widened by accident. SPDX-Lite is not offered under either profile; selecting a framework profile falls back to full SPDX.

See [Downloading SBOMs](/product-guides/sbom-management/versions#downloading-sboms) for the download flow.

***

## Evidence Collection

For compliance audits, Interlynk provides evidence across several dimensions:

| Evidence Type            | Source                                 | How to Access                          |
| ------------------------ | -------------------------------------- | -------------------------------------- |
| SBOM completeness        | Compliance check results               | SBOM detail view > Checks tab          |
| Vulnerability management | VEX dispositions, triage history       | Vulnerability detail view              |
| Component provenance     | Package URLs, supplier data            | Component detail view                  |
| Policy enforcement       | Policy scan results, violation history | Policy dashboard                       |
| Remediation tracking     | Jira ticket status, VEX status changes | Ticketing settings, vulnerability logs |
| Change history           | Activity logs, component vuln logs     | Activity log views                     |

***

## Best Practices for Audits

### Preparation

* **Enable the relevant compliance framework** before generating SBOMs that will be audited.
* **Run SBOM checks** on all products in scope to identify gaps before the audit.
* **Address critical and high-severity check failures** — these represent the most impactful gaps.
* **Use VEX dispositions** to document why specific vulnerabilities are not exploitable in your context.

### During the Audit

* **Export SBOMs** in the format required by your auditor (CycloneDX or SPDX).
* **Provide compliance check results** as evidence of SBOM quality.
* **Show policy scan history** to demonstrate ongoing enforcement.
* **Reference Jira tickets** (via the Jira integration) to show remediation progress.

### Ongoing Compliance

* **Enable SBOM checks by default** in [Environment Defaults](/administration/environment-defaults) so all new projects are automatically evaluated.
* **Create policies** that enforce compliance minimums (e.g., fail if compliance score below 80%).
* **Set up notifications** for compliance check failures to catch regressions early.
* **Review compliance scores monthly** and track trends.

***

## Common Misconfigurations

| Issue                                                      | Symptom                                       | Fix                                                                                      |
| ---------------------------------------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------- |
| No compliance framework enabled                            | No compliance checks run, no scores displayed | Enable at least one framework in compliance settings                                     |
| SBOM checks disabled in environment defaults               | Compliance checks never execute               | Enable "Run SBOM Checks" in [Environment Defaults](/administration/environment-defaults) |
| All checks set to Low severity                             | Compliance failures do not trigger policies   | Adjust severity levels to reflect actual risk                                            |
| Multiple frameworks enabled but no quality scorer selected | No SBOM quality score displayed               | Select a primary framework for quality scoring                                           |
| Critical checks disabled                                   | Fundamental gaps not flagged                  | Review disabled checks and re-enable any that are required by your audit scope           |

***

## Recommended Best Practices

* Enable the compliance framework that matches your **regulatory requirements** (e.g., FDA for medical devices, NTIA for U.S. government).
* Start with **all checks enabled** and disable only those explicitly not applicable to your context.
* Set the **quality scoring framework** to match your primary compliance driver.
* Use **policies with compliance-related conditions** to automate enforcement.
* **Export and archive** compliance evidence regularly, not just before audits.
* Align custom field usage (see [Vulnerability Custom Fields](/administration/vulnerability-custom-fields)) with compliance categories for richer audit evidence.


# Overview

lynkctl is Interlynk's SBOM generator. It produces spec-compliant CycloneDX 1.6 SBOMs from a project's build system or its package-manager descriptors.

***

## How It Works

lynkctl has two families of providers, and it picks the right one for your project automatically.

**Build providers** derive an SBOM from the build system of a compiled project — C/C++ applications, libraries, and embedded firmware. Most such projects have no dependency manifest, so lynkctl inspects build files and build metadata to determine which source files would be compiled, which libraries would be linked, and which tools would do the work. The build is never executed.

**Manifest providers** derive an SBOM from package-manager manifests and lockfiles — `package.json`, `go.mod`, `pom.xml`, and the rest. They read the descriptors directly; no build and no package manager need to run.

Both families feed the same enrichment and emitter stages, so every run produces a consistent SBOM regardless of ecosystem.

## Supported Ecosystems

### Build Providers (compiled projects)

| Build system                   | Detected from                                | Typical use                                 |
| ------------------------------ | -------------------------------------------- | ------------------------------------------- |
| GNU Make                       | `Makefile` / `GNUmakefile`                   | C/C++ applications and libraries            |
| CMake                          | `CMakeLists.txt` plus CMake File API replies | C/C++ projects with a configured build tree |
| IAR Embedded Workbench for Arm | Project files                                | Embedded firmware                           |

### Manifest Providers (package-manager projects)

| Ecosystem        | `--provider`                | Detected from                                                                                                           |
| ---------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| JavaScript / npm | `npm`, `yarn`               | `package.json`, `package-lock.json`, `npm-shrinkwrap.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lock`                   |
| Python           | `python`                    | `requirements.txt`, `Pipfile.lock`, `poetry.lock`, `pdm.lock`, `pylock.toml`, `uv.lock`, `pyproject.toml`, `setup.py`   |
| Go               | `go`                        | `go.mod`, `go.sum`                                                                                                      |
| Rust             | `cargo`                     | `Cargo.toml`, `Cargo.lock`                                                                                              |
| Ruby             | `gem`                       | `Gemfile.lock`, `*.gemspec`                                                                                             |
| PHP              | `php`                       | `composer.json`, `composer.lock`                                                                                        |
| .NET             | `nuget`, `dotnet`, `csharp` | `*.csproj`, `packages.lock.json`, `packages.config`, `Directory.Packages.props`, `Directory.Build.props`, `*.deps.json` |
| Java (Maven)     | `maven`                     | `pom.xml`                                                                                                               |
| Java (Gradle)    | `gradle`                    | `build.gradle`(`.kts`), `settings.gradle`(`.kts`), `gradle.lockfile`, `gradle/verification-metadata.xml`                |

`yarn`, `dotnet`, and `csharp` are aliases — they select the JavaScript and .NET providers respectively.

## Commands

| Command                   | Purpose                                   |
| ------------------------- | ----------------------------------------- |
| `lynkctl generate [DIR]`  | Produce a CycloneDX SBOM for a project    |
| `lynkctl db <subcommand>` | Manage the local OSS-index database cache |
| `lynkctl version`         | Print the build version                   |

Run any command with `--help` for full details.

## Output

lynkctl writes the SBOM to **stdout**, or to the path given with `--output`. Diagnostics, summaries, and progress go to **stderr**, so output can be piped safely:

```bash
lynkctl generate ./myproject > sbom.cdx.json
```

lynkctl produces CycloneDX 1.6 SBOMs, validated against the official schema.

## Flags Available on Every Command

| Flag        | Short | Default | Description                                                                                |
| ----------- | ----- | ------- | ------------------------------------------------------------------------------------------ |
| `--output`  | `-o`  | stdout  | Write output to this path. With `--iar-all-configs`, must be a directory.                  |
| `--quiet`   | `-q`  | `false` | Suppress the per-SBOM summary line; only errors print.                                     |
| `--verbose` | `-v`  | `false` | Per-diagnostic detail. Repeatable: `-vv` adds provenance detail, `-vvv` adds timing trace. |
| `--strict`  |       | `false` | Exit non-zero on any warning. Errors already exit non-zero.                                |

## Exit Codes

| Code | Meaning                                                                                 |
| ---- | --------------------------------------------------------------------------------------- |
| `0`  | Success                                                                                 |
| `1`  | Runtime error, or diagnostics contained errors, or `--strict` and a warning was present |
| `2`  | Usage error (bad flag, missing path, conflicting options)                               |

## Getting lynkctl

lynkctl is distributed by Interlynk. Contact Interlynk to obtain the binary for your platform. See [Installation](/lynkctl/installation) for setup and requirements.

{% hint style="info" %}
New to lynkctl? Start with [Installation](/lynkctl/installation), then follow the How-To guide for your project: [GNU Make](/lynkctl/how-to-guides/gnu-make), [CMake](/lynkctl/how-to-guides/cmake), [IAR](/lynkctl/how-to-guides/iar), or [Package Manifests](/lynkctl/how-to-guides/package-manifests).
{% endhint %}


# Installation

## Obtaining lynkctl

lynkctl is distributed directly by Interlynk. Contact Interlynk to receive the binary for your operating system and CPU architecture. Once you have it, place it on your `PATH` — for example, in `/usr/local/bin`.

## Requirements

lynkctl is a self-contained binary. It needs additional tooling only when analysing certain build systems:

| When analysing                                                                         | You also need                                                                                                                    |
| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| GNU Make projects                                                                      | GNU Make 3.81 or newer, on `PATH`                                                                                                |
| CMake projects                                                                         | CMake 3.14 or newer, and a build tree that has already been configured so that CMake File API replies exist                      |
| IAR Embedded Workbench projects                                                        | No extra tooling                                                                                                                 |
| Package manifest projects (npm, Python, Go, Maven, Gradle, Cargo, RubyGems, PHP, .NET) | No extra tooling — lynkctl reads the manifests and lockfiles directly. The package manager itself does not need to be installed. |

No compiler or target toolchain is required. lynkctl reads build definitions and manifests; it does not build the project.

## Verify the Installation

```bash
lynkctl version
```

This prints the build version of lynkctl.

## The OSS-Index Database

To identify vendored open-source code, lynkctl uses a local OSS-index database. Download it before your first `generate` run:

```bash
lynkctl db download
```

The download is roughly 300 MB. See [OSS-Index Database](/lynkctl/database) for cache locations, refreshing, and air-gapped use.

{% hint style="info" %}
If you do not need vendored open-source identification, you can skip the database and pass `--no-oss-index` to `generate`.
{% endhint %}


# Generating SBOMs

`lynkctl generate` reads a project's build system or its package-manager descriptors and emits a CycloneDX 1.6 SBOM. Build providers inspect C/C++ project metadata without executing the build; manifest providers read package-manager descriptors directly.

```bash
lynkctl generate [DIR] [flags]
```

`DIR` is the project root and defaults to the current directory.

***

## Provider Selection

By default lynkctl auto-detects the provider from root-level signals. If **multiple** provider signals are present at the root, detection is ambiguous and lynkctl asks you to choose with `--provider`.

### Build providers

| `--provider` | Build system                   |
| ------------ | ------------------------------ |
| `gnu-make`   | GNU Make                       |
| `cmake`      | CMake                          |
| `iar`        | IAR Embedded Workbench for Arm |

### Manifest providers

| `--provider` | Ecosystem                               |
| ------------ | --------------------------------------- |
| `npm`        | JavaScript / npm                        |
| `yarn`       | JavaScript (alias for the npm provider) |
| `python`     | Python                                  |
| `go`         | Go modules                              |
| `cargo`      | Rust / Cargo                            |
| `gem`        | Ruby / RubyGems                         |
| `php`        | PHP / Composer                          |
| `nuget`      | .NET / NuGet                            |
| `dotnet`     | .NET (alias for the NuGet provider)     |
| `csharp`     | .NET (alias for the NuGet provider)     |
| `maven`      | Java / Maven                            |
| `gradle`     | Java / Gradle                           |

`--provider auto` (the default) detects any of the above. See the [Overview](/lynkctl/lynkctl#supported-ecosystems) for the files each provider is detected from.

For step-by-step walkthroughs, see the How-To guides:

* [GNU Make Projects](/lynkctl/how-to-guides/gnu-make)
* [CMake Projects](/lynkctl/how-to-guides/cmake)
* [IAR Embedded Workbench Firmware](/lynkctl/how-to-guides/iar)
* [Package Manifest Projects](/lynkctl/how-to-guides/package-manifests)

## Quick Examples

```bash
# Auto-detect, SBOM to stdout
lynkctl generate ./myproject

# Write to a file
lynkctl generate ./myproject -o sbom.cdx.json

# Force a specific provider
lynkctl generate ./myproject --provider go -o sbom.cdx.json

# Fail the build on any warning (CI gate)
lynkctl generate ./myproject --strict -o sbom.cdx.json
```

## Flag Reference

Every command supports `--output`, `--quiet`, `--verbose`, and `--strict` — see [Overview](/lynkctl/lynkctl#flags-available-on-every-command). The most common `generate` flags:

| Flag             | Description                                                                                         |
| ---------------- | --------------------------------------------------------------------------------------------------- |
| `--provider`     | Choose the build system or manifest provider (default `auto`).                                      |
| `--evidence`     | Include evidence for how each field was determined. See [Evidence & Confidence](/lynkctl/evidence). |
| `--reproducible` | Produce deterministic output. See [Reproducible SBOMs](/lynkctl/how-to-guides/reproducible).        |
| `--overrides`    | Apply manual component corrections from a YAML file. See [Manual Overrides](#manual-overrides).     |
| `--no-enrich`    | Skip enrichment; emit only build-system or manifest extraction.                                     |

Provider-specific flags — such as `--cmake-build-dir`, `--iar-config`, and `--make-target` — are covered in the How-To guide for each build system. Run `lynkctl generate --help` for the complete flag reference.

## Manual Overrides

`--overrides` points at a YAML file. Each entry matches a component by name **or** by source-file path glob, and replaces its fields. Overrides resolve at confidence 1.0 and always win over auto-detected values. Empty fields are left untouched. An entry that matches no component emits an `OVERRIDE_NO_MATCH` diagnostic.

```yaml
overrides:
  - name: openssl              # exact match on detected component name
    version: 3.0.12
    license: Apache-2.0
    link_type: static          # static | dynamic
  - path: third_party/zlib/**  # glob match against component source files
    name: zlib                 # rename the matched component
    version: 1.3
    license: Zlib
```

## Next Steps

* Understand what lynkctl emitted: [Evidence & Confidence](/lynkctl/evidence)
* Read the warnings and errors in a run: [Diagnostics & Exit Codes](/lynkctl/diagnostics)
* Wire lynkctl into a pipeline: [Running in CI/CD](/lynkctl/how-to-guides/ci-cd)


# OSS-Index Database

`lynkctl db` manages the OSS-index database that `generate` uses to identify vendored open-source projects. The database is a local cache; `db` keeps it current and lets you inspect it.

***

## Cache Locations

By default, lynkctl stores the database in the operating system cache directory:

```
macOS:   ~/Library/Caches/lynkctl/oss-index/oss-index.db
Linux:   $XDG_CACHE_HOME/lynkctl/oss-index/oss-index.db
         (or ~/.cache/lynkctl/oss-index/oss-index.db)
```

Override the location with `--cache-dir DIR`. The file inside is always named `oss-index.db`.

## Common Flags

All `db` subcommands accept:

| Flag              | Default | Description                                                                 |
| ----------------- | ------- | --------------------------------------------------------------------------- |
| `--cache-dir`     |         | Directory holding `oss-index.db`; empty uses the OS default cache location. |
| `--oss-index-url` |         | Override the OSS-index download URL (staging or mirror).                    |

## Subcommands

### `db download`

Fetch or refresh the cache from the published URL — roughly 300 MB. The command is idempotent: it skips the transfer when the cached file already matches the published manifest. On success it prints the resolved cache path to stdout.

```bash
lynkctl db download              # first install or routine refresh
lynkctl db download --force      # re-download even when current
```

| Flag      | Description                                                           |
| --------- | --------------------------------------------------------------------- |
| `--force` | Re-download even when the local cache matches the published manifest. |

### `db check`

Compare the cached database against the published manifest. It does **not** modify the cache, which makes it suitable as a CI gate signal.

```bash
lynkctl db check || lynkctl db download   # refresh only when needed
lynkctl db check --format json            # machine-readable
```

The exit code is `0` when the cache is up to date, and `1` when it is stale, missing, format-incompatible, or a network error occurred.

| Flag       | Default | Description                                           |
| ---------- | ------- | ----------------------------------------------------- |
| `--format` | `text`  | `text` (human-readable) or `json` (machine-readable). |

### `db info`

Inspect the cached database without touching the network: format version, build date, sha256, file size, and self-described index statistics (project, version, and file counts) when the database is present.

```bash
lynkctl db info
lynkctl db info --format json
```

| Flag       | Default | Description       |
| ---------- | ------- | ----------------- |
| `--format` | `text`  | `text` or `json`. |

### `db path`

Print the absolute path lynkctl uses for the OSS-index cache, resolved against `--cache-dir` or the OS default. Useful in scripts.

```bash
DB=$(lynkctl db path)
cp "$DB" /backup/
```

### `db clear`

Delete the cached database and its manifest sidecar. The command is idempotent — it exits `0` if nothing is cached — and removes a partial cache too. It prompts for confirmation unless `--yes` is given.

```bash
lynkctl db clear
lynkctl db clear --yes
```

| Flag    | Default | Description                               |
| ------- | ------- | ----------------------------------------- |
| `--yes` | `false` | Skip the interactive confirmation prompt. |

## Related

* [Air-Gapped Environments](/lynkctl/how-to-guides/air-gapped) — pre-fetch the database and run lynkctl offline


# Evidence & Confidence

lynkctl records, for every conclusion it reaches, where that conclusion came from and how strongly it is supported. This lets you audit an SBOM rather than take it on faith.

***

## Evidence Output

When you pass `--evidence`, lynkctl emits CycloneDX 1.6 evidence on components where it can represent the supporting records cleanly. Evidence can include identity methods, source/manifest/map occurrences, license evidence, copyright evidence, confidence values, and tool references.

```bash
lynkctl generate ./myproject --evidence -o sbom.cdx.json
```

Scope decisions and other conclusions that CycloneDX cannot directly model remain internal. They are surfaced through [diagnostics](/lynkctl/diagnostics) when they affect auditability.

## Confidence

Confidence lives on evidence records and CycloneDX evidence methods. Higher values mean stronger evidence. When multiple evidence records support the same conclusion, the resolver applies precedence rules first, then confidence, then a stable evidence-ID tie break.

### Score Reference

lynkctl assigns each conclusion a confidence score based on the strength of its source — explicit declarations and build commands score highest, heuristic inferences lowest. The detailed score-to-source breakdown is internal and evolves with the tool. Contact Interlynk if you need the full reference for audit or review purposes.

### Interpreting Scores

| Range       | Confidence | Guidance                                                                                                              |
| ----------- | ---------- | --------------------------------------------------------------------------------------------------------------------- |
| 0.85 – 1.00 | High       | Data comes from authoritative sources — explicit declarations, build commands, pkg-config.                            |
| 0.60 – 0.84 | Moderate   | Inferred from build structure, source scanning, or heuristic analysis. Generally reliable, but may need verification. |
| Below 0.60  | Low        | Fallback heuristics. Review recommended.                                                                              |

When multiple stages contribute evidence for the same field, individual evidence records preserve the per-source confidence and reasoning. Conflicting or low-confidence conclusions produce diagnostics with evidence IDs in verbose output.

## Overriding a Conclusion

If lynkctl gets a component wrong, or you have authoritative information it cannot derive, supply a `--overrides` YAML file. Overrides carry confidence 1.00 and take precedence over every other source. Run `lynkctl generate --help` for the override file format.

```bash
lynkctl generate ./myproject --overrides overrides.yaml -o sbom.cdx.json
```

## Related

* [Diagnostics & Exit Codes](/lynkctl/diagnostics) — how conflicts and low-confidence conclusions are reported


# Diagnostics & Exit Codes

lynkctl emits structured diagnostics to stderr during SBOM generation. They tell you what lynkctl could not determine and why, so you can decide whether an SBOM is complete enough to use.

***

## The Summary Line

After the BOM is written, lynkctl prints a summary line to stderr:

```
SBOM generated: 5 components, 2 warnings, 0 errors
```

Suppress this line with `--quiet`. Run with `--verbose` (`-v`) to show individual diagnostics, grouped by severity — errors first, then warnings, then info. `-v` is repeatable: `-vv` adds provenance detail, `-vvv` adds a timing trace. Diagnostics produced from evidence resolution include the relevant evidence IDs in verbose output.

```
  [error] GNU_MAKE_NOT_FOUND: GNU Make not found in PATH
    → install with: brew install make
  [warning] EVIDENCE_CONFLICT: conflicting evidence for component:zlib identity field version
```

## Severity Levels

| Level       | Shown by default      | Description                                                                                                         |
| ----------- | --------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **error**   | Yes                   | The SBOM cannot be produced or is fundamentally invalid. You must act before the output is trustworthy.             |
| **warning** | Yes                   | The SBOM was produced, but a known limitation reduced fidelity, or a specific call deserves review.                 |
| **info**    | Only with `--verbose` | A non-trivial choice lynkctl made. SBOM-affecting choices surface with `-v`; provenance and debug notes with `-vv`. |

## Exit Codes

| Code | Meaning                                                                                 |
| ---- | --------------------------------------------------------------------------------------- |
| `0`  | Success                                                                                 |
| `1`  | Runtime error, or diagnostics contained errors, or `--strict` and a warning was present |
| `2`  | Usage error (bad flag, missing path, conflicting options)                               |

## Strict Mode

With `--strict`, any warning-level diagnostic causes lynkctl to exit with code `1` after writing the SBOM. This is designed for CI gates where incomplete or uncertain SBOMs should block the pipeline.

```bash
lynkctl generate . --strict
# Exit code 1 if any warnings are present
```

See [Running in CI/CD](/lynkctl/how-to-guides/ci-cd) for full pipeline examples.

## Diagnostic Codes

Each diagnostic carries a stable code, such as `GNU_MAKE_NOT_FOUND` or `EVIDENCE_CONFLICT`. Run with `-v` to see the codes a given run produced, along with their messages and suggested actions.

The full catalogue of diagnostic codes is internal and evolves with the tool. Contact Interlynk if you need the complete reference for a specific code or for audit purposes.


# How-To Guides


# GNU Make Projects

This guide covers generating an SBOM for a C/C++ project built with GNU Make.

## Prerequisites

* lynkctl installed — see [Installation](/lynkctl/installation)
* GNU Make 3.81 or newer, on `PATH`

lynkctl runs `make` in dry-run and introspection modes only. It never compiles the project.

***

## Generate an SBOM

From the project root:

```bash
lynkctl generate . -o sbom.cdx.json
```

lynkctl auto-detects a `Makefile` or `GNUmakefile`. To be explicit, pass `--provider gnu-make`.

## Choose a Build Target

By default lynkctl analyses the `all` target. Use `--make-target` (`-t`) to analyse a different one:

```bash
lynkctl generate . --make-target firmware -o sbom.cdx.json
```

## Pass Build Variables

Some Makefiles change what gets compiled based on variables. Supply them with `--make-config-vars`, which is repeatable:

```bash
lynkctl generate . \
  --make-config-vars BUILD=release \
  --make-config-vars ARCH=arm64 \
  -o sbom.cdx.json
```

## Troubleshooting

If a run reports warnings or errors, rerun with `-v` to see the individual diagnostics and their suggested actions. See [Diagnostics & Exit Codes](/lynkctl/diagnostics) for severity levels, exit codes, and strict mode. For help interpreting a specific diagnostic, contact Interlynk.


# CMake Projects

This guide covers generating an SBOM for a C/C++ project built with CMake.

## Prerequisites

* lynkctl installed — see [Installation](/lynkctl/installation)
* CMake 3.14 or newer
* A **configured** build tree

lynkctl reads the CMake File API replies, not `CMakeLists.txt` directly. The project must already be configured so those replies exist.

***

## Step 1 — Configure the Build Tree

Run CMake configure once to produce a build directory:

```bash
cmake -S ./app -B ./app/build -DCMAKE_BUILD_TYPE=Release
```

This populates `./app/build/.cmake/api/v1/reply/` with the File API replies lynkctl needs. No compilation happens at this step beyond CMake's own configure work.

## Step 2 — Generate the SBOM

```bash
lynkctl generate ./app \
  --provider cmake \
  --cmake-build-dir ./app/build \
  -o app.cdx.json
```

## Multi-Config Generators

For multi-config generators such as Ninja Multi-Config or Visual Studio, name the configuration with `--cmake-config`:

```bash
lynkctl generate ./app \
  --provider cmake \
  --cmake-build-dir ./app/build \
  --cmake-config Release \
  -o app.cdx.json
```

If multiple configurations exist and you omit `--cmake-config`, lynkctl reports `CMAKE_MULTI_CONFIG_AMBIGUOUS`.

## Container and Host Path Differences

When the build tree was configured inside a container but lynkctl runs on the host (or vice versa), absolute paths in the File API replies will not resolve. Rewrite them with `--cmake-path-prefix-map`, which is repeatable as `FROM=TO`:

```bash
lynkctl generate ./app \
  --provider cmake \
  --cmake-build-dir ./app/build \
  --cmake-path-prefix-map /work=/home/ci/app \
  -o app.cdx.json
```

## Projects in a Larger Repository

`DIR` doubles as the source and VCS root that lynkctl uses for git enrichment. When the CMake project is a subdirectory of a larger repository, point `--project-root` at the repository root so git-derived metadata resolves correctly:

```bash
lynkctl generate ./repo/app \
  --provider cmake \
  --cmake-build-dir ./repo/app/build \
  --project-root ./repo \
  -o app.cdx.json
```

`--project-root` defaults to `DIR` and is shared by every provider.

## Missing File API Replies

If the build directory exists but the File API replies are missing, lynkctl (with the default `--cmake-query=true`) writes File API query stamps and asks you to rerun CMake configure. Run the configure command from Step 1 again, then retry `generate`.

## Troubleshooting

If a run reports warnings or errors, rerun with `-v` to see the individual diagnostics and their suggested actions. See [Diagnostics & Exit Codes](/lynkctl/diagnostics) for severity levels, exit codes, and strict mode. For help interpreting a specific diagnostic, contact Interlynk.


# IAR Embedded Workbench Firmware

This guide covers generating an SBOM for embedded firmware built with IAR Embedded Workbench for Arm.

## Prerequisites

* lynkctl installed — see [Installation](/lynkctl/installation)
* An IAR project (`.ewp`) or workspace (`.eww`)

No IAR toolchain is required. lynkctl reads the project files directly.

***

## Generate an SBOM

Point `generate` at the `.ewp` or `.eww` file. lynkctl selects the IAR provider automatically when `DIR` is one of those files:

```bash
lynkctl generate ./fw/project.ewp -o fw.cdx.json
```

You can also pass the project directory with an explicit `--provider iar`.

## Select a Configuration

IAR projects usually declare more than one configuration, such as `Debug` and `Release`. Choose one with `--iar-config`:

```bash
lynkctl generate ./fw --provider iar --iar-config Release -o fw.cdx.json
```

When `--iar-config` is omitted, lynkctl processes the first declared configuration and reports `IAR_MULTIPLE_CONFIGURATIONS` if others exist.

## Emit Every Configuration

To produce one SBOM per configuration in a single run, use `--iar-all-configs`. This requires `--output` to be a **directory**, and it cannot be combined with `--iar-config`:

```bash
lynkctl generate ./fw --provider iar --iar-all-configs --output ./sboms/
```

## Troubleshooting

If a run reports warnings or errors, rerun with `-v` to see the individual diagnostics and their suggested actions. See [Diagnostics & Exit Codes](/lynkctl/diagnostics) for severity levels, exit codes, and strict mode. For help interpreting a specific diagnostic, contact Interlynk.


# Package Manifest Projects

This guide covers generating an SBOM for a project managed by a package manager — JavaScript, Python, Go, Rust, Ruby, PHP, .NET, or Java.

## Prerequisites

* lynkctl installed — see [Installation](/lynkctl/installation)

No package manager and no network access are required. lynkctl reads the manifests and lockfiles in your project directly.

***

## Supported Ecosystems

| Ecosystem        | `--provider`                         | Detected from                                                                                                           |
| ---------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| JavaScript / npm | `npm` (alias `yarn`)                 | `package.json`, `package-lock.json`, `npm-shrinkwrap.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lock`                   |
| Python           | `python`                             | `requirements.txt`, `Pipfile.lock`, `poetry.lock`, `pdm.lock`, `pylock.toml`, `uv.lock`, `pyproject.toml`, `setup.py`   |
| Go               | `go`                                 | `go.mod`, `go.sum`                                                                                                      |
| Rust             | `cargo`                              | `Cargo.toml`, `Cargo.lock`                                                                                              |
| Ruby             | `gem`                                | `Gemfile.lock`, `*.gemspec`                                                                                             |
| PHP              | `php`                                | `composer.json`, `composer.lock`                                                                                        |
| .NET             | `nuget` (aliases `dotnet`, `csharp`) | `*.csproj`, `packages.lock.json`, `packages.config`, `Directory.Packages.props`, `Directory.Build.props`, `*.deps.json` |
| Java (Maven)     | `maven`                              | `pom.xml`                                                                                                               |
| Java (Gradle)    | `gradle`                             | `build.gradle`(`.kts`), `settings.gradle`(`.kts`), `gradle.lockfile`, `gradle/verification-metadata.xml`                |

***

## Generate an SBOM

From the project root:

```bash
lynkctl generate . -o sbom.cdx.json
```

lynkctl auto-detects the ecosystem from the descriptors in the directory. The examples below are all equivalent to auto-detection, shown with an explicit `--provider` for clarity:

```bash
lynkctl generate ./web-app   --provider npm    -o sbom.cdx.json
lynkctl generate ./service   --provider go     -o sbom.cdx.json
lynkctl generate ./api       --provider python -o sbom.cdx.json
lynkctl generate ./lib       --provider maven  -o sbom.cdx.json
lynkctl generate ./gradle-app --provider gradle -o sbom.cdx.json
```

## Lockfiles vs Manifests

A lockfile pins the exact resolved dependency set; a manifest only declares ranges. lynkctl prefers the lockfile when one is present. When a project has only a manifest (for example a `package.json` with no `package-lock.json`), lynkctl falls back to the manifest and emits a `LOCKFILE_ABSENT` diagnostic — the resulting SBOM may be less precise than one built from a lockfile.

For the most accurate SBOM, commit and point lynkctl at a project that has its lockfile present.

## Multi-Ecosystem Repositories

If a directory contains descriptors for more than one ecosystem — say a `package.json` next to a `go.mod` — auto-detection is ambiguous and lynkctl reports `MULTI_ECOSYSTEM_DETECTED`. Pass `--provider` to choose:

```bash
lynkctl generate . --provider go -o backend.cdx.json
lynkctl generate . --provider npm -o frontend.cdx.json
```

## Flags

Manifest providers honour the shared flags — `--no-enrich`, `--overrides`, `--evidence`, `--exclude-dev`, `--exclude-optional`, `--reproducible`, `--timestamp`, `--strict`, `--quiet`, `--verbose`, and `--output`. See the [Generating SBOMs](/lynkctl/generate) flag reference.

The C/C++ build-provider flags — `--include-source-files`, `--exclude-header-files`, `--include-unlinked-vendored`, `--deep-scan`, and the `--make-*` / `--cmake-*` / `--iar-*` families — do **not** apply to manifest providers. Passing one produces a usage error (exit code `2`).

## Troubleshooting

If a run reports warnings or errors, rerun with `-v` to see the individual diagnostics and their suggested actions. See [Diagnostics & Exit Codes](/lynkctl/diagnostics) for severity levels, exit codes, and strict mode. For help interpreting a specific diagnostic, contact Interlynk.


# Running in CI/CD

This guide covers using lynkctl as a build step that generates an SBOM and, optionally, gates the pipeline on SBOM quality.

## Making lynkctl Available

lynkctl is distributed by Interlynk — see [Installation](/lynkctl/installation). In CI, make the binary available to the runner the same way you handle other internal tooling: a prebuilt container image, an internal artifact store, or a cached binary. The examples below assume `lynkctl` is already on `PATH`.

***

## Quality Gate with Strict Mode

`--strict` makes lynkctl exit `1` when any warning-level diagnostic is present. Use it to block releases whose SBOMs are incomplete or uncertain:

```bash
lynkctl generate . --strict -o sbom.cdx.json
```

The SBOM is still written before lynkctl exits non-zero, so you can archive it for inspection even on a failed gate.

## GitHub Actions

```yaml
name: SBOM
on: [push, pull_request]

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate SBOM
        run: lynkctl generate . --strict -o sbom.cdx.json

      - name: Upload SBOM
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: sbom.cdx.json
```

The `if: always()` on the upload step keeps the SBOM as an artifact even when the strict gate fails.

## GitLab CI

```yaml
sbom:
  stage: test
  script:
    - lynkctl generate . --strict -o sbom.cdx.json
  artifacts:
    when: always
    paths:
      - sbom.cdx.json
```

## Refreshing the OSS-Index Database

If your runners cache the OSS-index database, refresh it only when it is stale. `db check` exits `0` when current and `1` when not:

```bash
lynkctl db check || lynkctl db download
```

For runners without network access, see [Air-Gapped Environments](/lynkctl/how-to-guides/air-gapped).

## Reproducible Pipeline Output

To produce byte-identical SBOMs across rebuilds of the same source — useful for content-addressable storage and diffing — add `--reproducible`. See [Reproducible SBOMs](/lynkctl/how-to-guides/reproducible).

## Related

* [Diagnostics & Exit Codes](/lynkctl/diagnostics) — interpret the exit code and warnings
* [Air-Gapped Environments](/lynkctl/how-to-guides/air-gapped) — CI without network access


# Air-Gapped Environments

lynkctl can generate SBOMs without network access. The only component that normally needs the network is the OSS-index database used for vendored open-source identification. Pre-fetch it on a connected machine, then point lynkctl at the local copy.

***

## Step 1 — Fetch the Database on a Connected Machine

```bash
lynkctl db download
```

Find where it was stored:

```bash
lynkctl db path
```

## Step 2 — Transfer the Database

Copy the `oss-index.db` file to the air-gapped environment by whatever transfer mechanism you use — removable media, an internal artifact store, a base container image:

```bash
DB=$(lynkctl db path)
cp "$DB" /transfer/oss-index.db
```

## Step 3 — Run lynkctl Against the Local Database

Pass the database path explicitly with `--oss-index-db`:

```bash
lynkctl generate . --oss-index-db /opt/oss-index.db -o sbom.cdx.json
```

## Verifying the Database

`db info` inspects a cached database without touching the network — format version, build date, sha256, size, and index statistics:

```bash
lynkctl db info
```

## Generating Without Vendored Identification

If you do not need vendored open-source identification at all, skip the database entirely with `--no-oss-index`:

```bash
lynkctl generate . --no-oss-index -o sbom.cdx.json
```

This drops the OSS-index enrichment step; build-system analysis and other enrichment still run.

## Related

* [OSS-Index Database](/lynkctl/database) — full `db` subcommand reference
* [Running in CI/CD](/lynkctl/how-to-guides/ci-cd) — air-gapped runners


# Reproducible SBOMs

By default an SBOM embeds a generation timestamp and a fresh serial number, so two runs over identical source produce different files. `--reproducible` makes the output deterministic.

***

## Generate a Reproducible SBOM

```bash
lynkctl generate . --reproducible -o sbom.cdx.json
```

With `--reproducible`, lynkctl uses a fixed timestamp, a content-derived serial number, and sorted collections. Running it twice over the same source produces a byte-identical SBOM. This makes the output suitable for content-addressable storage and for diffing one build against the next.

## Controlling the Timestamp

`--reproducible` still records a timestamp; it just makes it deterministic instead of "now". Set it explicitly with `--timestamp`, which takes an RFC-3339 value and is only valid alongside `--reproducible`:

```bash
lynkctl generate . --reproducible --timestamp 2023-11-14T22:13:20Z -o sbom.cdx.json
```

When `--timestamp` is omitted, lynkctl falls back to the `SOURCE_DATE_EPOCH` environment variable — the same convention used by reproducible-build toolchains:

```bash
SOURCE_DATE_EPOCH=1700000000 lynkctl generate . --reproducible -o sbom.cdx.json
```

## When to Use It

| Scenario                                                       | Use `--reproducible`? |
| -------------------------------------------------------------- | --------------------- |
| Content-addressable artifact storage                           | Yes                   |
| Diffing SBOMs across builds to spot real changes               | Yes                   |
| Verifying a build is bit-for-bit reproducible                  | Yes                   |
| Routine SBOM generation where the real wall-clock time matters | No                    |


# FAQ

Practical answers for generating SBOMs with lynkctl. For platform-wide questions, see the main [Frequently Asked Questions](/support/faq).

***

## Basics

### What is the simplest command?

```bash
lynkctl generate .
```

This auto-detects the project and writes the SBOM to stdout. Add `-o` to write to a file:

```bash
lynkctl generate . -o sbom.cdx.json
```

### Does lynkctl build my project?

No. For compiled projects, lynkctl reads your build system — build files and, where available, build metadata — to work out what would be compiled and linked, without ever executing the build. For package-manager projects, it reads the manifests and lockfiles directly. No compiler, toolchain, or package manager needs to run.

### Which ecosystems does lynkctl support?

lynkctl has two provider families. **Build providers** cover compiled C/C++ and embedded projects: GNU Make, CMake, and IAR Embedded Workbench for Arm. **Manifest providers** cover package-manager projects: JavaScript/npm (including Yarn, pnpm, Bun), Python, Go, Rust/Cargo, Ruby/RubyGems, PHP/Composer, .NET/NuGet, and Java (Maven and Gradle). See the [Overview](/lynkctl/lynkctl#supported-ecosystems) for the full list and the files each provider is detected from.

### How does lynkctl know which provider to use?

It auto-detects from root-level signals — a `Makefile`, a `go.mod`, a `pom.xml`, and so on. If a directory contains signals for more than one ecosystem, detection is ambiguous and lynkctl reports `MULTI_ECOSYSTEM_DETECTED`; pass `--provider` to choose.

### Does lynkctl need the package manager installed?

No. Manifest providers read `package.json`, `go.mod`, `pom.xml`, lockfiles, and similar descriptors directly. The package manager does not run, and no network access is required.

### What output format does lynkctl produce?

CycloneDX 1.6 SBOMs, validated against the official schema. The SBOM is written to stdout, or to the path given with `--output` (`-o`).

### What command should I use in CI?

```bash
lynkctl generate . --strict -o sbom.cdx.json
```

`--strict` exits non-zero if lynkctl reports warnings; errors always exit non-zero. See [Running in CI/CD](/lynkctl/how-to-guides/ci-cd).

### What SBOM should I send to Interlynk support for analysis?

For a compiled C/C++ or embedded project, this is the most useful shape to share:

```bash
lynkctl generate . \
  --reproducible --timestamp 2023-11-14T22:13:20Z \
  --include-source-files --exclude-header-files \
  --evidence \
  -o sbom.cdx.json
```

It produces deterministic output, includes source-file components, drops header-file noise, and records evidence for how every field was determined. Add `-v` for verbose diagnostics on stderr when troubleshooting. For a package-manifest project, drop `--include-source-files --exclude-header-files` — those apply only to C/C++ build providers.

### How do I get lynkctl?

lynkctl is distributed by Interlynk. Contact Interlynk to obtain the binary for your platform. See [Installation](/lynkctl/installation).

## Build Systems

### How do I choose the build system?

Use auto-detection unless the project contains more than one build system, or you need to match a specific customer build. Force one with `--provider`:

```bash
lynkctl generate . --provider gnu-make -o sbom.cdx.json
lynkctl generate ./project.ewp --provider iar --iar-config Debug -o sbom.cdx.json
```

If both a `Makefile` and an IAR project are present, pass `--provider` explicitly. See the [GNU Make](/lynkctl/how-to-guides/gnu-make), [CMake](/lynkctl/how-to-guides/cmake), and [IAR](/lynkctl/how-to-guides/iar) guides.

## Source Detail

### How do I include source files as SBOM components?

```bash
lynkctl generate . --include-source-files --exclude-header-files -o sbom.cdx.json
```

`--include-source-files` emits one component per first-party source file; `--exclude-header-files` drops the headers. This is usually the better shape for C and embedded firmware audits. Both flags apply to C/C++ build providers only.

### How do I see how lynkctl decided a name, version, or license?

Pass `--evidence`. lynkctl then emits CycloneDX evidence — identity methods, occurrences, license and copyright evidence, confidence values, and tool references. Use it when the SBOM needs to be reviewed or defended. See [Evidence & Confidence](/lynkctl/evidence).

### What does the confidence score on a component mean?

It indicates how strongly a conclusion is supported. Scores of 0.85 and above come from authoritative sources such as explicit declarations and build commands; 0.60 to 0.84 are inferred from build structure or heuristics; below 0.60 are fallback heuristics that warrant review. See [Evidence & Confidence](/lynkctl/evidence).

### Why is a component missing a version or license?

lynkctl could not find authoritative information for that field, and reports it with `NO_VERSION_FOUND` or `NO_LICENSE_FOUND`. Run with `-v` to see which components are affected. If you know the correct value, supply it through a `--overrides` file.

### How do I make output stable for diffs?

```bash
lynkctl generate . --reproducible --timestamp 2023-11-14T22:13:20Z -o sbom.cdx.json
```

`--reproducible` sorts collections and makes identifiers deterministic; `--timestamp` sets the embedded timestamp. You can also use the `SOURCE_DATE_EPOCH` environment variable. See [Reproducible SBOMs](/lynkctl/how-to-guides/reproducible).

## Third-Party and Vendored Code

### How do I mark a third-party source directory as a component?

Use `--vendored-root`, repeating it for multiple subtrees:

```bash
lynkctl generate . \
  --vendored-root third_party/ringbuf \
  --vendored-root third_party/mbedtls \
  -o sbom.cdx.json
```

Use this when a third-party subtree should be its own component rather than a set of individual source files. `--vendored-root` applies to the GNU Make, CMake, and IAR providers.

### How do I include third-party code that is compiled but not linked?

```bash
lynkctl generate . --include-unlinked-vendored -o sbom.cdx.json
```

This emits vendored code seen during build analysis even when it is not linked into the final binary.

### How do I identify modified or patched OSS copies?

```bash
lynkctl generate . --deep-scan -o sbom.cdx.json
```

`--deep-scan` uses slower fingerprint matching to catch modified copies of open-source code.

{% hint style="warning" %}
`--deep-scan` is a work in progress. Treat results from this path as experimental for now.
{% endhint %}

## Enrichment and Corrections

### How do I run lynkctl in an air-gapped environment?

Pre-fetch the OSS-index database on a connected machine, transfer it, and point lynkctl at the local copy with `--oss-index-db`. See [Air-Gapped Environments](/lynkctl/how-to-guides/air-gapped) for the full procedure.

### How do I disable enrichment?

Disable only the OSS-index matching, or every enrichment step:

```bash
lynkctl generate . --no-oss-index -o sbom.cdx.json   # OSS-index only
lynkctl generate . --no-enrich -o sbom.cdx.json      # git, pkg-config, OS packages, OSS-index, overrides
```

Use `--no-enrich` when the SBOM should reflect only build-system extraction.

### lynkctl got a component wrong. How do I correct it?

Use a `--overrides` YAML file. Each entry matches a component by name or by source-file glob and replaces its fields. Overrides resolve at confidence 1.0 and win over auto-detected values; an entry that matches nothing emits `OVERRIDE_NO_MATCH`. See [Generating SBOMs](/lynkctl/generate#manual-overrides) for the file format.

## Diagnostics and Output

### Why did my build fail after I added `--strict`?

`--strict` turns any warning-level diagnostic into a non-zero exit. The SBOM is still written; lynkctl exits `1` because warnings were present. Run with `-v` to see the warnings, then resolve them or remove `--strict`. See [Diagnostics & Exit Codes](/lynkctl/diagnostics).

### What do the exit codes mean?

`0` is success. `1` is a runtime error, a diagnostic error, or a `--strict` run with warnings. `2` is a usage error such as a bad flag or missing path.

### How do I reduce console output?

`lynkctl generate . -q` suppresses the per-SBOM summary line. Errors still print.

### How do I get more diagnostic detail?

`--verbose` (`-v`) is repeatable:

| Flag   | Detail shown                                    |
| ------ | ----------------------------------------------- |
| `-v`   | Per-diagnostic detail and pipeline debug events |
| `-vv`  | Adds debug and provenance detail                |
| `-vvv` | Adds trace-level timing detail                  |

### Can I pipe the SBOM into another tool?

Yes. The SBOM goes to stdout; all diagnostics, summaries, and progress go to stderr, so piping stdout never mixes in diagnostic noise.

## OSS-Index Database

### Do I need the OSS-index database?

Only for vendored open-source identification. If you do not need it, pass `--no-oss-index` and lynkctl skips that step. Otherwise download it once with `lynkctl db download` (roughly 300 MB).

### How do I keep the database current?

`lynkctl db check` compares the cache against the published manifest without changing anything — exit `0` when current, `1` when stale. A common pattern is `lynkctl db check || lynkctl db download`.


# Overview

Interlynk provides a set of open-source command-line tools for SBOM management, quality scoring, and assembly. These tools integrate with the Interlynk platform and can operate standalone in CI/CD pipelines, local development environments, and automated workflows.

***

## Available CLIs

| Tool                                     | Purpose                                                               | Repository                                                        |
| ---------------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [pylynk](/productivity-tools/pylynk)     | CLI client for the Interlynk platform — upload, download, query SBOMs | [interlynk-io/pylynk](https://github.com/interlynk-io/pylynk)     |
| [lynk-mcp](/productivity-tools/lynk-mcp) | MCP server for AI assistant integration with Interlynk                | [interlynk-io/lynk-mcp](https://github.com/interlynk-io/lynk-mcp) |
| [sbomqs](/productivity-tools/sbomqs)     | SBOM quality scoring and compliance validation                        | [interlynk-io/sbomqs](https://github.com/interlynk-io/sbomqs)     |
| [sbomasm](/productivity-tools/sbomasm)   | SBOM assembly — merge, edit, enrich, sign, and view SBOMs             | [interlynk-io/sbomasm](https://github.com/interlynk-io/sbomasm)   |

***

## When to Use Each Tool

| Scenario                                            | Recommended Tool |
| --------------------------------------------------- | ---------------- |
| Upload SBOMs to Interlynk from CI/CD                | pylynk           |
| Download enriched SBOMs from Interlynk              | pylynk           |
| Query vulnerabilities or products programmatically  | pylynk           |
| Set VEX status from a script or in bulk             | pylynk           |
| Generate a license attribution report for a release | pylynk           |
| Natural language SBOM queries via AI assistants     | lynk-mcp         |
| Evaluate SBOM quality before upload                 | sbomqs           |
| Enforce compliance standards (NTIA, BSI)            | sbomqs           |
| Merge multiple SBOMs into one                       | sbomasm          |
| Enrich SBOMs with license data                      | sbomasm          |
| Edit SBOM metadata (supplier, author, version)      | sbomasm          |
| Convert an SBOM to CSV                              | sbomasm          |
| Sign and verify SBOMs                               | sbomasm          |

***

## Authentication

All tools that interact with the Interlynk platform require an API token. See [API Key Management](/administration/api-key-management) for token creation and management.

```bash
# Set once for pylynk
export INTERLYNK_SECURITY_TOKEN="lynk_service_your_token"

# Set once for lynk-mcp
lynk-mcp configure
```

{% hint style="warning" %}
Use **service tokens** for CI/CD and automation. Use **user tokens** only for local, interactive sessions. See [Least Privilege Recommendations](/administration/api-key-management#least-privilege-recommendations).
{% endhint %}


# pylynk

pylynk is the official command-line interface for the Interlynk platform. It provides programmatic access to SBOM upload, download, product management, vulnerability queries, and processing status checks — designed for both interactive use and CI/CD automation.

**Repository:** [github.com/interlynk-io/pylynk](https://github.com/interlynk-io/pylynk)

***

## When to Use pylynk

| Use Case                      | pylynk      | API (curl)  | UI             |
| ----------------------------- | ----------- | ----------- | -------------- |
| CI/CD SBOM upload             | Recommended | Possible    | Not practical  |
| Bulk vulnerability export     | Recommended | Possible    | Manual         |
| Interactive product browsing  | Good        | Verbose     | Best           |
| SBOM download with enrichment | Recommended | Complex     | Manual         |
| One-off queries               | Good        | Good        | Good           |
| Scripted automation           | Recommended | Recommended | Not applicable |

Use pylynk when you need repeatable, scriptable access to the platform. Use the API directly when you need fine-grained control over GraphQL queries. Use the UI for visual exploration and ad hoc operations.

***

## Installation

### pip (from source)

```bash
git clone https://github.com/interlynk-io/pylynk.git
cd pylynk
pip3 install -r requirements.txt
python3 pylynk.py --help
```

### Docker

```bash
# Pull the latest image
docker pull ghcr.io/interlynk-io/pylynk:latest

# Run a command
docker run -e INTERLYNK_SECURITY_TOKEN=$INTERLYNK_SECURITY_TOKEN \
  -v $(pwd):/app/data \
  ghcr.io/interlynk-io/pylynk:latest upload --prod 'my-app' --sbom /app/data/sbom.json
```

### Verify Installation

```bash
python3 pylynk.py version
```

Expected output:

```
pylynk version: v0.x.x
```

***

## Authentication

### Environment Variable (Recommended)

```bash
export INTERLYNK_SECURITY_TOKEN="lynk_service_your_token_here"
```

This is the recommended method for both local use and CI/CD. The token is read automatically by all commands.

### Command-Line Flag

```bash
python3 pylynk.py prods --token "lynk_service_your_token_here"
```

{% hint style="warning" %}
Avoid `--token` in CI/CD — the value may appear in build logs. Always use the environment variable.
{% endhint %}

### API Endpoint Override

The default API endpoint is `https://api.interlynk.io/lynkapi`. Override it with:

```bash
export INTERLYNK_API_URL="https://custom-api.example.com/lynkapi"
```

### Token Security Best Practices

* Store tokens in a secrets manager (Vault, AWS Secrets Manager, GitHub Secrets).
* Never commit tokens to source control.
* Use service tokens for automation; user tokens for interactive sessions.
* Set expiration dates — 90 days for CI/CD, 30 days for development.
* Rotate tokens proactively. See [Rotation Strategy](/administration/api-key-management#rotation-strategy).

***

## Core Commands

### prods — List Products

Lists all products in the organization.

```bash
python3 pylynk.py prods
python3 pylynk.py prods --output json
python3 pylynk.py prods --output csv
python3 pylynk.py prods --human-time
```

| Parameter       | Required | Default | Description                                   |
| --------------- | -------- | ------- | --------------------------------------------- |
| `--output`      | No       | `table` | Output format: `table`, `json`, `csv`         |
| `--human-time`  | No       | Off     | Show relative timestamps (e.g., "2 days ago") |
| `--token`       | No       | Env var | Override authentication token                 |
| `-v, --verbose` | No       | Off     | Enable debug output                           |

**Output columns:** NAME, ID, VERSIONS, UPDATED AT

***

### vers — List Versions

Lists all versions (SBOMs) for a product.

```bash
python3 pylynk.py vers --prod 'my-app'
python3 pylynk.py vers --prod 'my-app' --env 'production' --output json
```

| Parameter       | Required | Default   | Description                           |
| --------------- | -------- | --------- | ------------------------------------- |
| `--prod`        | Yes      | —         | Product name                          |
| `--env`         | No       | `default` | Environment name                      |
| `--output`      | No       | `table`   | Output format: `table`, `json`, `csv` |
| `--human-time`  | No       | Off       | Relative timestamps                   |
| `-v, --verbose` | No       | Off       | Debug output                          |

**Output columns:** ID, VERSION, PRIMARY COMPONENT, UPDATED AT

Use the `ID` value from this output as `--verId` in other commands.

***

### upload — Upload SBOM

Uploads an SBOM file to the platform.

```bash
# Upload to default environment
python3 pylynk.py upload --prod 'my-app' --sbom sbom.json

# Upload to a specific environment
python3 pylynk.py upload --prod 'my-app' --env 'production' --sbom sbom.json

# Upload with custom retry count
python3 pylynk.py upload --prod 'my-app' --sbom sbom.json --retries 5
```

| Parameter       | Required | Default   | Description                       |
| --------------- | -------- | --------- | --------------------------------- |
| `--prod`        | Yes      | —         | Product name                      |
| `--sbom`        | Yes      | —         | Path to SBOM file                 |
| `--env`         | No       | `default` | Target environment                |
| `--retries`     | No       | `3`       | Retry count on transient failures |
| `-v, --verbose` | No       | Off       | Debug output                      |

**Supported formats:** CycloneDX (JSON, XML), SPDX (JSON, tag-value)

**Retry behavior:**

| Condition        | Behavior                                      |
| ---------------- | --------------------------------------------- |
| 5xx server error | Retries with exponential backoff (1s, 2s, 4s) |
| 429 rate limit   | Retries with exponential backoff              |
| 401 unauthorized | Fails immediately — no retry                  |
| Other 4xx        | Fails immediately — no retry                  |
| Network error    | Retries with exponential backoff              |

**CI metadata:** When running in a CI environment (`CI=true`), pylynk automatically captures build metadata (PR number, commit SHA, branch name, build URL) and sends it as HTTP headers with the upload.

***

### gate — Policy Gate for CI/CD

Returns a single pass/fail policy verdict for one SBOM version and exits non-zero when it does not pass. Run it after `upload` to block a pull request on policy failures.

```bash
# Gate on the version uploaded by this CI run
python3 pylynk.py gate --prod 'my-app' --env 'production' --ver 'v1.2.3'

# Block on warn-severity policies as well, with a longer budget for large SBOMs
python3 pylynk.py gate --prod 'my-app' --ver 'v1.2.3' --fail-on warn --timeout 900

# Gate on a single policy by name
python3 pylynk.py gate --prod 'my-app' --env 'default' --ver 'v1.2.3' --policy-name 'No criticals'

# One-shot check of an existing version, machine-readable
python3 pylynk.py gate --verId 'abc-123' --no-wait --output json
```

| Parameter         | Required    | Default   | Description                                                  |
| ----------------- | ----------- | --------- | ------------------------------------------------------------ |
| `--prod`          | Conditional | —         | Product name (use with `--env` and `--ver`)                  |
| `--env`           | No          | `default` | Environment name                                             |
| `--ver`           | Conditional | —         | Version name (mutually exclusive with `--verId`)             |
| `--verId`         | Conditional | —         | Version ID (mutually exclusive with `--ver`)                 |
| `--fail-on`       | No          | `fail`    | Lowest policy severity that blocks: `fail` or `warn`         |
| `--policy-name`   | No          | —         | Gate on one active policy by exact name                      |
| `--policy-id`     | No          | —         | Gate on one active policy by ID                              |
| `--no-wait`       | No          | Off       | Check the current state once instead of waiting for the scan |
| `--timeout`       | No          | `600`     | Total seconds to wait for version resolution and policy scan |
| `--poll-interval` | No          | `15`      | Seconds between polls                                        |
| `--output`        | No          | `table`   | Output format: `table` or `json`                             |

An explicit version is required. Unlike other commands, `gate` does not fall back to the latest version, because that is racy when parallel CI runs upload concurrently.

**Statuses and exit codes:**

| Status          | Exit | Meaning                                                                             |
| --------------- | :--: | ----------------------------------------------------------------------------------- |
| `PASS`          |   0  | All active policies evaluated, no blocking violations                               |
| `NO_POLICIES`   |   0  | The organization has no active policies (a warning is printed)                      |
| `FAIL`          |   3  | At least one active policy of blocking severity was violated                        |
| `IN_PROGRESS`   |   4  | Scan still queued or running when the timeout was reached                           |
| `ERROR`         |   4  | Evaluation incomplete or errored, such as an interrupted scan                       |
| `NOT_EVALUATED` |   4  | No policy scan applies, such as vulnerability scanning disabled for the environment |

Exit `4` is the fail-closed case. An incomplete scan never reads as a pass. Exit codes `3` and `4` are distinct so pipelines can alert differently on a real policy failure than on a scan that never completed.

**Waiting behavior:** policy evaluation runs asynchronously after upload, chained behind the vulnerability scan. By default `gate` first retries version resolution until the uploaded version appears, then polls the verdict until the scan finishes. Both phases share the single `--timeout` budget.

**Requirements:** the token's role must grant the `View Policies` permission (all built-in roles include it). `--ver` must match the primary component version embedded in the uploaded SBOM, the same value shown by `pylynk vers`.

**Example output:**

```
Policy gate: FAIL
  Policies evaluated: 2 (passed: 1, failed: 1, warned: 0, skipped: 0, errored: 0)

POLICY       | SEVERITY | VIOLATIONS
-------------|----------|-----------
No criticals | fail     | 4
```

Counts are per policy, not per violation. A policy with four violations counts once as `failed`.

***

### download — Download SBOM

Downloads an SBOM from the platform, optionally enriched with vulnerabilities, support status, or converted to a different format.

```bash
# Download by version ID
python3 pylynk.py download --verId 'abc-123' --out-file sbom.json

# Download by product/environment/version
python3 pylynk.py download --prod 'my-app' --env 'default' --ver 'v1.0.0' --out-file sbom.json

# Download with vulnerabilities included
python3 pylynk.py download --verId 'abc-123' --vuln true --out-file enriched.json

# Download in a specific format
python3 pylynk.py download --verId 'abc-123' --spec CycloneDX --spec-version 1.5

# Download the original uploaded SBOM (unmodified)
python3 pylynk.py download --verId 'abc-123' --original --out-file original.json

# Download a lite version
python3 pylynk.py download --verId 'abc-123' --lite --out-file lite.json

# Include support status metadata
python3 pylynk.py download --verId 'abc-123' --include-support-status --out-file sbom.json

# Export support levels only (CSV)
python3 pylynk.py download --verId 'abc-123' --support-level-only --out-file support.csv
```

**Identification — provide one of:**

| Method        | Parameters Required          |
| ------------- | ---------------------------- |
| By version ID | `--verId`                    |
| By name       | `--prod` + `--env` + `--ver` |

| Parameter                  | Required    | Default  | Description                              |
| -------------------------- | ----------- | -------- | ---------------------------------------- |
| `--verId`                  | Conditional | —        | Version ID (from `vers` command output)  |
| `--prod`                   | Conditional | —        | Product name                             |
| `--env`                    | Conditional | —        | Environment name                         |
| `--ver`                    | Conditional | —        | Version name                             |
| `--out-file`               | No          | stdout   | Output file path                         |
| `--vuln`                   | No          | `false`  | Include vulnerabilities (`true`/`false`) |
| `--spec`                   | No          | Original | Output spec: `SPDX` or `CycloneDX`       |
| `--spec-version`           | No          | Original | Spec version (e.g., `2.3`, `1.5`)        |
| `--lite`                   | No          | Off      | Download lightweight version             |
| `--original`               | No          | Off      | Download exact uploaded SBOM             |
| `--dont-package-sbom`      | No          | Off      | Keep multi-SBOM files separate           |
| `--exclude-parts`          | No          | Off      | Exclude linked parts                     |
| `--include-support-status` | No          | Off      | Add support status metadata              |
| `--support-level-only`     | No          | Off      | CSV output with support levels only      |

***

### vulns — List Vulnerabilities

Queries vulnerabilities across products.

```bash
# All vulnerabilities for a product
python3 pylynk.py vulns --prod 'my-app'

# With vulnerability and VEX details
python3 pylynk.py vulns --prod 'my-app' --vuln-details --vex-details

# Specific version
python3 pylynk.py vulns --prod 'my-app' --verId 'abc-123'

# JSON export
python3 pylynk.py vulns --prod 'my-app' --output json > vulns.json

# CSV export for spreadsheet analysis
python3 pylynk.py vulns --prod 'my-app' --output csv > vulns.csv

# Custom column selection
python3 pylynk.py vulns --prod 'my-app' --columns 'id,component_name,severity,cvss,status'

# List all available columns
python3 pylynk.py vulns --list-columns
```

| Parameter             | Required | Default     | Description                                                |
| --------------------- | -------- | ----------- | ---------------------------------------------------------- |
| `--prod`              | No       | —           | Product name (uses latest version if no version specified) |
| `--env`               | No       | `default`   | Environment name                                           |
| `--verId`             | No       | —           | Specific version ID                                        |
| `--ver`               | No       | —           | Version name                                               |
| `--output`            | No       | `table`     | Output format: `table`, `json`, `csv`                      |
| `--columns`           | No       | Default set | Comma-separated column names                               |
| `--vuln-details`      | No       | Off         | Include severity, CVSS, EPSS, KEV, CWE                     |
| `--vex-details`       | No       | Off         | Include VEX status, justification, actions                 |
| `--timestamp-details` | No       | Off         | Include all timestamp columns                              |
| `--human-time`        | No       | Off         | Relative timestamps                                        |
| `--list-columns`      | No       | —           | Display available column names and exit                    |

**Default columns:** id, part\_name, part\_version, component\_name, component\_version, severity, source, status, assigned

**Vulnerability detail columns (`--vuln-details`):** severity, kev, cvss, cvss\_vector, epss, cwe

**VEX detail columns (`--vex-details`):** status, details, justification, action\_statement, impact\_statement, response

***

### status — Check Processing Status

Checks the processing status of an uploaded SBOM.

```bash
python3 pylynk.py status --prod 'my-app' --verId 'abc-123'
python3 pylynk.py status --prod 'my-app' --env 'production' --ver 'v1.0.0'
```

| Parameter  | Required    | Default   | Description                     |
| ---------- | ----------- | --------- | ------------------------------- |
| `--prod`   | Yes         | —         | Product name                    |
| `--verId`  | Conditional | —         | Version ID                      |
| `--ver`    | Conditional | —         | Version name (requires `--env`) |
| `--env`    | No          | `default` | Environment name                |
| `--output` | No          | `table`   | Output format: `table`, `json`  |

**Status types tracked:**

| Status           | Description                    |
| ---------------- | ------------------------------ |
| checksStatus     | SBOM quality and format checks |
| policyStatus     | Policy evaluation              |
| labelingStatus   | Internal labeling              |
| automationStatus | Automation rule execution      |
| vulnScanStatus   | Vulnerability scanning         |

**Status values:** `UNKNOWN`, `NOT_STARTED`, `IN_PROGRESS`, `COMPLETED`

***

### vex — Update VEX Data

Sets VEX disposition on component vulnerabilities from the command line, one at a time or in bulk.

**Update a single component vulnerability:**

```bash
python3 pylynk.py vex update --prod 'my-app' --ver 'v1.0.0' \
  --vuln CVE-2024-1234 --component lodash --status not_affected

python3 pylynk.py vex update --verId 'abc-123' \
  --component-vuln-id 'def-456' --status-id 'status-uuid'
```

Identify the target with either `--component-vuln-id` or `--vuln`; the two are mutually exclusive and one is required. `--component` and `--component-version` narrow a `--vuln` match to one component.

**Update several at once:**

```bash
# From a file
python3 pylynk.py vex bulk-update --prod 'my-app' --ver 'v1.0.0' --file vex-updates.csv

# From repeated IDs
python3 pylynk.py vex bulk-update --verId 'abc-123' \
  --component-vuln-id 'def-456' --component-vuln-id 'ghi-789' --status affected
```

`--file` accepts CSV or JSON. Rows may carry `component_vuln_id` directly, or the `vuln`, `component`, and `component_version` names instead.

**VEX fields (both actions):**

| Parameter                                | Description                                                           |
| ---------------------------------------- | --------------------------------------------------------------------- |
| `--status` / `--status-id`               | VEX status, by name or ID                                             |
| `--justification` / `--justification-id` | Justification, by name or ID                                          |
| `--response` / `--response-id`           | CycloneDX response, by name or ID                                     |
| `--note`                                 | VEX note                                                              |
| `--impact`                               | Impact statement                                                      |
| `--detail`                               | VEX detail                                                            |
| `--action`                               | Action statement                                                      |
| `--fixed-in`                             | Fixed-in version                                                      |
| `--propagate` / `--no-propagate`         | Apply the disposition to related component vulnerabilities, or do not |
| `--custom-fields-file`                   | JSON file of component vulnerability custom field values              |
| `--output`                               | Output format: `table` (default), `json`                              |

For the status and justification vocabularies, see [Vulnerabilities](/product-guides/security-and-compliance/vulnerabilities#vex-status-vulnerability-disposition). For custom fields, see [Vulnerability Custom Fields](/administration/vulnerability-custom-fields).

***

### report — Generate Reports

Generates a report for one Version. The attribution report lists the components and their licenses, for shipping alongside a release.

```bash
python3 pylynk.py report --type attribution --prod 'my-app' --env 'production' --ver 'v1.0.0'

# Include the full license text
python3 pylynk.py report --type attribution --prod 'my-app' --env 'default' --ver 'v1.0.0' \
  --include-license-text

# Choose the output path
python3 pylynk.py report --type attribution --prod 'my-app' --env 'default' --ver 'v1.0.0' \
  --output-file report.csv
```

| Parameter                | Required | Default                     | Description                                  |
| ------------------------ | -------- | --------------------------- | -------------------------------------------- |
| `--type`                 | Yes      | —                           | Report type. Currently `attribution`         |
| `--prod`                 | Yes      | —                           | Product name                                 |
| `--env`                  | No       | `default`                   | Environment name                             |
| `--ver`                  | No       | latest                      | Version name. Omit to use the latest version |
| `--include-license-text` | No       | Off                         | Include full license text in the output      |
| `--output-file`          | No       | `attribution_<product>.csv` | Output file path                             |

***

### version — Show CLI Version

```bash
python3 pylynk.py version
```

***

## CI/CD Integration

### GitHub Actions

```yaml
name: Upload SBOM
on:
  push:
    branches: [main]
  release:
    types: [published]

jobs:
  upload-sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate SBOM
        run: |
          # Use your preferred SBOM generator
          syft . -o cyclonedx-json > sbom.cdx.json

      - name: Upload SBOM to Interlynk
        env:
          INTERLYNK_SECURITY_TOKEN: ${{ secrets.INTERLYNK_SERVICE_TOKEN }}
        run: |
          pip3 install -r requirements.txt
          python3 pylynk.py upload --prod '${{ github.event.repository.name }}' --sbom sbom.cdx.json

      - name: Policy gate (blocks the PR on failure)
        env:
          INTERLYNK_SECURITY_TOKEN: ${{ secrets.INTERLYNK_SERVICE_TOKEN }}
        run: |
          python3 pylynk.py gate --prod '${{ github.event.repository.name }}' \
            --env 'default' --ver '${{ github.sha }}' --timeout 600
```

### GitLab CI

```yaml
upload-sbom:
  stage: deploy
  image: python:3.11
  variables:
    INTERLYNK_SECURITY_TOKEN: $INTERLYNK_SERVICE_TOKEN
  script:
    - pip3 install -r requirements.txt
    - python3 pylynk.py upload --prod 'my-app' --sbom sbom.cdx.json
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
    - if: '$CI_COMMIT_TAG'
```

### Bitbucket Pipelines

```yaml
pipelines:
  branches:
    main:
      - step:
          name: Upload SBOM
          image: python:3.11
          script:
            - pip3 install -r requirements.txt
            - python3 pylynk.py upload --prod 'my-app' --sbom sbom.cdx.json
  tags:
    'v*':
      - step:
          name: Upload Release SBOM
          image: python:3.11
          script:
            - pip3 install -r requirements.txt
            - python3 pylynk.py upload --prod 'my-app' --sbom sbom.cdx.json
```

### Azure DevOps

```yaml
trigger:
  branches:
    include: [main]
  tags:
    include: ['v*']

steps:
  - script: pip3 install -r requirements.txt
    displayName: 'Install pylynk'
  - script: python3 pylynk.py upload --prod 'my-app' --sbom sbom.cdx.json
    displayName: 'Upload SBOM'
    env:
      INTERLYNK_SECURITY_TOKEN: $(INTERLYNK_SERVICE_TOKEN)
```

### Docker-Based CI

For environments where Python installation is not practical:

```yaml
# GitHub Actions with Docker
- name: Upload SBOM
  run: |
    docker run --rm \
      -e INTERLYNK_SECURITY_TOKEN=${{ secrets.INTERLYNK_SERVICE_TOKEN }} \
      -v $(pwd):/app/data \
      ghcr.io/interlynk-io/pylynk:latest \
      upload --prod 'my-app' --sbom /app/data/sbom.cdx.json
```

### Handling Secrets Securely

| CI Platform    | Secret Storage                 | Reference Syntax                         |
| -------------- | ------------------------------ | ---------------------------------------- |
| GitHub Actions | Repository Secrets             | `${{ secrets.INTERLYNK_SERVICE_TOKEN }}` |
| GitLab CI      | CI/CD Variables (masked)       | `$INTERLYNK_SERVICE_TOKEN`               |
| Bitbucket      | Repository Variables (secured) | `$INTERLYNK_SERVICE_TOKEN`               |
| Azure DevOps   | Pipeline Variables (secret)    | `$(INTERLYNK_SERVICE_TOKEN)`             |

{% hint style="warning" %}
Always mark the variable as **secret/masked** in your CI platform to prevent it from appearing in build logs.
{% endhint %}

### Fail-the-Build Patterns

Use exit codes to gate builds on SBOM upload success:

```bash
# Fail if upload fails
python3 pylynk.py upload --prod 'my-app' --sbom sbom.json || exit 1
```

To block the build on policy failures, use [`gate`](#gate-policy-gate-for-ci-cd). It waits for the asynchronous policy scan and returns the verdict as an exit code, so no manual polling or `sleep` is needed:

```bash
python3 pylynk.py upload --prod 'my-app' --env 'production' --sbom sbom.json
python3 pylynk.py gate --prod 'my-app' --env 'production' --ver "$VERSION" --timeout 600
```

Exit `3` means a policy of blocking severity was violated. Exit `4` means the scan never produced a verdict within the timeout, which is treated as a failure rather than a pass.

{% hint style="warning" %}
Do not gate a build on `pylynk status` output. `status` reports whether processing stages have finished, not whether the SBOM passed its policies. A completed policy stage says nothing about the verdict.
{% endhint %}

### CI Metadata

When `CI=true` is set (automatically by most CI platforms), pylynk captures build metadata and sends it with uploads:

| Header               | Description                                 |
| -------------------- | ------------------------------------------- |
| `X-CI-Provider`      | CI platform name                            |
| `X-Event-Type`       | Trigger type (push, pull\_request, release) |
| `X-PR-Number`        | Pull request number                         |
| `X-Commit-SHA`       | Git commit hash                             |
| `X-Repository-URL`   | Repository URL                              |
| `X-Build-URL`        | Build/job URL                               |
| `X-PR-Source-Branch` | Source branch name                          |
| `X-PR-Target-Branch` | Target branch name                          |

Control metadata collection:

```bash
export PYLYNK_INCLUDE_CI_METADATA=auto   # Default — enabled only in CI
export PYLYNK_INCLUDE_CI_METADATA=true   # Force enable
export PYLYNK_INCLUDE_CI_METADATA=false  # Disable
```

***

## Troubleshooting

### Debug Mode

Enable verbose logging with `-v` or `--verbose`:

```bash
python3 pylynk.py upload --prod 'my-app' --sbom sbom.json -v
python3 pylynk.py prods -vv  # More detailed output
```

Debug output includes: API request/response details, token validation (masked), CI metadata detection, upload speed metrics, and timing information.

### Common Errors

| Error                                  | Cause                              | Resolution                                                   |
| -------------------------------------- | ---------------------------------- | ------------------------------------------------------------ |
| `Security token not found`             | `INTERLYNK_SECURITY_TOKEN` not set | Export the environment variable or use `--token`             |
| `Authentication failed`                | Invalid or expired token           | Verify token in UI; create a new one if expired              |
| `Product not found`                    | Typo in product name or no access  | Run `pylynk prods` to list available products                |
| `Version not found`                    | Invalid version ID or name         | Run `pylynk vers --prod 'name'` to list versions             |
| `File not found`                       | Bad SBOM file path                 | Verify path; use absolute paths in Docker                    |
| `Request failed with status code: 429` | Rate limited                       | Automatic retry handles this; increase `--retries` if needed |
| `RequestException`                     | Network or connectivity issue      | Check firewall, proxy, and `INTERLYNK_API_URL`               |
| `Error uploading sbom`                 | Invalid SBOM format                | Verify SBOM is valid CycloneDX or SPDX                       |

### Exit Codes

| Code | Meaning                                                                |
| ---- | ---------------------------------------------------------------------- |
| `0`  | Success                                                                |
| `1`  | General error (authentication, network, or version resolution failure) |
| `2`  | Argument parsing error                                                 |
| `3`  | Policy gate failed (`gate` only)                                       |
| `4`  | Policy gate could not reach a verdict (`gate` only)                    |

Codes `3` and `4` are returned only by [`gate`](#gate-policy-gate-for-ci-cd). Treat any non-zero exit as blocking in CI.

***

## Best Practices

### Least Privilege Token Usage

Create service tokens with the minimum role required:

| Workflow                      | Recommended Role                   |
| ----------------------------- | ---------------------------------- |
| SBOM upload only              | Custom role with upload permission |
| Upload + vulnerability review | Operator                           |
| Full automation               | Admin (use sparingly)              |
| Read-only reporting           | Viewer                             |

### Automation Design Patterns

* **Idempotent uploads:** Uploading the same SBOM twice to the same product/environment creates a new version. Design pipelines to upload only on meaningful changes.
* **Environment separation:** Use `--env` to separate staging, production, and development SBOMs.
* **Version tracking:** Capture the version ID from `vers` output after upload for downstream status checks.
* **Error handling:** Always check exit codes. Use `--retries 0` to disable retries when you need fast failure.

### Parallel vs Serial Execution

* **Serial:** Upload SBOMs for the same product sequentially to avoid race conditions on version ordering.
* **Parallel:** Upload SBOMs for different products concurrently. Each product is independent.
* **Status polling:** Wait for `COMPLETED` status before downloading enriched SBOMs. Processing is asynchronous.

***

## Common Misconfigurations

| Issue                         | Symptom                         | Fix                                                  |
| ----------------------------- | ------------------------------- | ---------------------------------------------------- |
| Token in `--token` flag in CI | Token visible in build logs     | Use `INTERLYNK_SECURITY_TOKEN` env var               |
| Wrong `INTERLYNK_API_URL`     | Connection errors or 401        | Verify URL or remove the override to use default     |
| Missing `--prod` on upload    | Argument parsing error          | Always specify `--prod` with upload                  |
| Docker volume not mounted     | File not found inside container | Add `-v $(pwd):/app/data` and use `/app/data/` paths |
| Using `--ver` without `--env` | Version not found               | Provide both `--env` and `--ver` together            |
| Old pylynk version            | Unexpected API errors           | Pull latest from repository or Docker image          |


# lynk-mcp

lynk-mcp is an MCP (Model Context Protocol) server that enables AI assistants — Claude, Cursor, VS Code Copilot, and Zed — to query the Interlynk platform using natural language. It exposes SBOM data, vulnerability information, policy results, and compliance status through a standardized tool interface.

**Repository:** [github.com/interlynk-io/lynk-mcp](https://github.com/interlynk-io/lynk-mcp)

***

## When to Use lynk-mcp vs pylynk

| Use Case                                 | lynk-mcp       | pylynk         |
| ---------------------------------------- | -------------- | -------------- |
| Natural language queries about SBOMs     | Best           | Not applicable |
| CI/CD SBOM uploads                       | Not applicable | Best           |
| AI-assisted vulnerability triage         | Best           | Manual         |
| Scripted automation                      | Not applicable | Best           |
| Interactive exploration via AI assistant | Best           | CLI only       |
| Drift analysis between versions          | Built-in       | Manual         |

Use lynk-mcp when your workflow involves AI assistants and conversational interaction. Use pylynk for scripted, non-interactive automation.

***

## Architecture

```
┌───────────────────────┐
│   AI Assistant        │
│ (Claude, Cursor, etc) │
└──────────┬────────────┘
           │ MCP Protocol (stdio)
           │
┌──────────▼────────────┐
│     lynk-mcp          │
│   ┌───────────────┐   │
│   │  MCP Server   │   │
│   │  (24 Tools)   │   │
│   └───────┬───────┘   │
│   ┌───────▼───────┐   │
│   │ GraphQL Client│   │
│   └───────┬───────┘   │
│   ┌───────▼───────┐   │
│   │  Config &     │   │
│   │  Keyring      │   │
│   └───────────────┘   │
└──────────┬────────────┘
           │ HTTPS + Bearer Token
           │
┌──────────▼────────────┐
│  Interlynk API        │
│  (GraphQL endpoint)   │
└───────────────────────┘
```

The MCP server runs as a local process. The AI assistant communicates with it over stdio using the MCP protocol. The server translates tool calls into GraphQL queries against the Interlynk API and returns structured responses.

***

## Setup

### Installation

**Homebrew (macOS/Linux):**

```bash
brew install interlynk-io/tap/lynk-mcp
```

**Go Install:**

```bash
go install github.com/interlynk-io/lynk-mcp/cmd/lynk-mcp@latest
```

**Docker:**

```bash
docker pull ghcr.io/interlynk-io/lynk-mcp:latest
```

**From Source:**

```bash
git clone https://github.com/interlynk-io/lynk-mcp.git
cd lynk-mcp
make build
```

### Configuration

Run the interactive configuration:

```bash
lynk-mcp configure
```

This prompts for:

1. **API Endpoint** — defaults to `https://api.interlynk.io/lynkapi`
2. **API Token** — must start with `lynk_live_`, `lynk_staging_`, or `lynk_test_`

The token is stored securely in the system keychain. The endpoint and logging configuration are saved to `~/.lynk-mcp/config.yaml`.

### Verify Connection

```bash
lynk-mcp verify
```

A successful response displays the organization name and confirms connectivity. The verify command includes retry logic (up to \~6 minutes) to account for token propagation delays.

### Environment Variables

| Variable                 | Description                                 | Default                            |
| ------------------------ | ------------------------------------------- | ---------------------------------- |
| `LYNK_API_TOKEN`         | API token (overrides keychain)              | —                                  |
| `LYNK_MCP_API_ENDPOINT`  | API endpoint override                       | `https://api.interlynk.io/lynkapi` |
| `LYNK_MCP_LOGGING_LEVEL` | Log level: `debug`, `info`, `warn`, `error` | `info`                             |

### Configuration File

Location: `~/.lynk-mcp/config.yaml`

```yaml
api:
  endpoint: "https://api.interlynk.io/lynkapi"
  timeout: 30s
logging:
  level: "info"
```

***

## Connecting to AI Assistants

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "lynk": {
      "command": "lynk-mcp",
      "args": ["serve"]
    }
  }
}
```

### Claude Code (CLI)

```bash
claude mcp add lynk -- lynk-mcp serve
```

### VS Code (v1.99+)

Add to `.vscode/mcp.json`:

```json
{
  "mcp": {
    "servers": {
      "lynk": {
        "command": "lynk-mcp",
        "args": ["serve"]
      }
    }
  }
}
```

### Cursor

Add to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "lynk": {
      "command": "lynk-mcp",
      "args": ["serve"]
    }
  }
}
```

### Zed

Add to `~/.config/zed/settings.json`:

```json
{
  "context_servers": {
    "lynk": {
      "command": {
        "path": "lynk-mcp",
        "args": ["serve"]
      }
    }
  }
}
```

### Docker-Based Setup

For environments where local installation is not practical:

```json
{
  "mcpServers": {
    "lynk": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "LYNK_API_TOKEN=lynk_live_your_token",
        "ghcr.io/interlynk-io/lynk-mcp",
        "serve"
      ]
    }
  }
}
```

***

## Available Tools

The MCP server exposes 24 tools organized into five categories.

### Organization & Products

| Tool                | Parameters                        | Description                        |
| ------------------- | --------------------------------- | ---------------------------------- |
| `get_organization`  | —                                 | Organization info and metrics      |
| `list_products`     | `search`, `limit`                 | List products with optional search |
| `get_product`       | `id` (required)                   | Product details with environments  |
| `list_environments` | `product_id` (required), `search` | Environments in a product          |
| `get_environment`   | `id` (required)                   | Environment details                |

### Versions & Components

| Tool               | Parameters                                                   | Description                         |
| ------------------ | ------------------------------------------------------------ | ----------------------------------- |
| `list_versions`    | `environment_id` (required), `lifecycle`, `limit`            | Versions in an environment          |
| `get_version`      | `id` (required)                                              | Version details with statistics     |
| `list_components`  | `version_id` (required), `search`, `kind`, `direct`, `limit` | Components in a version             |
| `get_component`    | `id` (required), `version_id` (required)                     | Component details                   |
| `compare_versions` | `source_version_id`, `target_version_id` (both required)     | Drift analysis between two versions |

### Vulnerabilities

| Tool                     | Parameters                                                                  | Description                        |
| ------------------------ | --------------------------------------------------------------------------- | ---------------------------------- |
| `list_vulnerabilities`   | `version_id` (required), `severity`, `vex_status`, `kev`, `search`, `limit` | Filtered vulnerability list        |
| `get_vulnerability`      | `vuln_id` (required)                                                        | Vulnerability by CVE ID or UUID    |
| `search_vulnerabilities` | `search`, `severity`, `kev`, `limit`                                        | Cross-product vulnerability search |

**Vulnerability filters:**

| Filter       | Values                                             |
| ------------ | -------------------------------------------------- |
| `severity`   | `critical`, `high`, `medium`, `low`                |
| `vex_status` | `affected`, `not_affected`, `fixed`                |
| `kev`        | `true` / `false` (Known Exploited Vulnerabilities) |

### Policies & Compliance

| Tool                     | Parameters                                        | Description                    |
| ------------------------ | ------------------------------------------------- | ------------------------------ |
| `list_policies`          | `search`, `limit`                                 | List security policies         |
| `get_policy`             | `id` (required)                                   | Policy details with rules      |
| `list_policy_violations` | `policy_id`, `version_id`, `result_type`, `limit` | Policy evaluation results      |
| `list_licenses`          | `status`, `search`, `limit`                       | Organization license inventory |

**License filters:**

| Filter   | Values                                |
| -------- | ------------------------------------- |
| `status` | `approved`, `rejected`, `unspecified` |

### Resources

MCP resources provide structured access to complete datasets:

| Resource URI                                     | Description                      |
| ------------------------------------------------ | -------------------------------- |
| `version:///{version_id}`                        | Complete version information     |
| `version:///{version_id}/components`             | All components (up to 1000)      |
| `version:///{version_id}/vulnerabilities`        | All vulnerabilities (up to 1000) |
| `environment:///{environment_id}/latest-version` | Most recent version              |
| `organization:///summary`                        | Organization overview            |
| `vulnerability:///{cve_id}`                      | Vulnerability details by CVE     |

***

## Security Considerations

### Token Storage

lynk-mcp stores API tokens in the system keychain:

| Platform | Storage Backend                                |
| -------- | ---------------------------------------------- |
| macOS    | Keychain (login keychain)                      |
| Windows  | Credential Manager                             |
| Linux    | Secret Service (or file-based with encryption) |

Tokens are never written to the configuration file or logged to stderr.

### Token Format

Valid token prefixes: `lynk_live_`, `lynk_staging_`, `lynk_test_`. The `configure` command validates the format before storing.

### Access Control

* All API requests are scoped to the organization associated with the token.
* Users can only access data their token's role permits.
* The MCP server does not add, modify, or elevate permissions beyond what the token provides.

### Isolation Recommendations

* Run lynk-mcp as a dedicated process per user session. Do not share a single instance across multiple users.
* In Docker deployments, pass the token via environment variable rather than mounting configuration files.
* Use service tokens with read-only roles for MCP access unless write operations are explicitly needed.
* In production environments, restrict the `LYNK_API_TOKEN` to the minimum required role (typically Viewer or Operator).

***

## Example Workflows

### Vulnerability Triage

Ask your AI assistant:

> "Show me all critical vulnerabilities with KEV status across my organization."

The assistant calls `search_vulnerabilities(severity="critical", kev=true)` and returns CVE details with EPSS/CVSS scores, allowing you to prioritize remediation.

### Drift Analysis

> "Compare the last two releases of my-app in production and highlight security-relevant changes."

The assistant calls `list_versions`, then `compare_versions`, returning component additions, removals, and version changes between releases.

### Policy Compliance Review

> "Which products are currently failing security policies?"

The assistant calls `list_policy_violations(result_type="fail")`, groups results by product, and presents violations with the associated policy rules.

### License Audit

> "Find all GPL-licensed components in my organization."

The assistant calls `list_licenses(search="GPL")` and summarizes license distribution, highlighting deprecated or restrictive licenses.

### Component Search

> "Do any of my products use log4j?"

The assistant calls `search_vulnerabilities(search="log4j")` or iterates through products and environments calling `list_components(search="log4j")` to locate all instances.

***

## Debugging & Observability

### Logging Configuration

Set the log level via environment variable:

```bash
LYNK_MCP_LOGGING_LEVEL=debug lynk-mcp serve
```

| Level   | Output                                                |
| ------- | ----------------------------------------------------- |
| `debug` | Full request/response details, retry attempts, timing |
| `info`  | Startup, connection events (default)                  |
| `warn`  | Recoverable issues                                    |
| `error` | Failures only                                         |

Logs are written to stderr in JSON format. They do not interfere with MCP protocol communication on stdout.

### Monitoring Recommendations

* Monitor the `lynk-mcp` process for unexpected exits. AI assistants typically restart the process automatically, but persistent crashes indicate configuration issues.
* Check `~/.lynk-mcp/config.yaml` exists and contains a valid endpoint.
* Run `lynk-mcp verify` periodically to confirm token validity and API connectivity.

### Common Issues

| Issue                          | Cause                                      | Resolution                                                               |
| ------------------------------ | ------------------------------------------ | ------------------------------------------------------------------------ |
| AI assistant cannot find tools | lynk-mcp not configured in assistant       | Add MCP server configuration (see Connecting to AI Assistants)           |
| `token not found`              | Keychain empty and no `LYNK_API_TOKEN` set | Run `lynk-mcp configure` or set the environment variable                 |
| `invalid token format`         | Token does not start with valid prefix     | Use a token starting with `lynk_live_`, `lynk_staging_`, or `lynk_test_` |
| Connection timeout             | Network or firewall blocking API           | Verify HTTPS access to `api.interlynk.io`; check proxy settings          |
| Verify command hangs           | Token propagation delay                    | Wait up to 6 minutes; the verify command retries automatically           |
| Docker: keychain not available | No system keychain in container            | Pass token via `LYNK_API_TOKEN` environment variable                     |

***

## Common Misconfigurations

| Issue                                           | Symptom                                 | Fix                                                                                     |
| ----------------------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------- |
| Token stored in config file instead of keychain | Security risk — plaintext token on disk | Run `lynk-mcp configure` to store in keychain                                           |
| Wrong API endpoint                              | All queries return errors               | Verify `api.endpoint` in `~/.lynk-mcp/config.yaml`                                      |
| Admin token used for read-only MCP access       | Excessive permissions                   | Create a Viewer or Operator service token                                               |
| lynk-mcp binary not in PATH                     | AI assistant fails to start the server  | Install via Homebrew or add binary location to PATH                                     |
| Multiple AI assistants sharing one config       | Token collisions in keychain            | Each instance reads the same keychain entry — this is fine for same-organization access |


# sbomqs

sbomqs evaluates the quality of Software Bills of Materials (SBOMs) and validates compliance against industry standards. It scores SBOMs on a 0–10 scale across multiple quality dimensions — identification, provenance, integrity, licensing, vulnerability readiness, and structural correctness — and provides actionable feedback for improvement.

**Repository:** [github.com/interlynk-io/sbomqs](https://github.com/interlynk-io/sbomqs)

***

## How Scoring Works

sbomqs evaluates SBOMs across 8 weighted categories, each containing multiple features:

| Category          | Weight        | What It Measures                                                          |
| ----------------- | ------------- | ------------------------------------------------------------------------- |
| Identification    | 10            | Component names, versions, unique identifiers                             |
| Provenance        | 12            | Creation timestamp, authors, tool info, supplier, namespace               |
| Integrity         | 15            | Checksums (SHA-256+), SBOM signatures                                     |
| Completeness      | 12            | Dependencies, primary component, source URIs, suppliers                   |
| Licensing         | 15            | License info quality, SPDX validity, deprecated/restrictive detection     |
| Vulnerability     | 10            | CPE/PURL identifiers for vulnerability lookup                             |
| Structural        | 8             | Spec compliance, version, file format, schema validation                  |
| Component Quality | Informational | PURL and CPE validation against package registries and the NVD dictionary |

Each feature is scored 0–10. Category scores are the average of their features. The overall score is the weighted average of all categories.

Component Quality is reported but excluded from the overall score. Its checks call the Interlynk API, so they run only with `--enable-component-analysis` and an API key:

```bash
sbomqs score --enable-component-analysis --api-key "your-api-key" sbom.json
```

The key can also come from the `INTERLYNK_SECURITY_TOKEN` environment variable.

**Grade scale:**

| Grade | Score Range |
| ----- | ----------- |
| A     | 9.0 – 10.0  |
| B     | 8.0 – 8.9   |
| C     | 7.0 – 7.9   |
| D     | 5.0 – 6.9   |
| F     | below 5.0   |

### Supported SBOM Formats

* **SPDX:** 2.2.1, 2.3, 3.0 (partial)
* **CycloneDX:** 1.4, 1.5, 1.6
* **File formats:** JSON, XML, Tag-Value
* Format and spec version are auto-detected.

***

## Installation

### Homebrew (macOS/Linux)

```bash
brew tap interlynk-io/interlynk
brew install sbomqs
```

### Go Install

```bash
go install github.com/interlynk-io/sbomqs@latest
```

### Pre-Built Binaries

Download from the [GitHub releases page](https://github.com/interlynk-io/sbomqs/releases) for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64).

### Linux Packages

```bash
# Debian/Ubuntu
sudo dpkg -i sbomqs_*_amd64.deb

# RedHat/CentOS
sudo rpm -i sbomqs_*_amd64.rpm
```

### Docker

```bash
docker run ghcr.io/interlynk-io/sbomqs:latest score sbom.json
```

Mount local files:

```bash
docker run -v $(pwd):/data ghcr.io/interlynk-io/sbomqs:latest score /data/sbom.json
```

### Build from Source

```bash
git clone https://github.com/interlynk-io/sbomqs.git
cd sbomqs
make build
```

### Verify Installation

```bash
sbomqs version
```

***

## Running a Scan

### Basic Score

```bash
sbomqs score sbom.json
```

### Output Formats

```bash
# Detailed table (default)
sbomqs score --detailed sbom.json

# Single-line summary
sbomqs score --basic sbom.json

# JSON for automation
sbomqs score --json sbom.json

# Color-coded table
sbomqs score --color sbom.json
```

**Basic output example:**

```
7.8 interlynk cyclonedx 1.6 json sbom.json
```

**JSON output structure:**

```json
{
  "run_id": "abc-123",
  "timestamp": "2025-02-20T10:30:00Z",
  "creation_info": { ... },
  "files": [
    {
      "sbom_quality_score": 7.8,
      "grade": "B",
      "num_components": 247,
      "spec": "cyclonedx",
      "spec_version": "1.6",
      "file_format": "json",
      "comprehensive": [ ... ],
      "profiles": { ... }
    }
  ]
}
```

### Filter by Category or Feature

```bash
# Score only specific categories
sbomqs score --category "integrity,licensing" sbom.json

# Score only specific features
sbomqs score --feature "comp_with_purl,comp_with_version" sbom.json
```

### Recursive Directory Scoring

```bash
sbomqs score --recursive ./sboms/
```

### Scoring Against a Compliance Profile

By default `score` uses the Interlynk scoring model. Pass `--profile` to score the SBOM against the feature set of a compliance standard instead, or against several at once:

```bash
# Score under one profile
sbomqs score --profile ntia sbom.json

# Score under several profiles in one run
sbomqs score --profile ntia,bsi,oct-v1.1,interlynk sbom.json
```

Accepted profiles: `interlynk`, `ntia` (aliases `cisa-2021`, `cisa2021`), `cisa` (aliases `cisa-2026`, `cisa2026`), `fsct`, `bsi` (an alias for the latest BSI profile), `bsi-v1.1`/`bsiv11`, `bsi-v2.0`/`bsiv20`, `bsi-v2.1`/`bsiv21`, and `oct-v1.1`/`octv11`/`oct`.

Profile results appear under `profiles` in the JSON output, each with its own score and grade.

{% hint style="info" %}
Feature keys differ per profile. `--feature comp_with_purl` applies to the default Interlynk model, while a profile run uses that profile's own keys. Run `sbomqs features --profile <profile>` to list them.
{% endhint %}

### Listing Supported Features

```bash
# All features across all profiles
sbomqs features

# Features for one profile
sbomqs features --profile bsiv21

# JSON output
sbomqs features --json
```

Use this to find the exact feature key to pass to `score --feature` or `list --feature`.

### Compliance Validation

Validate against industry standards:

```bash
# CISA Minimum Elements (2026)
sbomqs compliance --cisa sbom.json

# NTIA Minimum Elements (2021), also the default when no standard flag is given
sbomqs compliance --ntia sbom.json

# BSI TR-03183-2, latest version
sbomqs compliance --bsi sbom.json

# BSI TR-03183-2 v2.1.0
sbomqs compliance --bsi-v21 sbom.json

# BSI TR-03183-2 v2.0.0
sbomqs compliance --bsi-v2 sbom.json

# BSI TR-03183-2 v1.1
sbomqs compliance --bsi-v1 sbom.json

# OpenChain Telco SBOM v1.1
sbomqs compliance --oct sbom.json

# Framing Software Component Transparency v3
sbomqs compliance --fsct sbom.json
```

Compliance output shows pass/fail status for each requirement, score breakdowns, and recommendations.

#### Standard Flags

| Flag        | Standard                                          | Aliases                     |
| ----------- | ------------------------------------------------- | --------------------------- |
| `--cisa`    | CISA Minimum Elements (2026)                      | `--cisa-2026`, `--cisa2026` |
| `--ntia`    | NTIA Minimum Elements (July 12, 2021)             | `--cisa-2021`, `--cisa2021` |
| `--bsi`     | BSI TR-03183-2, latest version (currently v2.1.0) | —                           |
| `--bsi-v21` | BSI TR-03183-2 v2.1.0                             | `--bsi-v2.1`, `--bsiv21`    |
| `--bsi-v2`  | BSI TR-03183-2 v2.0.0                             | `--bsi-v2.0`, `--bsiv20`    |
| `--bsi-v1`  | BSI TR-03183-2 v1.1                               | `--bsi-v1.1`, `--bsiv11`    |
| `--oct`     | OpenChain Telco SBOM v1.1                         | `--oct-v1.1`, `--octv11`    |
| `--fsct`    | Framing Software Component Transparency v3        | —                           |

Running `compliance` with no standard flag produces the NTIA report.

{% hint style="warning" %}
`--bsi` tracks the latest BSI version rather than pinning one, and currently selects v2.1.0. Pin `--bsi-v21`, `--bsi-v2`, or `--bsi-v1` in CI if the report needs to stay on one version of the standard across sbomqs upgrades.
{% endhint %}

#### Verifying a Detached Signature

For SPDX SBOMs distributed with a detached signature, pass the signature and the public key alongside the standard flag:

```bash
sbomqs compliance --ntia \
  --signature sbom.json.sig \
  --public-key public.pem \
  sbom.json
```

### List Components by Feature

```bash
# List components missing PURLs
sbomqs list --feature comp_with_purl --missing sbom.json

# List components with their license values
sbomqs list --feature comp_valid_licenses --show sbom.json

# JSON output
sbomqs list --feature comp_with_version --missing --json sbom.json

# Feature keys from a compliance profile rather than the default model
sbomqs list --profile bsiv21 --feature comp_name --missing sbom.json
```

### Share Results

Generate a permanent shareable link on sbombenchmark.dev:

```bash
sbomqs share sbom.json
```

### Policy Enforcement

```bash
# Using a policy file
sbomqs policy --file policies.yaml sbom.json

# Inline policy
sbomqs policy --name "require-purl" --type required --rules "comp_with_purl" --action fail sbom.json
```

Policy types: `whitelist`, `blacklist`, `required`

Policy actions: `fail` (exit non-zero), `warn` (report only), `pass` (force pass)

***

## Exit Codes

| Code     | Meaning                                                     |
| -------- | ----------------------------------------------------------- |
| `0`      | Success                                                     |
| `1`      | Error (invalid input, configuration issue, parsing failure) |
| Non-zero | Policy violation with `--action fail`                       |

***

## Integration Patterns

### CI Quality Gate

Fail the build if SBOM quality drops below a threshold:

```bash
#!/bin/bash
THRESHOLD=7.0
SCORE=$(sbomqs score --json sbom.json | jq -r '.files[0].sbom_quality_score')

if (( $(echo "$SCORE < $THRESHOLD" | bc -l) )); then
  echo "SBOM quality score $SCORE is below threshold $THRESHOLD"
  exit 1
fi

echo "SBOM quality score: $SCORE (threshold: $THRESHOLD)"
```

### GitHub Actions

```yaml
name: SBOM Quality Gate
on: [push, pull_request]

jobs:
  sbom-quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

      - name: Install sbomqs
        run: |
          curl -sL https://github.com/interlynk-io/sbomqs/releases/latest/download/sbomqs-linux-amd64 -o sbomqs
          chmod +x sbomqs

      - name: Score SBOM
        run: |
          SCORE=$(./sbomqs score --json sbom.cdx.json | jq -r '.files[0].sbom_quality_score')
          echo "SBOM Quality Score: $SCORE"
          if (( $(echo "$SCORE < 7.0" | bc -l) )); then
            echo "::error::SBOM quality below threshold: $SCORE < 7.0"
            exit 1
          fi
```

### GitLab CI

```yaml
sbom-quality:
  stage: test
  image: golang:1.24
  script:
    - go install github.com/interlynk-io/sbomqs@latest
    - SCORE=$(sbomqs score --json sbom.cdx.json | jq -r '.files[0].sbom_quality_score')
    - |
      if [ $(echo "$SCORE < 7.0" | bc -l) -eq 1 ]; then
        echo "SBOM quality below threshold: $SCORE"
        exit 1
      fi
  artifacts:
    reports:
      dotenv: sbom-quality.env
```

### Pre-Release Validation

Score all SBOMs in a release directory:

```bash
sbomqs score --recursive --json ./release-sboms/ | \
  jq -r '.files[] | "\(.file_name): \(.sbom_quality_score) (\(.grade))"'
```

### Compliance Gate

Block releases that fail compliance standards:

```bash
sbomqs compliance --ntia --json sbom.json | \
  jq -e '.files[0].compliance_status == "pass"' || {
    echo "SBOM does not meet NTIA minimum elements"
    exit 1
  }
```

### Dependency-Track Integration

Score SBOMs directly from a Dependency-Track instance:

```bash
sbomqs dtrackScore \
  --url https://dtrack.example.com \
  --api-key "$DT_API_KEY" \
  --tag-project-with-score \
  --tag-project-with-grade \
  <project-uuid>
```

***

## Customization

### Configuration Files

Generate default configuration templates:

```bash
sbomqs generate features       # Individual feature weights
sbomqs generate comprehenssive # Category configuration
sbomqs generate profiles       # Profile definitions
```

### Custom Scoring Configuration

Use `--configpath` to apply a custom configuration:

```bash
sbomqs score --configpath ./custom-config.yaml sbom.json
```

Configuration structure allows you to:

* Enable or disable specific categories
* Adjust category weights
* Customize individual feature weights (0.0–1.0)
* Create organization-specific scoring profiles

### Compliance Profiles

Apply compliance profiles during scoring:

```bash
sbomqs score --profile ntia sbom.json
sbomqs score --profile bsi sbom.json
sbomqs score --profile bsi-v2.0 sbom.json
sbomqs score --profile oct sbom.json
sbomqs score --profile fsct sbom.json
sbomqs score --profile interlynk sbom.json
```

### Legacy Scoring Mode

Use the pre-v2.0 scoring categories (NTIA Minimum Elements, Structural, Semantic, Quality, Sharing):

```bash
sbomqs score --legacy sbom.json
```

***

## Best Practices

### When to Enforce Strict Scoring

| Context                     | Recommended Threshold | Standard               |
| --------------------------- | --------------------- | ---------------------- |
| Internal development builds | 5.0+ (Grade C)        | No specific standard   |
| Pre-release / staging       | 7.0+ (Grade B)        | Organization policy    |
| Production releases         | 8.0+ (Grade A)        | NTIA minimum elements  |
| Regulatory submissions      | 8.5+ (Grade A)        | BSI TR-03183-2 or FSCT |
| Supply chain sharing        | 7.5+ (Grade B)        | OpenChain Telco        |

### Using Alongside Vulnerability Scanning

1. **Score first** — validate the SBOM has sufficient quality for vulnerability scanning to be meaningful. An SBOM without PURLs or CPEs will produce incomplete vulnerability results.
2. **Scan second** — run vulnerability scanning on SBOMs that meet quality thresholds.
3. **Gate on both** — a release should pass both quality and vulnerability gates.

```bash
# Step 1: Quality gate
sbomqs score --json sbom.json | jq -e '.files[0].sbom_quality_score >= 7.0' || exit 1

# Step 2: Upload for vulnerability scanning
pylynk upload --prod 'my-app' --sbom sbom.json
```

### Governance Recommendations

* **Baseline scores:** Establish minimum quality scores per project tier (critical, standard, experimental).
* **Track trends:** Export JSON scores to a time-series database to monitor quality over time.
* **Automate compliance:** Run compliance checks in CI and block merges that introduce regressions.
* **Share results:** Use `sbomqs share` to create permanent links for audit trails.

***

## Common Misconfigurations

| Issue                                    | Symptom                            | Fix                                                          |
| ---------------------------------------- | ---------------------------------- | ------------------------------------------------------------ |
| Scoring SBOM without PURLs               | Low vulnerability readiness score  | Ensure SBOM generator includes PURLs for all components      |
| Using `--legacy` in new pipelines        | Inconsistent scoring with platform | Remove `--legacy` flag; use v2.0 categories                  |
| Threshold too low                        | Low-quality SBOMs pass the gate    | Raise threshold to 7.0+ for production                       |
| Threshold too high for early development | All builds fail quality gate       | Use 5.0 for development, increase for staging/production     |
| Not using `--json` in CI                 | Parsing table output is fragile    | Always use `--json` with `jq` for automation                 |
| Scoring the wrong file                   | Unexpected results                 | Verify the file is a valid SBOM, not a lock file or manifest |


# sbomasm

sbomasm is a comprehensive SBOM management toolkit for assembling, editing, enriching, viewing, and cryptographically signing SBOMs. It supports both SPDX and CycloneDX formats and handles operations that span multiple SBOMs — merging microservice SBOMs into a platform-wide view, enriching components with license data, editing metadata for compliance, and signing SBOMs for integrity verification.

**Repository:** [github.com/interlynk-io/sbomasm](https://github.com/interlynk-io/sbomasm)

***

## Use Cases

| Operation        | When to Use                                                           |
| ---------------- | --------------------------------------------------------------------- |
| Assemble (merge) | Combine SBOMs from multiple services, containers, or modules into one |
| Edit             | Update metadata (supplier, author, version) before distribution       |
| Enrich           | Fill missing license information from ClearlyDefined                  |
| Remove           | Strip components or fields before sharing externally                  |
| View             | Inspect SBOM structure and dependencies                               |
| Sign / Verify    | Establish authenticity and detect tampering                           |

***

## Installation

### Homebrew (macOS/Linux)

```bash
brew tap interlynk-io/interlynk
brew install sbomasm
```

### Go Install

```bash
go install github.com/interlynk-io/sbomasm@latest
```

### Pre-Built Binaries

Download from the [GitHub releases page](https://github.com/interlynk-io/sbomasm/releases) for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64).

### Docker

```bash
docker run -v $(pwd):/data ghcr.io/interlynk-io/sbomasm:latest assemble \
  -n 'my-app' -v '1.0.0' -o /data/merged.json /data/sbom1.json /data/sbom2.json
```

### Build from Source

```bash
git clone https://github.com/interlynk-io/sbomasm.git
cd sbomasm
make build
```

### Verify Installation

```bash
sbomasm version
```

***

## Core Operations

### Assemble (Merge SBOMs)

Combine multiple SBOMs into a single document. Four merge strategies are available:

| Strategy     | Flag                    | Behavior                                                                                                                            |
| ------------ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Hierarchical | `--hierMerge` (default) | Preserves component structure; nests each input SBOM's components under its own primary component, below a new root                 |
| Flat         | `--flatMerge`           | Places every component at the same level under a new root, which depends on all of them; input nesting is dropped                   |
| Assembly     | `--assemblyMerge`       | Combines the inputs as an assembly, carrying their own relationships through rather than re-parenting components under the new root |
| Augment      | `--augmentMerge`        | Enriches a primary SBOM with data from others; no new root created                                                                  |

Flat and assembly merges also accept `--primary`. Passing an existing SBOM as the primary uses its root as the root of the result instead of creating a new one.

#### Hierarchical Merge (Default)

```bash
sbomasm assemble \
  -n 'platform-sbom' \
  -v '2.0.0' \
  -o merged.cdx.json \
  service-a.cdx.json service-b.cdx.json service-c.cdx.json
```

#### Flat Merge

```bash
sbomasm assemble \
  --flatMerge \
  -n 'platform-sbom' \
  -v '2.0.0' \
  -o merged.cdx.json \
  service-a.cdx.json service-b.cdx.json
```

#### Assembly Merge

```bash
sbomasm assemble \
  --assemblyMerge \
  -n 'platform-sbom' \
  -v '2.0.0' \
  -o merged.cdx.json \
  service-a.cdx.json service-b.cdx.json
```

#### Augment Merge

Enrich an existing SBOM with components from other SBOMs without changing the root structure:

```bash
sbomasm assemble \
  --augmentMerge \
  --primary base-sbom.cdx.json \
  --merge-mode if-missing-or-empty \
  -o enriched.cdx.json \
  additional-data.cdx.json
```

Merge modes for augment:

* `if-missing-or-empty` (default) — only fills in empty or missing fields
* `overwrite` — replaces existing values

#### Output Format Control

```bash
# CycloneDX JSON (default)
sbomasm assemble -n 'app' -v '1.0' -o out.cdx.json sbom1.json sbom2.json

# CycloneDX XML
sbomasm assemble -n 'app' -v '1.0' --xml -o out.cdx.xml sbom1.json sbom2.json

# SPDX JSON
sbomasm assemble -n 'app' -v '1.0' --outputSpecSpdx -o out.spdx.json sbom1.json sbom2.json

# Specific spec version
sbomasm assemble -n 'app' -v '1.0' --outputSpecVersion 1.5 -o out.json sbom1.json sbom2.json
```

#### Configuration-Driven Assembly

Generate a configuration template:

```bash
sbomasm generate > assemble-config.yaml
```

Example configuration file (`assemble-config.yaml`):

```yaml
app:
  name: 'platform-sbom'
  version: '2.0.0'
  type: 'application'
  description: 'Combined platform SBOM'
  supplier:
    name: 'Acme Corp'
    email: 'security@acme.com'
  author:
    - name: 'Security Team'
      email: 'security@acme.com'
  licenses:
    - id: 'Apache-2.0'
  purl: 'pkg:generic/acme/platform@2.0.0'
  cpe: 'cpe:2.3:a:acme:platform:2.0.0:*:*:*:*:*:*:*'

output:
  spec: cyclonedx
  file_format: json
  file: 'platform-sbom.cdx.json'

assemble:
  hierarchical_merge: true
  include_components: true
  include_dependency_graph: true
```

Run with configuration:

```bash
sbomasm assemble --configPath assemble-config.yaml service-a.cdx.json service-b.cdx.json
```

#### Assemble Parameters

| Parameter             | Short | Required          | Default               | Description                                                                                                     |
| --------------------- | ----- | ----------------- | --------------------- | --------------------------------------------------------------------------------------------------------------- |
| `--name`              | `-n`  | Yes (non-augment) | —                     | Name for assembled SBOM                                                                                         |
| `--version`           | `-v`  | Yes (non-augment) | —                     | Version for assembled SBOM                                                                                      |
| `--output`            | `-o`  | No                | stdout                | Output file path                                                                                                |
| `--type`              | `-t`  | No                | `application`         | Component type                                                                                                  |
| `--configPath`        | `-c`  | No                | —                     | YAML configuration file                                                                                         |
| `--hierMerge`         | `-m`  | No                | Default               | Hierarchical merge                                                                                              |
| `--flatMerge`         | `-f`  | No                | —                     | Flat merge                                                                                                      |
| `--assemblyMerge`     | `-a`  | No                | —                     | Assembly merge                                                                                                  |
| `--augmentMerge`      | —     | No                | —                     | Augment merge                                                                                                   |
| `--primary`           | `-p`  | Augment only      | —                     | Primary SBOM file. Required for augment merge; optional on assembly and flat merges, where it supplies the root |
| `--merge-mode`        | —     | No                | `if-missing-or-empty` | Merge mode for augment: `if-missing-or-empty`, `overwrite`                                                      |
| `--doc-license`       | —     | No                | `CC0-1.0`             | Document license for the assembled SBOM metadata. Use `none` to omit                                            |
| `--outputSpecCdx`     | `-g`  | No                | Default               | CycloneDX output                                                                                                |
| `--outputSpecSpdx`    | `-s`  | No                | —                     | SPDX output                                                                                                     |
| `--outputSpecVersion` | `-e`  | No                | Latest                | Spec version, for example `1.5`, `1.6`, or `1.7` for CycloneDX                                                  |
| `--xml`               | `-x`  | No                | —                     | XML output                                                                                                      |
| `--json`              | `-j`  | No                | Default               | JSON output                                                                                                     |

**Component type values:** `application`, `framework`, `library`, `container`, `device`, `firmware`

***

### Edit SBOM Metadata

Modify metadata on the SBOM document, primary component, or specific components.

#### Edit Document Metadata

```bash
sbomasm edit \
  --subject document \
  --supplier "Acme Corp (https://acme.com)" \
  --author "Security Team" \
  --tool "sbomasm (v2.0)" \
  --timestamp \
  -o updated.cdx.json \
  original.cdx.json
```

#### Edit Primary Component

```bash
sbomasm edit \
  --subject primary-component \
  --name "my-application" \
  --version "2.1.0" \
  --purl "pkg:generic/acme/my-application@2.1.0" \
  --license "Apache-2.0" \
  --description "Main application component" \
  -o updated.cdx.json \
  original.cdx.json
```

#### Edit a Specific Component

```bash
sbomasm edit \
  --subject component-name-version \
  --search "log4j-core:2.17.0" \
  --license "Apache-2.0" \
  --supplier "Apache Foundation (https://apache.org)" \
  -o updated.cdx.json \
  original.cdx.json
```

#### Edit Modes

| Flag        | Behavior                                           |
| ----------- | -------------------------------------------------- |
| (default)   | Overwrite existing values                          |
| `--append`  | Add to existing values (e.g., additional licenses) |
| `--missing` | Only set if the field is currently empty           |

#### Editable Fields

| Field       | Flag            | Format                             |
| ----------- | --------------- | ---------------------------------- |
| Name        | `--name`        | String                             |
| Version     | `--version`     | String                             |
| Type        | `--type`        | Component type value               |
| Supplier    | `--supplier`    | `"Name (url)"`                     |
| Author      | `--author`      | String (repeatable)                |
| PURL        | `--purl`        | Package URL                        |
| CPE         | `--cpe`         | CPE identifier                     |
| License     | `--license`     | SPDX expression (repeatable)       |
| Hash        | `--hash`        | `"Algorithm (value)"` (repeatable) |
| Tool        | `--tool`        | `"Name (version)"` (repeatable)    |
| Copyright   | `--copyright`   | String                             |
| Lifecycle   | `--lifecycle`   | Phase name (repeatable)            |
| Description | `--description` | String                             |
| Repository  | `--repository`  | URL                                |
| Timestamp   | `--timestamp`   | Flag — adds current time           |

***

### Enrich SBOMs

Fill missing license information using the ClearlyDefined API.

```bash
# Enrich missing licenses
sbomasm enrich --fields license -o enriched.cdx.json sbom.cdx.json

# Force-replace existing licenses
sbomasm enrich --fields license --force -o enriched.cdx.json sbom.cdx.json

# Custom license joining operator
sbomasm enrich --fields license --license-exp-join AND -o enriched.cdx.json sbom.cdx.json

# Adjust batch size and retry behavior
sbomasm enrich --fields license --chunk-size 50 --max-retries 3 --max-wait 10 -o enriched.cdx.json sbom.cdx.json
```

| Parameter            | Short | Default | Description                                      |
| -------------------- | ----- | ------- | ------------------------------------------------ |
| `--fields`           | —     | —       | Fields to enrich (currently: `license`)          |
| `--output`           | `-o`  | stdout  | Output file                                      |
| `--force`            | `-f`  | Off     | Replace existing values                          |
| `--max-retries`      | `-r`  | `2`     | API retry attempts                               |
| `--max-wait`         | `-w`  | `5`     | Max wait time (seconds)                          |
| `--license-exp-join` | `-j`  | `OR`    | License expression operator: `OR`, `AND`, `WITH` |
| `--chunk-size`       | `-c`  | `100`   | Batch size for API requests                      |

The enrichment process reports:

* Total components
* Components selected for enrichment
* Successfully enriched count
* Skipped count
* Failed count

***

### Remove Components or Fields

Strip components or metadata before external distribution.

```bash
# Remove a specific component
sbomasm rm --components --name "internal-lib" -o cleaned.cdx.json sbom.cdx.json

# Remove a field from all components
sbomasm rm --field author --scope component --all -o cleaned.cdx.json sbom.cdx.json

# Remove dependencies
sbomasm rm --dependency --id "pkg:npm/internal@1.0.0" -o cleaned.cdx.json sbom.cdx.json

# Dry run — preview changes
sbomasm rm --components --name "internal-*" --dry-run sbom.cdx.json

# Summary of changes
sbomasm rm --components --name "internal-lib" --summary -o cleaned.cdx.json sbom.cdx.json
```

***

### View SBOM Structure

Inspect SBOM contents without modifying the file.

```bash
# Default tree view
sbomasm view sbom.cdx.json

# Verbose — show all fields
sbomasm view --verbose sbom.cdx.json

# Show only licenses
sbomasm view --only-licenses sbom.cdx.json

# Filter by component type
sbomasm view --filter-type "library,framework" sbom.cdx.json

# Show vulnerabilities with severity filter
sbomasm view --vulnerabilities --min-severity high sbom.cdx.json

# Limit tree depth
sbomasm view --max-depth 2 sbom.cdx.json

# Flat list format
sbomasm view --format flat sbom.cdx.json

# JSON output
sbomasm view --format json -o structure.json sbom.cdx.json

# Hide disconnected components
sbomasm view --hide-islands sbom.cdx.json
```

***

### Sign and Verify SBOMs

Cryptographically sign SBOMs for integrity verification using the SecureSBOM service.

#### Sign

```bash
sbomasm sign \
  --key-id "your-key-id" \
  --api-key "$SECURE_SBOM_API_KEY" \
  --output signed.cdx.json \
  sbom.cdx.json
```

For SPDX (detached signature):

```bash
sbomasm sign \
  --key-id "your-key-id" \
  --api-key "$SECURE_SBOM_API_KEY" \
  --detached \
  --output signature.b64 \
  sbom.spdx.json
```

#### Verify

```bash
# CycloneDX (embedded signature)
sbomasm verify \
  --key-id "your-key-id" \
  --api-key "$SECURE_SBOM_API_KEY" \
  signed.cdx.json

# SPDX (detached signature)
sbomasm verify \
  --key-id "your-key-id" \
  --api-key "$SECURE_SBOM_API_KEY" \
  --signature "$(cat signature.b64)" \
  sbom.spdx.json
```

| Parameter    | Default                | Description                      |
| ------------ | ---------------------- | -------------------------------- |
| `--key-id`   | —                      | Signing key ID (required)        |
| `--api-key`  | `$SECURE_SBOM_API_KEY` | API key for SecureSBOM service   |
| `--base-url` | Default service URL    | Custom SecureSBOM endpoint       |
| `--output`   | stdout                 | Output file                      |
| `--detached` | Off                    | Return detached signature (SPDX) |
| `--timeout`  | `30s`                  | Request timeout                  |
| `--retry`    | `3`                    | Retry attempts                   |

#### Managing Signing Keys

Signing keys live in the SecureSBOM account and are managed with `securesbomkey`:

```bash
# List the keys available to your account
sbomasm securesbomkey list

# Create a new signing key
sbomasm securesbomkey generate

# Fetch the public key for a key ID
sbomasm securesbomkey public "your-key-id" --output public.pem
```

All three accept `--api-key` (or `SECURE_SBOM_API_KEY`), `--base-url` (or `SECURE_SBOM_BASE_URL`), `--timeout`, `--retry`, and `--quiet`. `list` and `generate` also take `--output table|json`; `public` takes `--output` as a file path and defaults to stdout.

***

### Convert to CSV

Flatten an SBOM into a spreadsheet-friendly component list. Both SPDX and CycloneDX inputs are accepted:

```bash
# Print CSV to stdout
sbomasm convert --format csv sbom.cdx.json

# Write to a file
sbomasm convert --format csv --output components.csv sbom.spdx.json
```

`csv` is the only output format, and also the default for `--format`.

***

## Supported Formats

### Input

| Spec      | Versions      | File Formats         |
| --------- | ------------- | -------------------- |
| SPDX      | 2.1, 2.2, 2.3 | JSON, XML, Tag-Value |
| CycloneDX | 1.0 – 1.6     | JSON, XML            |

### Output

| Spec      | Default Version | File Formats |
| --------- | --------------- | ------------ |
| SPDX      | 2.3             | JSON         |
| CycloneDX | 1.6             | JSON, XML    |

Formats are auto-detected on input. Cross-format assembly (mixing SPDX and CycloneDX inputs) is supported — the output format is determined by flags.

***

## Advanced Usage

### Multi-Module Builds

For projects with multiple build modules (e.g., microservices, monorepos):

```bash
# Step 1: Generate per-module SBOMs during build
cd service-a && syft . -o cyclonedx-json > ../sboms/service-a.cdx.json
cd service-b && syft . -o cyclonedx-json > ../sboms/service-b.cdx.json
cd service-c && syft . -o cyclonedx-json > ../sboms/service-c.cdx.json

# Step 2: Assemble into platform SBOM
sbomasm assemble \
  -n 'platform' \
  -v '$(git describe --tags)' \
  -t application \
  -o platform-sbom.cdx.json \
  sboms/*.cdx.json

# Step 3: Enrich with license data
sbomasm enrich --fields license -o platform-sbom-enriched.cdx.json platform-sbom.cdx.json

# Step 4: Score quality
sbomqs score platform-sbom-enriched.cdx.json

# Step 5: Upload to Interlynk
pylynk upload --prod 'platform' --sbom platform-sbom-enriched.cdx.json
```

### Large SBOM Handling

For SBOMs with thousands of components:

* **Batch assembly:** Assemble in stages — merge groups of SBOMs first, then merge the results.
* **Enrichment chunking:** Use `--chunk-size 50` to reduce memory usage during license enrichment.
* **View depth limiting:** Use `--max-depth 2` and `--hide-islands` for readable output.
* **JSON output:** Use `--format json` for machine processing rather than tree rendering.

```bash
# Stage 1: Merge groups
sbomasm assemble -n 'batch-1' -v '1.0' -o batch1.json group1/*.json
sbomasm assemble -n 'batch-2' -v '1.0' -o batch2.json group2/*.json

# Stage 2: Final assembly
sbomasm assemble -n 'complete' -v '1.0' -o final.json batch1.json batch2.json
```

### Dependency-Track Integration

Fetch SBOMs directly from Dependency-Track, assemble, and optionally upload back:

```bash
sbomasm assemble dt \
  --url https://dtrack.example.com \
  --api-key "$DT_API_KEY" \
  -n 'combined' \
  -v '1.0.0' \
  -o combined.cdx.json \
  <project-uuid-1> <project-uuid-2>
```

### CI/CD Pipeline Example

```yaml
# GitHub Actions: Full SBOM pipeline
name: SBOM Pipeline
on:
  release:
    types: [published]

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate SBOMs
        run: |
          syft ./service-a -o cyclonedx-json > service-a.cdx.json
          syft ./service-b -o cyclonedx-json > service-b.cdx.json

      - name: Assemble Platform SBOM
        run: |
          sbomasm assemble \
            -n '${{ github.event.repository.name }}' \
            -v '${{ github.event.release.tag_name }}' \
            -o platform.cdx.json \
            service-a.cdx.json service-b.cdx.json

      - name: Enrich Licenses
        run: sbomasm enrich --fields license -o platform-enriched.cdx.json platform.cdx.json

      - name: Quality Gate
        run: |
          SCORE=$(sbomqs score --json platform-enriched.cdx.json | jq -r '.files[0].sbom_quality_score')
          if (( $(echo "$SCORE < 7.0" | bc -l) )); then
            echo "::error::SBOM quality $SCORE below threshold 7.0"
            exit 1
          fi

      - name: Upload to Interlynk
        env:
          INTERLYNK_SECURITY_TOKEN: ${{ secrets.INTERLYNK_SERVICE_TOKEN }}
        run: pylynk upload --prod '${{ github.event.repository.name }}' --sbom platform-enriched.cdx.json
```

***

## Error Handling

### Common Errors

| Error                       | Cause                                       | Resolution                                                  |
| --------------------------- | ------------------------------------------- | ----------------------------------------------------------- |
| `file not found`            | Invalid input path                          | Verify file path; use absolute paths in Docker              |
| `unsupported format`        | Unrecognized SBOM format                    | Ensure input is valid CycloneDX or SPDX                     |
| `name and version required` | Missing `--name` or `--version`             | Provide both for non-augment assembly                       |
| `primary file required`     | Augment merge without `--primary`           | Specify `--primary` with augment merge                      |
| `invalid reference`         | Dependency references nonexistent component | Fix the source SBOM; ensure all referenced components exist |
| ClearlyDefined API timeout  | Network or rate limiting                    | Increase `--max-wait` and `--max-retries`                   |
| Signing service unavailable | SecureSBOM API down                         | Check service status; increase `--timeout`                  |

### Debug Mode

Enable debug logging globally:

```bash
sbomasm --debug assemble -n 'app' -v '1.0' -o out.json input.json
```

Debug output includes processing flow details, component matching decisions, deduplication results, and API request/response information.

***

## Best Practices

### Assembly

* Use **hierarchical merge** for platform-level SBOMs where component provenance matters.
* Use **flat merge** when downstream consumers need a simple component list.
* Use **augment merge** to enrich vendor-provided SBOMs without altering their structure.
* Include `--type` to set the correct component type (`application`, `container`, `library`).
* Store assembly configuration in version control alongside your build scripts.

### Editing

* Use `--missing` mode to fill gaps without overwriting vendor-provided metadata.
* Use `--append` to add supplementary licenses or authors without removing existing ones.
* Edit the `document` subject to set creation tool and timestamp metadata before distribution.

### Enrichment

* Run enrichment after assembly to process all components in one pass.
* Use `--license-exp-join AND` for conservative license interpretation in regulated environments.
* Review enrichment reports — failed components may need manual attention.

### Security

* Sign SBOMs before distributing to external parties.
* Verify received SBOMs before importing into your supply chain management system.
* Store signing API keys in a secrets manager; never commit to source control.
* Strip internal components (`sbomasm rm`) before sharing SBOMs externally.

***

## Common Misconfigurations

| Issue                                        | Symptom                       | Fix                                                     |
| -------------------------------------------- | ----------------------------- | ------------------------------------------------------- |
| Missing `--name` and `--version` on assemble | Error at startup              | Always provide both unless using augment merge          |
| Mixing formats without output spec flag      | Unexpected output format      | Explicitly set `--outputSpecCdx` or `--outputSpecSpdx`  |
| Augment without `--primary`                  | Error requiring primary file  | Specify the base SBOM with `--primary`                  |
| Large enrichment without `--chunk-size`      | Timeouts or high memory usage | Set `--chunk-size 50` for SBOMs with 1000+ components   |
| Signing without `SECURE_SBOM_API_KEY`        | Authentication error          | Set the environment variable or use `--api-key`         |
| Editing with default overwrite mode          | Vendor metadata lost          | Use `--missing` or `--append` to preserve existing data |


# Technical Support

Interlynk provides technical support to help you resolve issues, answer questions, and get the most out of the platform. Support is available through multiple channels depending on your subscription tier.

***

## Contact Us

| Channel       | Details                                                                                                                                           | Availability                           |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| **Live Chat** | Click the chat icon at the bottom left of the [Platform Dashboard](https://app.interlynk.io) or [Website](https://www.interlynk.io/#hs-chat-open) | Business hours                         |
| **Email**     | <support@interlynk.io>                                                                                                                            | 24/7 (responses during business hours) |
|               |                                                                                                                                                   |                                        |

***

## Support Tiers

Support level and response times vary by subscription plan.

### Free Tier

| Priority          | Response Time | Channel          |
| ----------------- | ------------- | ---------------- |
| General questions | Best effort   | Email, Live Chat |
| Bug reports       | Best effort   | Email, GitHub    |

### Enterprise Tier

| Priority                                            | Response Time     | Channel          |
| --------------------------------------------------- | ----------------- | ---------------- |
| **Critical** — Platform unavailable or data loss    | 8 business hours  | Email, Live Chat |
| **High** — Major feature impaired, no workaround    | 24 business hours | Email, Live Chat |
| **Medium** — Feature impaired, workaround available | 2 business day    | Email, Live Chat |
| **Low** — General questions, feature requests       | 4 business days   | Email, Live Chat |

{% hint style="info" %}
Business hours are Monday through Friday, 9:00 AM — 6:00 PM ET, excluding US federal holidays.
{% endhint %}

{% hint style="info" %}
Enterprise customers can contact their account representative for escalation paths and dedicated support options.
{% endhint %}

***

## Reporting a Bug

When reporting a bug, include the following information to help us diagnose the issue quickly:

1. **Summary** — A brief description of the problem.
2. **Steps to reproduce** — The exact steps to trigger the issue.
3. **Expected behavior** — What you expected to happen.
4. **Actual behavior** — What actually happened.
5. **Screenshots or screen recordings** — Visual evidence of the issue, if applicable.
6. **Environment details**:
   * Browser and version (for platform issues)
   * CLI tool and version (for `sbomqs`, `sbomasm`, `pylynk` issues — run `<tool> --version`)
   * Operating system
   * SBOM format and specification version (if relevant)

### Where to Report

| Issue Type                | Where to Report                                                 |
| ------------------------- | --------------------------------------------------------------- |
| Platform (Dashboard, API) | <support@interlynk.io> or Live Chat                             |
| sbomqs                    | [GitHub Issues](https://github.com/interlynk-io/sbomqs/issues)  |
| sbomasm                   | [GitHub Issues](https://github.com/interlynk-io/sbomasm/issues) |
| pylynk                    | [GitHub Issues](https://github.com/interlynk-io/pylynk/issues)  |
| Security vulnerabilities  | <security@interlynk.io>                                         |

{% hint style="warning" %}
For security vulnerabilities, do not open a public GitHub issue. Email <security@interlynk.io> directly with details.
{% endhint %}

***

## Troubleshooting

### SBOM Upload Issues

| Problem                                       | Possible Cause                                  | Solution                                                                                  |
| --------------------------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Upload fails with validation error            | SBOM does not meet minimum quality requirements | Run [sbomqs](/productivity-tools/sbomqs) locally to check quality scores before uploading |
| Upload succeeds but no vulnerabilities appear | Vulnerability scan has not completed            | Wait a few minutes — scans run asynchronously after upload                                |
| Upload rejected with format error             | Unsupported SBOM format or malformed file       | Verify the file is valid CycloneDX or SPDX in JSON or XML format                          |

### Authentication and Access

| Problem                          | Possible Cause            | Solution                                                                                            |
| -------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------- |
| Cannot log in via SSO            | SAML misconfiguration     | Review the [SSO configuration guide](/administration/sso) and verify tenant, Entity ID, and ACS URL |
| User lacks expected permissions  | Incorrect role assignment | Check [role management](/administration/role-management) and verify the user's assigned role        |
| API key returns 401 Unauthorized | Expired or revoked key    | Generate a new API key in [API key management](/administration/api-key-management)                  |

### Integrations

| Problem                           | Possible Cause                 | Solution                                                                                   |
| --------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------ |
| Slack notifications not delivered | Invalid webhook URL            | Verify the webhook URL in [Slack integration settings](/administration/slack)              |
| Jira tickets not created          | Connection credentials expired | Re-authenticate the [Jira integration](/administration/jira)                               |
| GitHub integration not syncing    | Repository permissions changed | Verify the [GitHub integration](/administration/github) has the required repository access |

### CLI Tools

| Problem                                    | Possible Cause                 | Solution                                                                                |
| ------------------------------------------ | ------------------------------ | --------------------------------------------------------------------------------------- |
| `pylynk` returns authentication error      | Missing or invalid API key     | Set the API key with `pylynk configure` or the `INTERLYNK_API_KEY` environment variable |
| `sbomqs` returns low scores                | SBOM missing required fields   | Review the scoring output and address the flagged fields                                |
| `sbomasm` merge produces unexpected output | Conflicting component versions | Review input SBOMs for duplicate or conflicting entries                                 |

***

## Frequently Asked Questions

For the full list of frequently asked questions, see the [FAQ page](/support/faq).


# FAQ

Common questions from Interlynk users, organized by topic and ranked by how frequently they come up.

***

## Vulnerability Management

{% hint style="info" %}
These are the most frequently asked questions across all support conversations.
{% endhint %}

### How do I import vulnerability statuses from one version to another?

Use the **Import Status** wizard on the target version's Vulnerabilities tab. Select the source version and choose the CVEs whose statuses you want to carry over. The wizard matches vulnerabilities across versions using CPE, PURL, and name-version.

### Why does the vulnerability import wizard show no CVEs to import?

The import wizard looks for differences in vulnerability status between the source and destination versions. If all vulnerabilities in the source version are in "Unspecified" status, there is nothing to import. Only statuses like "Affected", "Not Affected", or "In Triage" are eligible for import.

### Can vulnerability status import be automated when a new SBOM version is uploaded?

Yes. Interlynk supports automatic status carry-over when new versions are uploaded. This eliminates the manual import step. Contact support or check version settings for auto-import controls.

### Why does vulnerability import fail when the SBOM generator changes between versions?

If you switch SBOM generators (e.g., from Mend to CycloneDX Maven plugin), component names may differ between versions. The import wizard matches on CPE, PURL, and name-version. If these change, the wizard cannot find matching components. Ensure consistent component naming or use PURLs/CPEs for reliable matching.

### Why is the vulnerability count different between Interlynk and NVD for the same component?

This can happen when NVD CPE queries use wildcard or placeholder versions (e.g., `1.1.1:-`) that Interlynk handles differently. If you notice a discrepancy, report it to support with the specific component, version, and NVD query for investigation.

### Why does the vulnerability count at the product level double-count vulnerabilities from parts?

The top-level vulnerability summary row is intended to be the sum of all part vulnerabilities plus the product's own. If the count appears doubled, this may be a display bug — contact support with the specific product and version.

### How do I filter for unique/deduplicated CVEs across a product with multiple parts?

Currently, the vulnerability view shows CVEs per part, which can result in duplicates. As a workaround, export vulnerabilities as CSV and use a spreadsheet to filter unique CVEs. A UI-level deduplication filter is under consideration.

### What does "Incomplete Only" filter mean in the vulnerabilities view?

"Incomplete" refers to statuses that have been assigned but are missing required information per VEX guidelines. "Unspecified" and "In Triage" are considered complete once set. "Affected" and "Not Affected" require additional information (justification, notes, etc.) — if that information is missing, the status is considered incomplete.

### Why is a known vulnerability (e.g., from GitHub Security Advisories) not showing up for my component?

Some GitHub Security Advisories are only available at the repository level and may not be published to GitHub Global Advisories or OSV. If a vulnerability has a GHSA ID but is not in Global Advisories, it will not appear in Interlynk's vulnerability data. As a workaround, create a custom vulnerability using the CVE or GHSA ID.

### How do I create a custom vulnerability when one is missing from the platform?

You can create custom vulnerabilities from two places:

* **Version Vulnerabilities page** — directly assign it to a component.
* **Global Vulnerabilities page** — assign it a PURL for auto-matching.

Use the CVE ID when available for best compatibility.

### What is the difference between EPSS Score and EPSS Percentile?

The **EPSS Score** is the probability of the vulnerability being exploited in the next 30 days. The **EPSS Percentile** is the rank of that vulnerability relative to all other scored vulnerabilities. These numbers can differ significantly — a low probability score can still have a high percentile if most other vulnerabilities have even lower scores. See [FIRST's EPSS documentation](https://www.first.org/epss/articles/prob_percentile_bins) for details.

### How does Interlynk handle CVSS v3.1 vs CVSS v4.0 scoring?

NVD and OSV may report different CVSS versions for the same vulnerability. NVD is transitioning to CVSS v4.0 as default while OSV often shows CVSS v3.1. These scores are not directly comparable. Interlynk displays the data as received from each source — check which CVSS version is being shown when comparing scores.

### Why is the NVD link missing or broken for some vulnerabilities?

In some cases, the link may incorrectly use a GHSA identifier instead of the CVE number, which NVD does not recognize. This is a known bug. If you encounter a missing or broken NVD link, report the specific CVE to support.

### When does Interlynk detect a new CVE — at SBOM import time or when the CVE gets a CPE assignment?

Interlynk detects CVEs when a CPE match is established in NVD. If a CVE is published but does not have CPE assignments yet, it will not be matched to your components until NVD assigns the CPE. The "Assigned" date in Interlynk reflects when the match was first detected, not when the CVE was published.

***

## SBOM Upload & Management

### Why is my SBOM upload failing with a validation error?

Common causes include:

* **Empty supplier fields** — If the SBOM contains empty supplier elements, upload may fail. Remove the empty supplier fields or wait for a platform update that handles this case.
* **Unsupported format** — Verify the file is valid CycloneDX or SPDX in JSON or XML format.
* **Quality requirements** — Run [sbomqs](/productivity-tools/sbomqs) locally to check quality scores before uploading.

### Why is the SBOM upload delayed or not processing?

During periods of high upload volume, SBOM processing may be delayed. The upload service processes SBOMs asynchronously. If your SBOM does not appear after several minutes, check the Change Log page for processing errors or contact support.

### How do I merge multiple SBOMs together using sbomasm?

Use [sbomasm](/productivity-tools/sbomasm) to merge SBOMs. The default mode is **hierarchical** (preserves component grouping). Use the `-f` flag for **flat** mode if you want all dependencies at the same level:

```bash
sbomasm assemble -f -n "MyProduct" -v "1.0.0" -t "application" -o merged.cdx.json sbom1.json sbom2.json
```

Alternatively, upload each SBOM as a separate product in Interlynk and use the **Parts** feature to create an umbrella product.

### What SBOM formats does Interlynk support?

Interlynk supports CycloneDX and SPDX in JSON and XML formats. For the best experience, use the latest specification versions.

***

## API & CLI (pylynk)

### Where can I find the API documentation for Interlynk?

The API documentation is available at [docs.interlynk.io/api](https://docs.interlynk.io/api). Interlynk uses a GraphQL API. You can use GraphQL introspection tools to explore the full schema from the API endpoint.

### Why do I get an "Invalid project" error when uploading via pylynk?

Common causes:

* **Product name mismatch** — The `--prod` value must exactly match the product name in Interlynk, including dashes and spaces (e.g., `'SmartECG - Package'` vs `'SmartECG Package'`).
* **Quote type** — In some CI/CD environments (e.g., Azure DevOps), use double quotes (`"product-name"`) instead of single quotes (`'product-name'`).
* Verify the product name by running `python3 pylynk.py prods --table`.

### What is the difference between projectGroup and project in the API?

In the API, `projectGroup` refers to a **Product** and `project` refers to an **Environment**. Use `projectGroupId` (not `projectId`) when targeting a product. This naming inconsistency is a known source of confusion.

### How do I create a new build version for a product via the API?

Use the `sbomCreate` mutation to create a new SBOM under a project, then use `componentCreate` to add components. See the [API documentation](https://docs.interlynk.io/api) for mutation details or contact support for sample scripts.

### How do I get an API security token?

Navigate to **Personal Settings** (click your avatar in the top-right, then your name) and select the **Security Tokens** tab. Note: Security tokens are not available on the Free tier — contact support to discuss upgrading.

### How do I create component relationships via the API?

Use the `componentRelationCreate` mutation with `fromCompId`, `toCompId`, and `relationType` parameters. Note: relationships created via the API may appear correctly in the Tree View and exported SBOM but may not immediately show in the UI's "Depends On" field until the page is refreshed.

***

## Notifications

### Why am I not receiving email notifications for new vulnerabilities?

Check the following:

1. **Subscription** — You must subscribe to specific products by clicking the bell icon on the product page and selecting "Vulnerabilities."
2. **Configuration level** — If you moved notification emails from organization-level to personal-level, ensure the personal notification settings are properly configured.
3. **Notification Manager** — Use the Notification Manager feature to review and manage all your notification subscriptions in one place.

### Why am I receiving notifications for projects I haven't subscribed to?

This may indicate a configuration issue. Review your notification subscriptions in the Notification Manager and ensure you are only subscribed to the intended products and environments.

***

## Permissions & Roles

### How do I allow developers to create API tokens without giving them full organization settings access?

API token creation is under the user's Personal Settings. If developers cannot access it, they may be missing the required permission. Contact support to ensure the role is configured correctly — token creation should not require full organization admin access.

### Why is my custom role's permissions not working as expected?

Permission changes may not take effect immediately or may have a bug in a specific release. If a role with specific permissions (e.g., "edit support status") is not functioning, contact support with the role name and expected vs actual behavior.

***

## Components & Support Status

### How is "Direct" dependency defined for support level analysis?

"Direct" includes:

* The primary component of the product
* Any component directly dependent on the primary component
* For products with parts: each part's primary component and its direct dependencies

Transitive dependencies (dependencies of dependencies) are not included in the "Direct" count.

### Why is a component showing "Unknown" support status when it is actively maintained?

This can happen when the platform does not correctly detect the latest version of a component from the package registry. Report the specific component name and version to support for investigation.

### Can I set support status at the parent product level and have it propagate to parts?

This is currently a feature request. Today, support status must be managed per-part for shared components. A future update may allow centralized support status management at the parent product level.

### Why does the support status CSV export exclude components from parts?

This is a known bug. The UI displays components from all parts in the Support Status tab, but the CSV export only includes components from the top-level product. This is being tracked for a fix.

***

## PURL & Component Identity

### How should I format the PURL for non-standard version strings?

Use the version string exactly as it appears in the source repository. For example: `pkg:github/eclipse-threadx/threadx@v6.4.3.202503_rel` — include the leading `v` and trailing `_rel` as-is.

### What PURL type should I use for components not on standard package managers?

Use `generic` as the PURL type for any source that does not fit the known package types. The current supported list is available at the [PURL types index](https://raw.githubusercontent.com/package-url/purl-spec/refs/heads/main/purl-types-index.json).

***

## SBOM Features

### How do I add hashes to a component for regulatory submissions (e.g., FDA)?

Currently, hashes cannot be added directly through the platform UI. As a workaround:

* Download the SBOM and add hashes manually to the JSON.
* Use [sbomasm](/productivity-tools/sbomasm) to edit an existing SBOM and add hash values.

A platform feature for adding hashes through the UI is planned.

### What does "Redact internal components" do when downloading an SBOM?

Redaction replaces the core identifying properties of components marked as "Internal" (name, version, description, CPE, PURL) with SHA-based identifiers. This maintains structural integrity and audit compliance while hiding proprietary component details.

### Can I exclude internal components from an SBOM export entirely?

Exclusion/suppression of internal components is not currently supported. Interlynk only supports redaction (replacing identifying properties with SHA IDs) to maintain structural integrity for compliance purposes.

***

## Products & Environments

### Why are my products or SBOMs not visible after upload?

You may be viewing the wrong environment. Check the environment selector on the Products or Versions page and switch to the correct environment (e.g., "Default" vs "Production").

### How do I compare two versions across different environments?

Use the **SBOM Compare** tool under **Tools** in the left navigation panel. This tool allows you to select any product/version and compare it against a different product/version, including across environments.

***

## CI/CD Integration

### Where can I view CI/CD metadata sent during pylynk upload?

On the **Versions** page of a product, click the arrow ">" next to the version to expand the details view. CI/CD metadata (provider, PR info, build info, commit SHA) will be shown if it was sent during upload. If no metadata was sent, the fields will appear empty.

### How do I upload SBOMs from Azure DevOps pipelines?

Use [pylynk](/productivity-tools/pylynk) in your pipeline. Key tips:

* Use **double quotes** for product names and environment values.
* Ensure the product name exactly matches what is configured in Interlynk.
* Set the API token as a pipeline secret variable.

***

## General

### What is an SBOM?

SBOM (Software Bill of Materials) is a cybersecurity artifact that lists all internal and external components used to build a software product. SBOMs are used to meet regulatory requirements and map software to potential vulnerabilities. Learn more from [CISA's SBOM page](https://www.cisa.gov/sbom).

### How often are vulnerability scans run?

Vulnerability scans run automatically when a new SBOM is uploaded. Existing SBOMs are periodically re-scanned as new vulnerability data becomes available.

### Can I export my data from Interlynk?

Yes. SBOMs, vulnerability reports, and compliance data can be exported from the platform dashboard or via the API using [pylynk](/productivity-tools/pylynk).

### Is there a rate limit on the API?

Yes. API rate limits vary by subscription tier. If you encounter rate limit errors, reduce request frequency or contact support for limit adjustments.

### How do I request a new feature?

Email <support@interlynk.io> with a description of the feature, the use case it addresses, and any relevant context.


# Release Notes

Interlynk's Platform release notes.

## 🚀 Release v4.0.1 — September 2026

### ✨ Highlights

* **Guided Fix Flows for Compliance Checks** — Thirteen compliance checks now carry an in-app fix flow, so a failing check can be corrected and rescanned without leaving the drawer: the five BSI component property checks, both checksum checks, the three external URL checks, copyright and component name on a shared field editor, document creation tools, and declared license.
* **ENISA EUVD Added to Known Exploited Vulnerabilities** — The KEV flag is now the union of the CISA and ENISA EUVD feeds, with partial-failure handling so one feed being unavailable does not drop the other's entries.
* **Policies Can Ignore Resolved Vulnerabilities** — A new policy option excludes vulnerabilities marked Not Affected or Fixed from evaluation, so triaged findings stop re-triggering violations. A new component scope subject narrows policies to a chosen set of components.
* **Fixed Version Shown to Customers** — Customers viewing a shared SBOM can now see which version resolves a vulnerability, rather than only that one exists.
* **Dashboard Preferences Persist Across Devices** — Dashboard layout and widget preferences are stored server-side instead of per browser, and the label widget reads a pre-aggregated count query rather than assembling counts client-side.

***

### 🆕 New Features

* **Compliance Check Fix Flows** — Correct a failing check inline and rescan only after the server accepts the save, with field-level errors reported in place.
* **Exclude Resolved Vulnerabilities from Policy** — A policy-level toggle that keeps Not Affected and Fixed findings out of policy evaluation, exposed in the policy form.
* **Component Scope Policy Subject** — Scope a policy to specific components, with evaluator and importer support.
* **ENISA EUVD KEV Feed** — Union the EUVD known-exploited feed into the existing KEV flag.
* **Server-Side Dashboard Preferences** — Persist dashboard preferences through the API so they follow the user across sessions and devices.
* **Label Count Widget Query** — A dedicated aggregate query backing the dashboard label-count widget.
* **Fixed-Version Visibility for Customers** — Show the version that fixes a vulnerability in the customer share view.
* **Floating Bulk Action Bar** — Vulnerability detail bulk actions moved into a floating bar, with a selection count and labelled actions.
* **Issue-Tracker Bulk Actions Always Visible** — Show issue-tracker bulk actions when the feature is locked or the tracker is not connected, instead of hiding them entirely.
* **Redesigned Compliance Summary Cards** — Rebuilt compliance summary stat cards and clearer sidebar navigation.
* **Package Type Icons** — Icons for ten package types that previously rendered without one.
* **Policy Results Link Through to Products** — The product column in policy results now links to the product details page.
* **System Badge on Feed Toggles** — Mark read-only feed toggles in Profile as system-managed.

***

### 🐛 Bug Fixes

* Fixed compliance checks showing a dead Fix button and marking failing checks as fixed, the drawer's Run action running the wrong check, and Save appearing on a check's read-only View state.
* Fixed two filters offering values the query could never match, in the Checks severity filter and the Doctor severity filter.
* Fixed SBOM downloads failing silently instead of surfacing the reason the server gave.
* Fixed sorting defects: sortable headers that flipped their arrow without reordering rows, the SBOM files table not sorting at all, and a redundant client-side re-sort applied on top of server-sorted results.
* Fixed filter state not resetting or persisting predictably across navigation, and vulnerability filtering leaving rows selected inside the table.
* Fixed Fixed and Not Affected being swapped in two VEX status popovers.
* Fixed stale data after writes: severity badges after a custom vulnerability delete or ticket sync, and the SBOM header keeping an old health score after a policy rescan.
* Fixed handlers that reported success for work the server had refused or that had never run, across five actions, and routed all three issue-tracker providers through the shared error handler.
* Fixed a Jira issue being titled with the current selection rather than the row it was created for.
* Fixed the Executive Summary reporting no licenses at all.
* Fixed saved health score weights coming back invalid and locking the form.
* Fixed copying an automation rule converting its copy actions into set actions, and editing an internal component rule making it case insensitive.
* Fixed a link to an unreachable product reporting four different problems at once.
* Fixed Analytics filter and chart-selector gaps, including missing empty states, a missing tooltip, and a product filter that could not be cleared.
* Fixed Progress Overview rejecting reverse version comparisons, and clarified what the Manual Scan button does.
* Fixed the full-screen loader flashing on the first visit to each product, and component drawer tab panels remounting and losing state on tab switch.
* Fixed invitation redirect links not encoding the email address, and email confirmation success being announced twice.
* Fixed layout and accessibility defects: archived versions drawer sorting, policy description clicks colliding with row expand, drawer background tone, cramped customer dashboard sidebar spacing, dashboard grid breakpoints and draft-mode alert styling, activity icon visibility in dark mode, `fontVariantNumeric` leaking to the DOM, and a form label used as a section heading.
* Fixed backend correctness: policy violation rows not rendering in notifications, previous-version lookup skipping archived SBOMs, OSV `last_affected` events being ignored, and Red Hat distributions failing to resolve when matching OSV advisories.

***

### 🔧 Technical Improvements

* **Worker Memory Guard** — A Sidekiq memory watchdog that tracks running jobs and recycles workers before slow jobs exhaust memory, reporting events to monitoring.
* **Runtime and Dependency Updates** — Ruby 3.4.10 on a slim Trixie base image, a gem refresh, and resolution of 33 npm audit findings including the Tiptap v2 to v3 upgrade.
* **CI Hardening** — Workflow security audits via zizmor across both repositories, with the reported findings remediated.
* **Apollo Cache Correctness** — Closed cache normalization gaps from missing ids and extended `keyArgs` pagination policies.
* **Frontend Performance** — Stopped the command palette rebuilding and discarding every action on each keystroke, memoized expanded-row rendering and product label aggregation, and served the dashboard label widget from the pre-aggregated count query.
* **Component Refactors** — Split the customer SBOM general tab into smaller components, moved the Doctor tab's query and state ownership into its own component, aligned the package details page with existing layout patterns, and removed the unused global context.
* **Code Health** — Backed relative timestamps with `date-fns`, removed three `react-hooks/exhaustive-deps` suppressions that had crept back, made `lazyImport` fail loudly in development on a missing default export, and stopped reporting expected API rejections as errors.
* **Build and Test Tooling** — Added a bundle analyzer, and aria-labels on the Settings navigation with matching Playwright locators.

***

## 🚀 Release v4.0.0 — August 2026

### ✨ Highlights

* **NTIA Minimum Elements 6.3.1** — Scoring and the compliance UI now follow the 6.3.1 element set, with corrected SPDX-Lite export handling for the NTIA profile.
* **BSI TR-03183-2 v2.1.0 Support** — A new scoring and export profile that separates SHALL from MAY requirements, reports MAY coverage in compliance reports, and preserves license assertion roles, external reference hashes, and role-aware creator evidence.
* **Policy Gate for CI/CD** — A new policy gate returns a single pass/fail verdict per SBOM so pipelines can block pull requests on policy failures, counting policies rather than violations and reporting scans still in progress as indeterminate instead of a pass.
* **Redesigned Product, Vulnerability, and Settings Pages** — A compact expandable progress overview on product details, a stat strip and expanded description panel on vulnerability details, a grouped sticky settings navigation rail with search, and a quick-access strip for pinned products.
* **Table and Filter State Correctness** — A broad sweep fixing filters, sorting, pagination, and selection state that leaked between SBOMs, products, tabs, and environments.

***

### 🆕 New Features

* **NTIA 6.3.1 Scoring and UI** — Align compliance scoring and the compliance view with the 6.3.1 minimum elements.
* **BSI v2.1.0 Score and Export** — Adopt the TR-03183-2 v2.1.0 profile across scoring, compliance reports, and export, including SPDX 3 SBOM identity and creation info binding, and recording SWID as out of scope.
* **SBOM Policy Gate** — Query an aggregate policy verdict per SBOM for CI and pull-request blocking, with per-policy violation detail and a configurable failure threshold.
* **Owning Organization Resolution** — Resolve the organization that owns a given resource through a new query.
* **Assign Labels from Product Details** — Assign labels to a product directly from its details page.
* **Grouped Settings Navigation** — Replace the settings tab strip with a sticky, searchable navigation rail organized into sections.
* **Pinned Products Quick Access** — Reach pinned products from a compact strip instead of the previous card layout.
* **Redesigned Policy and Environment Defaults** — A rebuilt policy details header and an organization environment defaults page matching the product settings UI.
* **Customer SBOM Header Band** — Give the customer share view the same SBOM header band as the vendor view.
* **SBOM Support Status Bulk Update** — Surface bulk support status updates directly instead of burying them in a menu, and clear selections afterward.
* **Excel Export Branding** — Ship SBOM Excel exports with the Interlynk logo and without the leading blank row.
* **Notification Copy Updates** — Clearer vulnerability report titles, no duplicated environment prefix in email subjects, and suppression of repeated notifications for the same vulnerability on the same version.

***

### 🐛 Bug Fixes

* Fixed OSV lookup failures being treated as "no vulnerabilities found" rather than as errors.
* Fixed vulnerability exports and download options that were not gated behind the `view_vulnerabilities` permission, and fixed the Copy VEX action being gated on the wrong permission.
* Fixed vulnerability export access that had been broken by the `view_vulnerabilities` gate.
* Fixed Jira defects: duplicate version handling, screen field provisioning running more than once, project permission errors hidden from the person who can resolve them, and rate-limited issue updates ignoring `Retry-After`.
* Fixed policy defects: duplicated VEX checks in policy evaluation, `DispositionByParent` overrides ignored on has-parts relationships, policy scans enqueued more than once per SBOM, and policy condition rows colliding on id and crashing the operator select.
* Fixed filter and pagination state carrying across contexts, including SBOM part filters, Doctor tab filters, archived SBOM date filters, versions search between products, analytics filters on environment switch, and search or sort from page two reusing the previous page's cursor.
* Fixed table behavior: row selection not clearing after a search or filter change, three columns sorting by a field other than the one displayed, support status sorting on end date and updated date doing nothing, expanding one component expanding every same-named row, and shift-clicking a license on the Files tab doing nothing.
* Fixed failed queries rendering as empty tables across SBOM detail, customer tables, and chart refetches, where a failure previously showed as no data or as the previous filter's data.
* Fixed filter interactions: excluding in the Visibility filter wiping the Licenses filter, the Files parts filter vanishing when parts were excluded, the label filter menu rendering behind other elements, the license filter flickering on sibling refetch, and the vulnerability component filter showing with nothing to filter.
* Fixed SBOM Compare never loading the vulnerability diff and both SBOM cards in the compare drawer rendering red.
* Fixed customer and supplier share flows: share links dead-ending on draft SBOMs with a false "removed" message, an unusable request link telling the supplier they had declined, the Decline action reporting success on failure, the customer "exclude" visibility filter showing only the excluded components, and the customer share view polling the public endpoint for roughly thirty minutes per tab.
* Fixed accepting an SBOM request filing it into the previous product's environment, and fixed the product select showing the chosen product as placeholder text.
* Fixed creating a custom vulnerability from an SBOM reporting success without refreshing, and Enter in the vulnerability link drawer saving the wrong link type.
* Fixed navigation defects: login discarding the deep link the user arrived with, branch switches crashing the app, internal organization ids appearing in product URLs, and vulnerability details linking to the wrong product tab.
* Fixed the Automation "Add Rule" dialog crashing when opened before subject mapping loaded, and the checks toolbar rescan silently rerunning only the last opened row.
* Fixed the patch velocity chart clipping points above 9.99 and showing infinite ticks, and thin overlapping x-axis date labels on long analytics ranges.
* Fixed a patch velocity deadlock and six application defects surfaced through production error triage.
* Fixed the Properties tab save causing stale-value flicker and focus jumping to a tooltip, the disabled Save button in component details being unreachable by keyboard, and inconsistent destructive-action confirmations.
* Fixed import statuses being submitted twice while an import was running, and resending an invite dropping the user's assigned role.
* Fixed assorted layout and labeling issues, including parts name column alignment, truncation of long labels in the part select filter, inconsistent text casing in compliance checks and locked feature views, SBOM diff tabs missing their card, spacing and pending-state text in the progress overview, archived actions missing an icon, SBOM filters shifting on tab switch, incomplete kebab action sets, the customer portal showing the support chat bubble, and the enterprise upgrade error hiding its real cause behind a duplicated toast.

***

### 🔧 Technical Improvements

* **Query Performance** — Replaced offset paging of VCS URLs with a single query, stopped loading every pending row to compute patch velocity, and deleted SBOM activity logs in bulk rather than row by row.
* **Background Job Health** — Terminated stale compliance report processing, fixed NVD feed sync memory retention and worker overlap, and enqueued policy scans once per SBOM.
* **Frontend Performance** — Memoized graph aggregation, query filter objects, and pagination props; computed table sorting with a memo instead of an effect-driven double render; and capped node pagination so a misreporting server cannot loop indefinitely.
* **Component Refactors** — Extracted a shared paginated table shell and empty state, adopted a common table filter bar across table headers, split the oversized SBOM General view into an orchestrator and sections, moved SBOM files table filters into global state, and extracted the vulnerability description panel as a component.
* **Shared Utilities** — Consolidated duplicated severity-order, empty-count, and download helpers, and removed dead row-action plumbing from the customer files table.
* **Export Tooling** — Migrated the OTS Excel export to a single spreadsheet library.
* **Rendering Correctness** — Fixed id collisions on dynamic rows in rule creation, support, and legal dialogs, and index-keyed link rows in tree views.
* **Test Coverage** — Updated compliance end-to-end tests for the redesigned selectors.

***

## 🚀 Release v3.9.9 — August 2026

### ✨ Highlights

* **SPDX 3.0 VEX Import & Export** — Exchange VEX data in SPDX 3.0 alongside CycloneDX, and download a standalone VEX document for any SBOM directly from the download menu.
* **VEX Import Conflict Controls** — When an imported VEX statement contradicts an existing assessment, the import now flags the conflict and lets you skip or overwrite it instead of silently applying the change.
* **Jira Ticket Reuse Across Environments** — Reuse existing Jira tickets when the same vulnerability appears in another environment of the same product, with a Copy Tickets Across Environments setting to control it, fix-availability populated from advisory fixed versions, and reuse recorded in the Change Log.
* **Redesigned SBOM Detail & Settings Pages** — A compact SBOM header band, a collapsible insights panel that remembers your choice, one row per part in the parts breakdown, and a reorganized project settings area with issue trackers folded into its navigation.
* **Export Integrity Hardening** — Redacted and shared SBOM exports no longer leak internal component names or bypass TLP classification, and compliance, attribution, and vulnerability exports no longer fabricate or drop data.

***

### 🆕 New Features

* **SPDX 3.0 VEX** — Import and export VEX statements in SPDX 3.0.
* **Standalone VEX Download** — Export VEX on its own from the SBOM download menu, in CycloneDX or SPDX.
* **VEX Import Conflict Detection** — Detect statements that conflict with existing assessments during import and resolve them with per-statement skip or overwrite controls.
* **Cross-Environment Jira Ticket Reuse** — Reuse tickets when a vulnerability appears in another environment of the same product, controlled by a new Copy Tickets Across Environments toggle.
* **Jira Fix Availability** — Populate the Jira fix-availability field automatically from advisory fixed versions.
* **Ticket Reuse Audit Trail** — Record reused tickets in the Change Log, and improve created and deleted ticket notifications.
* **Contextual Jira Settings for Policy Tickets** — Policy-driven tickets now use the Jira configuration of their own product context rather than a single global setting.
* **Collapsible SBOM Insights** — Collapse the insights panel on the SBOM detail page; the preference persists across visits.
* **Per-Part SBOM Breakdown** — See one row per part in the SBOM parts breakdown, listing parts only.
* **Redesigned Project Settings** — A rebuilt Import and defaults page, settings grouped into readable sections, issue trackers merged into the settings navigation, and consistent on/off toggles across project detail tables.

***

### 🐛 Bug Fixes

* Fixed redacted SBOM exports leaking internal component names through the vulnerability section, and fixed share recipients being able to re-download an SBOM under their own TLP classification.
* Fixed bulk VEX changes propagating to upstream products while the consent checkbox was hidden.
* Fixed row actions remaining editable on archived SBOMs, hover shortcuts bypassing menu guards, and license row actions ignoring free-tier gating.
* Fixed compliance CSV exports reporting partial scores as FAIL and fabricating score values.
* Fixed attribution reports dropping TORQUE-style licenses, crashing on empty component rows, and silently deleting angle-bracket text from legal notices.
* Fixed vulnerability CSV exports ignoring the Direct dependencies filter, capping custom fields at two, losing product-group scope, and crashing mid-export.
* Fixed SBOM Excel exports writing partial data on query errors instead of aborting, and fixed OTS Excel CID numbering and manufacturer-contact cells.
* Fixed History CSV log order differing from the drawer, and custom fields shadowing built-in columns.
* Fixed Users CSV exports using the raw search input instead of the applied filter, and export column configuration applying before custom-field definitions loaded.
* Fixed VEX assessments not carrying forward when an SBOM upload changed component or vulnerability identity.
* Fixed stale Jira links surviving reuse, duplicate version conflicts, and ticketing edit modals wiping the configured Jira value while options were still loading.
* Fixed settings mutations and vulnerability status changes reporting success when the change had actually failed.
* Fixed three error-state retry buttons that did nothing, and added a retryable error state when the SBOM detail page fails to load.
* Fixed the customer vulnerability tab reporting zero vulnerabilities when its query failed, and fixed pagination never advancing on the customer share vulnerability view.
* Fixed filter menu pagination stalling on the first page, and made Parts filters and "Exclude parts" mutually exclusive in SBOM and support views.
* Fixed the Defect Density chart ignoring additional SBOM rows on the same date, and Executive Summary severity colors mismatching the app palette.
* Fixed navigation issues: users could return to the reset password page after a successful reset, deleting an SBOM did not always return to product details, and a duplicate "Registration successful" toast appeared on registration.
* Fixed assorted layout and labeling issues, including navbar height alignment, icon sizing, breadcrumb gaps above the SBOM heading, tooltip-induced scrollbars, inline code font size, bare "N/A" severity labels, duplicate organization link labels, and the Bitbucket integration label.

***

### 🔧 Technical Improvements

* **Permission Enforcement** — Project setting updates are now authorized against the `edit_product_settings` permission.
* **Release Signing** — Builds are produced through a signing workflow.
* **Dependency Hygiene** — Patched transitive advisories in brace-expansion, linkify-it, and postcss, upgraded date-fns and react-pdf-charts, and completed a minor and patch catch-up sweep.
* **Shared Utilities** — Replaced nine hand-rolled file download implementations, seven hand-rolled pagination loops, and inline date comparators with shared helpers.
* **Design Tokens** — Replaced hardcoded numeric font sizes with theme tokens and normalized icon sizing.
* **Deletion Safety** — Policy scans and automatic ticket creation are skipped for products pending deletion.
* **Test Infrastructure** — Centralized integration test credentials and repaired end-to-end coverage for the redesigned settings page.

***

## 🚀 Release v3.9.8 — July 2026

### ✨ Highlights

* **CSAF & OpenVEX Import** — Import VEX data in CSAF and OpenVEX formats alongside CycloneDX, with a new affected-product selection step in the import wizard for precise statement mapping.
* **Jira Ticket Reuse Across SBOM Versions** — Automatically reuse existing Jira tickets when the same vulnerability appears in a new SBOM version, keep reused issues updated with the versions they cover, and control the behavior with a new Copy Tickets Across Versions setting.
* **Responsive Dashboard Overhaul** — Use the platform comfortably on tablets and smaller screens: sidebar navigation moves into a drawer on small viewports, tables, charts, and stat cards resize fluidly, and large/ultra-wide displays get restored breakpoints.
* **Faster, Lighter App** — Heavy export libraries now load only when needed, compliance summaries render progressively, and several runaway polling loops are eliminated, cutting load times and background network traffic.

***

### 🆕 New Features

* **CSAF & OpenVEX Support** — Import VEX documents in CSAF and OpenVEX formats in addition to CycloneDX.
* **VEX Import Product Selection** — Choose the affected products a VEX document applies to as a dedicated wizard step.
* **Jira Ticket Reuse & Richer Tickets** — Reuse Jira tickets across SBOM versions and on same-version imports, keep reused issues stamped with the SBOM versions they apply to, and auto-populate vulnerability and VEX fields on automatic tickets. Jira configuration problems are now detected proactively before ticket creation fails.
* **Copy Tickets Across Versions Toggle** — Turn cross-version ticket copying on or off from settings.
* **SPDX 3.0 Supplier Description** — Round-trip supplier descriptions through SPDX 3.0 export and import.
* **Stricter SBOM Upload Validation** — Reject uploads with malformed JSON or missing required information at submission time, with clear errors.
* **Unified Bulk Actions Bar** — Act on selected table rows through a consistent floating action bar across the app.
* **Click-to-Filter Vulnerability Cards** — Click the SBOM vulnerability summary cards to filter the list below.
* **Integration Next Steps** — After connecting GitHub, GitLab, or Bitbucket, a guided next-steps card points to what to do next.
* **Security Incidents Quick Navigation** — Jump to Security Incidents from the command palette.

***

### 🐛 Bug Fixes

* Fixed CSV exports across the board: Vulnerability Detail exports now honor active filters and environment scope, Support Status exports include occurrences and automatic assessment levels, Vulnerability History exports capture per-log custom field snapshots, Users exports apply the search filter and show the correct Joined date, and missing EPSS values render as N/A instead of blank.
* Fixed End-of-Support and FDA OTS export dates shifting by a day for users in timezones behind UTC.
* Fixed editing a component from the Doctor table targeting the wrong SBOM, and fixed Doctor part component ownership.
* Fixed SBOM metrics cards not refreshing after VEX and custom vulnerability edits.
* Fixed pagination in the VEX review table, and bulk Save now requires a VEX status before enabling.
* Fixed stale Jira components and priority lingering when the issue type changes, the Jira project showing N/A after a hard refresh, and the test-ticket component fallback.
* Fixed duplicate version filter entries in policies by disambiguating them with the environment name.
* Fixed label filters being ignored in the Resolution Age and Resolution Velocity trend charts.
* Fixed component relationships missing from certain imported SBOMs, and CycloneDX bom-refs now persist for stable VEX BOM-Link resolution.
* Fixed login failures not being surfaced, with repeat failures guided to password reset.
* Fixed expired share links redirecting to the login page instead of an Invalid Request notice, and fixed rate-limit errors on shared customer views.
* Fixed supplier details being unreadable in dark mode, and long SBOM or version names overflowing the layout.
* Fixed SBOM, PDF, and Excel exports failing after a deploy by auto-recovering from stale-chunk errors.
* Fixed crashes in component health scoring, EPSS data cleanup, the CBOM unsafe-primitives chart, and closing search on the customer licenses table.

***

### 🔧 Technical Improvements

* **Export Performance** — Load PDF and Excel generation libraries only when an export is triggered, shrinking initial page loads.
* **Smarter Caching** — Serve organization issue connections and customer share views cache-first, and normalize policy objects in the client cache to prevent field loss.
* **Polling Discipline** — Stop compliance-card and gradual-polling loops from running indefinitely once their work is done.
* **Compliance Summary Speedup** — Fetch compliance data earlier and render partial results instead of waiting for the full set.
* **SBOM Upload Refactor** — Restructure the SBOM upload service for maintainability and stricter validation.
* **Accessibility & Polish** — Give icon buttons accessible names, standardize table sub-header layouts, and move font sizing to rem-based theme tokens.

***

## 🚀 Release v3.9.7 — July 2026

### ✨ Highlights

* **VEX Import** — Bulk-import third-party VEX documents through a guided wizard, mapping statements onto your SBOM's components with both XML and JSON support.
* **Third-Party Support Status** — Record a support status and supplier description for third-party components, with confidence scoring and assessment cards surfaced across the product overview, SBOM PDF, and CycloneDX exports.
* **SPDX 3.0 Export by Default** — Generate SPDX 3.0 documents by default, now round-tripping VEX and support status alongside standard SBOM data.
* **Vulnerability Remediation View** — See remediation status and a VEX × severity matrix on the SBOM vulnerability tab, backed by KEV-scoped metrics that isolate known-exploited vulnerabilities.
* **TLP Classification** — Apply TLP markings at the organization and project level, with a per-export override so shared documents carry the right handling label.

***

### 🆕 New Features

* **VEX Import Wizard** — Guide the import of third-party VEX documents step by step, with XML and JSON support and a clear indication when the target SBOM has no parts to match against.
* **Third-Party Support Status & Supplier Description** — Assign a support status and supplier description to third-party components to capture how each dependency is maintained.
* **Support Status Confidence** — Score support-level confidence with SBOM scope, so assessment cards reflect how much of the SBOM the status covers.
* **Support Status Assessment & Summary Cards** — Add Product Support Status assessment cards and a summary card set on the SBOM Support Status tab.
* **Support Status in Exports** — Surface third-party support counts in the product overview and SBOM PDF, and add a support explanation to CycloneDX exports.
* **SPDX 3.0 Export & Import** — Default SBOM export to SPDX 3.0 when no version is requested, import and export SPDX 3.0 VEX and support status, and enable SPDX download options in the UI.
* **KEV-Scoped Vulnerability Metrics** — Add KEV-scoped VEX counts and a KEV scope chip on the SBOM vulnerability remediation card to spotlight known-exploited vulnerabilities.
* **VEX × Severity Matrix & Remediation Status** — Break down vulnerabilities by severity and VEX status on the SBOM vulnerability tab, with remediation status at a glance.
* **TLP Classification** — Set TLP classification in project and organization settings, with an export-time override.
* **Overly Broad CPE Detection** — Add the IDT-CPE-003 SBOM Doctor check for CPEs that are too broad, with findings rendered in the dashboard.
* **Support in the Navbar** — Replace the floating support chat with a single-click Support button in the navbar, with one-time cues pointing to its new home.
* **Security Incidents Alpha Badge** — Mark the Security Incidents sidebar item as Alpha.

***

### 🐛 Bug Fixes

* Fixed patch velocity incorrectly counting removed vulnerabilities as detections.
* Fixed loss of original SBOM attachments on re-import.
* Fixed VEX imports failing entirely when a statement had a missing or blank affects reference; such statements now fall through to vulnerability-ID matching.
* Fixed a ResolveLicensesJob crash when a project was deleted mid-run.
* Fixed an SBOM Doctor timeout on vendor-known CPE lookups.
* Fixed SPDX 3.0 root element and copyright fields in exports.
* Fixed Jira ticket creation when auto-priority values fell outside the allowed set, and made Jira errors for unsupported required custom fields readable.
* Fixed TLP markings missing from exports when set via a project default.
* Fixed Jira and Linear default cards showing without an active organization connection.
* Fixed Compliance Summary cards appearing when no products exist.
* Fixed a server validation error when clearing the risk score field in VEX.
* Fixed table selection persisting after bulk VEX, Jira, and Linear submissions.
* Fixed the "Forever" data-retention project default sending an object instead of a value.
* Fixed the confirmation page redirecting before email confirmation resolved.
* Fixed rate-limit and PersistedQueryNotFound errors on customer share views.
* Fixed a removeChild crash on new-user organization creation.
* Fixed stale SBOM part data on the parts view.
* Fixed the support chat fallback when HubSpot fails to load.

***

### 🔧 Technical Improvements

* **Faster Vulnerability Views** — Skip global vulnerability list and count queries on detail views, use dedicated queries for the component filter, and lazy-load VEX tooltip details.
* **GraphQL Error Hardening** — Sanitize GraphQL client errors while preserving request IDs, and improve unauthorized-user handling in error reporting.
* **Security Incidents Gating** — Disable the Security Incidents feature for trial organizations unless explicitly flagged.
* **Responsive Table Layouts** — Improve support-status and other table column layouts on smaller viewports.
* **SupplierDetails Link** — Replace the SupplierTag component with a read-only SupplierDetails link.
* **Lint & CI Hardening** — Clean up RuboCop offenses and tighten the RuboCop CI gate.

***

## 🚀 Release v3.9.6 — June 2026

### ✨ Highlights

* **Organization Impact Timeline** — A new timeline on the customer incident view shows how a security incident's impact across your organization evolved over time, backed by an actor audit trail so you can see who changed what and when.
* **Security Incidents for Free and Trial Orgs** — Security incident tracking is no longer reserved for paid tiers. Free and trial organizations can now create, manage, and review security incidents.
* **Live Vulnerability Scan Updates** — Vulnerability scan status now polls gradually and updates in place, so scan counts in the versions table and the SBOM vulnerabilities view refresh automatically as a scan completes, with no manual reload.
* **Sharper SBOM Doctor Findings** — Doctor cuts false positives by treating git-describe versions as matching the base-tag CPE, consolidates cross-reference findings into one per component, and explains why a CPE wildcard missed. A force-rescan button bypasses the 30-minute cache, and CPE/PURL identifiers are now click-to-copy.
* **Faster, More Resilient Dashboard** — Dashboard load is optimized by parallelizing version and metric fetches, and individual graph widgets now surface failed queries inline with a retry action instead of breaking the whole page.

***

### 🆕 New Features

* **Organization Impact Timeline** — Customer incident view gains a timeline of organization-wide impact with a full actor audit trail.
* **Security Incidents for Free and Trial Orgs** — Open up security incident creation and management to free and trial organizations.
* **Gradual Vulnerability Scan Polling** — Vulnerability scan status updates progressively; the versions table and vulnerability views refresh their counts automatically when a scan finishes.
* **Manual "Copy VEX from this version" Recovery** — Recover VEX data for same-version SBOMs on demand when an automatic same-version copy was incomplete, with a review notification to confirm the copy.
* **SBOM Doctor Force Rescan and Click-to-Copy** — Add a force-rescan button that bypasses the 30-minute cache, and click-to-copy for CPE and PURL identifiers in Doctor findings.
* **Retracted Vulnerability Filtering** — Filter retracted vulnerabilities out of component and SBOM vulnerability lists.
* **SBOM Files CSV Export** — Export the SBOM Files table to CSV.
* **Lifecycle Stage Date Badge** — The version selector badge now shows the lifecycle stage date.
* **48-Hour Invite Expiry** — Organization invitations now expire after 48 hours, with the validity window shown on the invite email and on the invite, accept, and registration screens.
* **Component Vulnerability Label Filter** — Filter component vulnerabilities by label.
* **Inline Jira Config Overrides** — Pass Jira field overrides when sending a test ticket, and see inline-selected Jira fields reflected in test-ticket creation.
* **Vulnerability Metrics** — New vulnerability metrics for tracking and reporting.
* **Support Status CSV with Parts** — Include component parts in the support status CSV export.

***

### 🐛 Bug Fixes

* Fixed fixed-version and last-affected-version data not populating for CPE-matched vulnerabilities, and now show "Affected before \<fix>" when the last-affected version is empty.
* Fixed CPE wildcard prefix matching, and Doctor now explains CPE wildcard miss reasons.
* Fixed handling of duplicate SBOM parts with proper validation.
* Fixed two notification GraphQL field bugs.
* Fixed org-less signups being blocked from reaching organization creation.
* Fixed the registration form to use native form submission.
* Fixed the date picker dropdown staying open when clicking other fields.
* Fixed dashboard summary checkboxes resetting on paid tiers.
* Fixed the Create Rule modal locking up when using Copy.
* Fixed a crash from null rows when sorting the product table by date.
* Fixed product group navigation from the command bar.
* Fixed security incidents page access when the feature is disabled.
* Fixed redirect to the version table when an SBOM no longer exists.
* Fixed "In Triage" status being missing from Progress Overview vulnerability breakdowns.
* Fixed vulnerability stat badges remaining clickable while a scan was in progress.
* Standardized inline field validation across the Set Life Stage, Edit Vulnerability, Create Role, TLP classification, PURL details, Add Parts, Jira config, and CPE modals.
* Fixed sidebar overflow and clipping issues, including when the security incident banner is visible.
* Constrained webhook URL validation to the declared provider.

***

### 🔧 Technical Improvements

* Reduced SBOM Doctor false positives and clarified findings: git-describe-to-base-tag CPE matching, one cross-reference finding per component, and classified reasons for fully-specified uncatalogued CPEs.
* Optimized dashboard load by parallelizing independent version and metric fetches and grouping skeleton graphs, and tuned GraphQL batch sizes so daily metric operations fit in a single batch.
* Disabled Apollo GraphQL request batching to stop slow Doctor queries from head-of-line blocking the rest of the dashboard.
* Completed the dashboard GraphQL feature-module migration; the former monolithic query and mutation files are now re-exports only.
* Stopped benign fetch aborts and deps.dev 400 batch errors from flooding error monitoring.
* Clamped GraphQL query complexity by setting a max page size on organization licenses.
* Fixed 11 npm audit vulnerabilities, including one critical.
* Tuned the ECS deployment runtime with Ruby YJIT and GC settings, and raised the NVD feed download timeout to handle slow feeds.
* Removed the legacy user settings onboarding API and pruned dead code and unused dependencies.
* Cut Doctor tab input latency by decoupling row-action state from the table.
* Expanded Playwright end-to-end coverage for the invitation, password reset, registration, and SBOM Files flows.

***

## 🚀 Release v3.9.5 — June 2026

### ✨ Highlights

* **SBOM File Artifacts** — File-level records are now first-class citizens, tracked separately from components. Interlynk imports explicit file entries from both SPDX and CycloneDX SBOMs, links them to the components they belong to, and surfaces them in their own files view with license filtering. CycloneDX exports gain an "Include File Artifacts" option so you can choose whether file-level detail rides along.
* **Redesigned SBOM Details** — The SBOM Details tab moves to a card-based dashboard layout, with an overhauled document metadata card and a new phases, TLP classification, and supplier summary strip for an at-a-glance read of any SBOM.
* **Clickable Vulnerability Impact Filtering** — Vulnerability impact badges are now clickable and filter the product vulnerability list directly, and the shared vulnerability view gains an expanded layout with VEX status and a risk summary.
* **SBOM Doctor CSV Export** — Export the full SBOM Doctor diagnostics table to CSV for offline review and sharing.
* **Jira Epic Support** — Add Jira epic display and editing to ticketing settings, so issues land in the right epic.

***

### 🆕 New Features

* **SBOM File Artifacts** — Import file-level records from SPDX and CycloneDX SBOMs as dedicated SBOM files, separate from components. Includes file attribution, source linking back to the originating component, a GraphQL API for file artifacts and their annotations, and a files table with license filtering. CycloneDX exports add an "Include File Artifacts" toggle.
* **Redesigned SBOM Details View** — Card-based dashboard layout with a reworked document metadata card, a phases / TLP classification / supplier summary strip, and rich-text rendering of vulnerability descriptions with source and severity badges.
* **Clickable Vulnerability Impact Badges** — Click an impact badge to filter product vulnerabilities, with a redesigned shared vulnerability view showing VEX information and a risk summary.
* **SBOM Doctor CSV Export** — Download the SBOM Doctor results table as a CSV file.
* **Jira Epic Display and Editing** — Manage Jira epics directly from ticketing settings.
* **Concluded License Editing Redesign** — Rebuilt Edit Concluded License modal with a clearer, discoverable delete action.
* **Compact Dashboard Totals** — Dashboard stat totals now render as compact numbers for readability at a glance.
* **VEX Cross-Environment Migration** — New scripts to export and import VEX data between environments.
* **Service Token Support for Security Incidents** — Manage security incidents using service tokens for automation.

***

### 🐛 Bug Fixes

* Fixed a crash when viewing customer SBOM details for an SBOM that had been deleted.
* Fixed pagination not resetting when switching between SBOMs across detail and vulnerability tabs.
* Fixed the versions table not refreshing after an SBOM upload by auto-polling until the version populates.
* Fixed the SBOM tree view losing its pan and zoom position when expanding child nodes.
* Fixed the version actions column getting cut off on narrow viewports.
* Fixed expired ShareLynk links not surfacing their status in the View ShareLynk drawer.
* Fixed SBOM Details not listing the vendor in the tools section.
* Fixed the UI wiping out on transient errors during polling by tolerating partial GraphQL responses.
* Fixed license display overflow and layout issues in the SBOM detail tables.
* Fixed search staying active when all compliance filters were already selected.
* Fixed full-page reloads after login and after starting a trial, replacing them with reactive refetches.
* Fixed super admin users being incorrectly routed through the enterprise onboarding flow.
* Fixed a Postgres error when loading project group component vulnerabilities.

***

### 🔧 Technical Improvements

* Hardened component `partIds` tenant isolation so file and component data stay scoped to the correct tenant.
* Neutralized CSV formula injection in exported CSV fields and prevented an open redirect in the organization-switch flow.
* Updated Puma to 7.2.1 and sidekiq-cron to 2.4.0 to address security advisories.
* Added a max page size and clamped query complexity on GraphQL connections, and corrected the `hasNextPage` pagination guard.
* Optimized batching for the file artifact data migrations.
* Introduced gradual TypeScript adoption in the dashboard, extracted shared mutation hooks, migrated settings and product GraphQL operations to feature modules, and removed an unused dependency.
* Added end-to-end Playwright coverage for the security incident lifecycle.
* Stopped classifying SPDX packages as files and excluded file components from component workflows for cleaner separation.

***

## 🚀 Release v3.9.4 — May 2026

### ✨ Highlights

* **Security Incident Impact Alerts (Alpha)** — Surface malicious-package supply-chain attacks before a CVE exists. When a campaign like Shai-Hulud is confirmed, Interlynk flags the affected package versions and identifies exactly which products across your organizations contain them, so teams can respond ahead of the CVE process.
* **Enterprise User Onboarding** — New guided onboarding flow for enterprise users, backed by a dedicated backend, covering organization setup and profile details.
* **HttpOnly Cookie Authentication** — Move authentication to HttpOnly cookies and remove client-side token storage, hardening sessions against token theft.
* **Faster SBOM Doctor** — Persist Doctor PURL resolution in Postgres with nightly prewarming, index the CPE dictionary, and cut cold-fetch load time for quicker Doctor diagnostics.
* **Organization Profile** — Split the settings profile header into organization and personal sections, with dedicated organization profile details.

***

### 🆕 New Features

* **Security Incident Impact Alerts (Alpha)** — Track malicious-package supply-chain incidents end to end: open an incident, mark affected component versions (manually or imported from CSV), scan SBOMs across organizations to find impacted products, review impact from the dashboard, suppress findings that don't apply, and publish or resolve as remediation lands.
* **Enterprise User Onboarding** — Guided enterprise onboarding flow with a supporting backend, including an organization setup step.
* **Organization Profile Details** — Settings profile header now splits organization and personal profiles, with editable organization details.
* **Jira Permission Health Checks** — Detect and report missing Jira permissions so integration failures surface early.

***

### 🐛 Bug Fixes

* Fixed cookie login losing organization context after the HttpOnly auth migration.
* Fixed several modals, drawers, and tab components issuing GraphQL queries with undefined IDs by adding skip guards.
* Fixed mutations reporting success despite backend errors across 5 components.
* Fixed auth requests failing silently by showing a network error message when no response is received.
* Fixed the session-probe loader in `PrivateRoute` to use the correct `login` loader.
* Fixed the organization avatar showing letter initials instead of the building icon when no logo is set.
* Fixed organization links opening as relative paths in the enterprise onboarding step.
* Fixed org drawer link URLs to auto-prepend `https://` on blur.
* Fixed onboarding step buttons staying enabled during step transitions, and a content flash when finishing onboarding.
* Fixed the shared lynk view by disabling version row selection and correcting signed-URL handling across components.
* Fixed the Pin Product action being available to users without edit permission.
* Fixed `LynkSelect` height not expanding for multi-select tags.
* Fixed list rendering by replacing index-based keys with stable keys across 11 components.
* Fixed CSV export to cap GraphQL page size at 100.
* Fixed a hardcoded warning color by using the `warningTextColor` theme token.
* Renamed the Doctor findings table "COMPONENT" column to "AFFECTED" for clarity.
* Removed the share product action from the products table.

***

### 🔧 Technical Improvements

* **HttpOnly Cookie Auth Migration** — Move token handling server-side, remove client-side token writes, and update Playwright auth fixtures for the new flow.
* **Doctor Performance** — Persist PURL resolution in Postgres with a nightly prewarm job, index `cpe_infos` for dictionary lookups, and reduce cold-fetch load time.
* **GraphQL Complexity Fix** — Remove complexity lambdas that double-multiplied connection scores in graphql-ruby, restoring linear scaling with `max_page_size: 100`.
* **Cursor Pagination** — Switch the CBOM analysis drawer and analytics graph metrics to cursor pagination, replacing fixed `first:N` fetches.
* **Service Object Refactor** — Extract mixed responsibilities out of service `call` methods.
* **React Hooks Hygiene** — Remove the remaining `react-hooks/exhaustive-deps` suppressions across forms, drawers, wizards, modals, and filters, adopting `useEventCallback` where needed.
* **Code Quality** — Move nested component definitions to module scope, extract Executive Summary PDF styles into a shared util, resolve a Tag/Badge style conflict, remove dead code and unguarded production `console.warn` calls, and enforce explicit radix on `parseInt` via ESLint.

***

## 🚀 Release v3.9.3 — May 2026

### ✨ Highlights

* **Doctor Findings Redesign & Coverage Scorecards** — Redesigned Doctor findings table and drawer, plus new coverage overview scorecards on the Doctor tab so users can see SBOM quality at a glance.
* **Hackage and Nixpkgs Package Manager Support** — Add `pkg:hackage` and `pkg:nixpkgs` clients, extending supply chain coverage to the Haskell and Nix ecosystems.
* **Automatic Persisted Queries (APQ)** — Enable APQ for GraphQL on both backend and frontend to reduce request payload and improve query latency.
* **Assigned Before Vulnerability Filter** — Filter vulnerabilities by assignment date end-to-end, with uniform archival activity logging.
* **Customer SBOM Detail Refresh** — Surface SBOM detail stats as cards with expanded tab navigation, and improve the parts tree view header.

***

### 🆕 New Features

* **Doctor Findings Table & Drawer Redesign** — Refreshed findings table and drawer for clearer diagnostics.
* **Doctor Coverage Overview Scorecards** — New scorecards on the Doctor tab summarizing coverage.
* **Doctor Spotlight Counts** — Show critical and high finding counts in the SBOM Doctor onboarding spotlight card.
* **doctorStats Enhancements** — New fields on the `doctorStats` GraphQL query alongside IDT/LIC check robustness improvements.
* **Hackage Package Manager Client** — Resolve and enrich `pkg:hackage` PURLs for Haskell packages.
* **Nixpkgs Package Manager Client** — Resolve and enrich `pkg:nixpkgs` PURLs for the Nix ecosystem.
* **Assigned Before Vulnerability Filter** — New `assignedBefore` vulnerability filter exposed in the UI vuln view, with uniform archival activity logging.
* **Automatic Persisted Queries (APQ)** — Backend APQ support paired with frontend opt-in to reduce GraphQL request size.
* **Component Name Filter** — API-backed component name filter with search and infinite scroll.
* **Enterprise Trial Expiry Banner** — Permanent banner shown when an enterprise trial expires.
* **Customer SBOM Detail Redesign** — Stats shown as cards with expanded tab navigation, plus an improved parts tree view header.
* **Nested Part Stats** — Include nested part component counts in SBOM stats.

***

### 🐛 Bug Fixes

* Fixed CPE dictionary matching robustness for edge cases that previously missed matches.
* Fixed Doctor license precedence so the correct ordering applies when multiple license sources disagree.
* Fixed retracted flag carrying over when duplicating vulnerabilities — the flag now resets on duplication.
* Fixed FK violations on `sbom_activities` by using `attribution_user_id` for service token actors.
* Fixed `NotificationJob` and `DigestNotificationJob` crashing on deleted parent projects.
* Fixed Maven Central `published_at` to use the Solr timestamp, falling back to HEAD `Last-Modified`.
* Fixed pagination and ordering for the SBOM vulnerabilities resolver.
* Fixed onboarding backfill being stuck for sole free-org members with pre-existing products.
* Fixed pending-invite acceptance flow for OAuth and SAML sign-ins.
* Fixed SAML tenant validation during lookup.
* Fixed trial expiry authorization bypass window.
* Fixed onboarding step-transition flash on the Configs step.
* Fixed "vulnerabilty" misspelling across 7 occurrences in 5 files.
* Fixed low contrast for the NEW badge and step dots in dark mode during onboarding.
* Fixed LynkDate calendar month-label alignment with navigation arrows.
* Fixed blank page on production and staging deploys via correct cache headers.
* Fixed list rendering by replacing index keys with stable IDs across mutable list components.
* Fixed attribution selected-rows export to paginate and respect `max_page_size`.
* Fixed sidebar active-state fade lag and collapsed logo clipping.
* Fixed duplicate focus outline from `useSelect` control styles.
* Fixed APQ being unintentionally enabled in development, restoring full query visibility in devtools.
* Fixed null safety for date fields, a Support Status crash, and Users row count in CSV export.
* Fixed analytics component and license count graphs always showing 0.
* Fixed stale chart renders caused by JSX inside `useState` initializers.
* Fixed VEX log CSV export to filter null fields and keep the modal open on error or no-data for retry.
* Fixed Blob URL memory leak on CSV download.
* Fixed onpopstate handler stability and guarded the `DoctorFilterOptions` query.
* Fixed vulnerability delete query skip to require `vulnIdentifier` presence.
* Fixed create-org being available to free-tier and enterprise-trial users.
* Fixed Exec Dashboard vulnerability counts ignoring label filtering.
* Fixed missing required role in the invite user modal.
* Fixed duplicate-email errors being shown during registration.
* Fixed broken mutation refetches by normalizing query names.
* Fixed `useEffect` deps in Connections to prevent stale closures, and kept slack/teams/email data as arrays.
* Fixed Connections skeleton column alignment with the loaded grid.
* Fixed responsive layout in Product Settings by replacing fixed-width cards with a responsive grid.
* Fixed environment selector being enabled in the Pin Env modal for free-tier orgs.
* Fixed `ConfigModal` create-vs-update detection by checking `data.length`.
* Fixed `useCustomToast` `showToast` reference stability.
* Fixed `useLazyDropDown` infinite scroll regression.
* Fixed `target="_blank"` links to include `rel="noopener noreferrer"`.

***

### 🔧 Technical Improvements

* **AppSignal Observability** — Instrument outbound HTTP and handled controller errors, and add caller identification tags to the ComplexityLogger gauge.
* **GraphQL Hardening** — Disable introspection queries outside development, remove `compiled_queries` from the persisted query config, and disable the Nix package manager client on production.
* **GraphQL Domain Modularization** — Extract Activities, Analytics, Automations & Rules, Custom Fields, Integrations, Licenses, Notifications, Policies, ShareLynk, and seven additional domains into feature modules; align mutation operation names with JS export identifiers.
* **Performance** — Memoize the `GlobalQueryContext` provider value; cut SBOM checks filter re-renders with stable handlers and memoized children; lazy-load `PolicyTable`, `SharedProductList`, recharts in CBOM and Executive Summary drawers, and `@react-pdf/renderer`; replace the wildcard d3 import with targeted subpackage imports in `Tree.jsx`.
* **Internal Components Mutation Errors** — Improve error feedback for Internal Components mutations.
* **Doctor UI Refactor** — Replace the inline component menu with `LynkComponentFilter`.
* **Accessibility** — Use a mode-aware focus border color on `Input`, `NumberInput`, and `Textarea`; add aria-label to the role select and accessibility selectors for Doctor suppressions.
* **Code Quality** — Replace deprecated `.substr()` and add a no-restricted-syntax ESLint rule; enforce strict equality in `styleUtils`; ignore build and test artifact directories in ESLint; replace the `GrDocumentCsv` icon with `LuFileSpreadsheet`.
* **Security Hygiene** — Remove hardcoded Playwright credentials from env template files; remove debug logs and derive the SSO ACS URL outside form state; bump vulnerable gems flagged by Dependabot alerts.
* **Dependency Bumps** — Bump `@interlynk-io/cpe-js` and `purl-js` to latest versions.
* **E2E Test Coverage** — Add E2E tests for the SBOM Doctor check flow, Doctor suppression checks, role selection in invites, and slack/teams flow stability.

***

## 🚀 Release v3.9.2 — April 2026

### ✨ Highlights

* **SBOM Doctor UI** — Ship the user-facing Doctor experience with org-level rollout flag (`sbomDoctorEnabled`), human-readable findings summaries, project-scoped suppressions, and Redis-cached results — making SBOM quality diagnostics consumable end-to-end.
* **Pinned Products** — Bookmark and pin frequently accessed products with a backing GraphQL bookmarks API and a dedicated dashboard section with field-level pin selection.
* **Onboarding Configs Step** — Add a Configs step covering email notifications, Dependency Cooldown, and Risk Exposure policies, plus an "Something else" intent card with a conditional Upload step and new MCP server / CLI feature cards.
* **Security Hardening** — Fix AWS marketplace token exposure in URLs and referrer headers, encode SAML tenant name to prevent query parameter injection, and apply correct autocomplete attributes on the login form.
* **pkg:cpan Package Manager Support** — Add a CPAN client for `pkg:cpan` PURLs, extending supply chain coverage to the Perl ecosystem.

***

### 🆕 New Features

* **SBOM Doctor UI** — Full Doctor experience with org-level rollout flag, surfacing on the onboarding free-tier features step.
* **Doctor Stats & Results GraphQL Queries** — `doctorStats` and `doctorResults` queries backed by Redis-cached results with explicit invalidation.
* **Doctor Filter Options API & Suppression Audit Logging** — Expose filter options and audit-log Doctor suppression activity, with part SBOM expansion.
* **Project-Scoped Doctor Suppressions** — Manage Doctor suppressions directly from Project Settings.
* **Human-Readable Doctor Findings** — One-liner summaries for Doctor findings.
* **Pinned Products** — Pin frequently used products via a generic bookmarks table with GraphQL mutations and resolver, with field selector in the pin environment modal.
* **Onboarding Configs Step** — Configure email notifications, Dependency Cooldown, and Risk Exposure policies during onboarding.
* **Onboarding Intent Expansion** — "Something else" intent card with conditional Upload step.
* **MCP Server & CLI Feature Cards** — Add MCP and CLI cards to the onboarding features step.
* **pkg:cpan Package Manager Client** — Resolve and enrich CPAN packages for Perl ecosystem support.

***

### 🐛 Bug Fixes

* Fixed AWS marketplace token exposure in URLs, browser history, and referrer headers.
* Fixed SAML URL tenant name encoding to prevent query parameter injection.
* Fixed login form autocomplete attributes.
* Fixed Doctor IDT-VER-001 false positives when CPE splits version into version + update.
* Fixed Doctor LIC-KNOWN-001 false positives from prefix casing and module collision.
* Fixed Doctor structured findings, SBOM-PRIMARY-001, LIC-MISSING-001, and IDT kind scoping.
* Fixed parent-dispositioned vulnerabilities being included in Part Scan Report notifications.
* Fixed Bitbucket webhook sync errors not surfacing and stopped indefinite retry noise.
* Fixed Bitbucket `oauthWorkspaces` failure caused by a deprecated `GET /2.0/workspaces` call.
* Fixed `bsi_property_present?` and `external_urls` checks against nil array entries.
* Fixed JSON validation middleware to rescue `BadRequest` and `MimeNegotiation::InvalidType` errors.
* Fixed silent mutation failures and always-close bugs across VEX, CVSS, Author, Supplier, modal, drawer, and table mutation calls.
* Fixed `useCustomToast` destructuring bug silently breaking error toasts in 4 components.
* Fixed user stuck on the onboarding Configs step.
* Fixed `ComponentCard` modal failing to close on navigate and search input desync.
* Fixed `componentFilter` search results reverting after Enter key press.
* Fixed `asyncFilter` `filteredNodes` not updating on search.
* Fixed ShareLynk drawer overflow.
* Fixed global policy expand view.
* Fixed hidden action button in the vulnerability table ASSIGNED column.
* Fixed default vulnerability count fields returning empty objects instead of 0.
* Fixed `hasReportedSessionExpiry` flag not resetting on logout, silently suppressing auth errors.
* Fixed casing inconsistency in the invalid credentials login error message.
* Fixed loading view not shown while user permissions are being fetched.
* Fixed lazy module resolving without a default export.
* Fixed `fetchPolicy` option not forwarded through `usePaginatedQuery`.
* Fixed `useLazyDropDown` refetch destructuring bug.
* Fixed `CreateParts.jsx` error handling missed in the modals PR.
* Fixed Customer SBOM and IntersectingVulns queries firing before route params or version were ready.
* Fixed per-item unpin loading state and limited labels to 2 in PinnedProducts.

***

### 🔧 Technical Improvements

* **GraphQL Complexity Cap** — Cap query complexity at `max_page_size` and log the first variable for diagnostics.
* **Doctor Backend Hardening** — PURL resolution correctness, batch pre-fetch, cache invalidation, integration specs, suppression improvements, and code quality.
* **Service Response Contract Standardization** — Standardize service response contracts across the API surface.
* **Extract Purl to `lynk_purl` Gem** — Move PURL handling into a dedicated gem.
* **Version Field Naming Consistency** — Align version field names across components, CPE, and PURL.
* **GraphQL Domain Modularization** — Extract Compliance and Components domains into feature modules; rename remaining camelCase mutations to PascalCase.
* **AppSignal Observability** — Breadcrumbs for the policy evaluation flow; suppress Sidekiq fetch-loop `RedisClient::ReadTimeoutError` and session-expiry noise; classify expected authorization errors separately.
* **PostHog on Staging** — Stop initializing PostHog on staging.
* **Performance** — Replace barrel imports with module imports in `data-display`; lift `RenderLink` to module scope and add sidebar hover prefetching; stable IDs across list renders; memoize derived values in `ProductDetailsSbomNew`; eliminate unnecessary re-fetches on product detail tabs and notification tab switches; deduplicate `GraphQL` operation names and `GetAllPermissions` fetch; load third-party analytics asynchronously.
* **Mutation Refetch Hygiene** — Wire targeted `refetchQueries` on unguarded mutations; suppress active `refetchQueries` on no-op mutations.
* **Empty States & UI Polish** — Charts previews with empty states across dashboard; toast colors via theme keys instead of hex literals.
* **Refactors** — Split `JiraCreateIssueModal` into a focused hook and component; move Licenses page to views and fix eager bundle import; replace moment.js and react-datetime with react-datepicker + date-fns; skip `GetOrgMfc` outside the environment-defaults tab.
* **Cleanup** — Remove unused third-party CDN resources from `index.html`; remove patch for `react-data-table-component` 7.7.0.

***

## 🚀 Release v3.9.1 — April 2026

### ✨ Highlights

* **SBOM Doctor API** — Introduce a new Doctor API with a stateless orchestrator and a comprehensive suite of identifier, license, CPE, and version consistency checks — giving users programmatic SBOM quality diagnostics.
* **Component Age Policy Rules** — Add `component_published_at` age as a policy field, enabling compliance rules that flag stale or outdated components.
* **Jira Components Field Support** — Configure Jira Components directly in Jira defaults so auto-created tickets route to the right team.
* **Compliance & Vulnerability Email Digests** — Ship a weekly compliance email digest and a vulnerability notification digest to summarize activity without inbox noise.
* **Platform Modernization** — Upgrade the Ruby runtime from 3.2.10 to 3.4.9 and patch Devise 5.0.3 and Rails 7.2.3.1 for improved performance and security.

***

### 🆕 New Features

* **SBOM Doctor API** — New `Api::V1::DoctorController` and route, backed by a stateless check orchestrator, with Rack::Attack rate limiting for fair use.
* **Identifier Validation Checks** — PURL syntax validation (IDT-PURL-001), PURL registry resolution (IDT-PURL-003), CPE dictionary lookup (IDT-CPE-002), missing identifier detection (IDT-MISSING-001), and CPE/PURL cross-consistency (IDT-XREF-001).
* **License Validation Checks** — SPDX license list validation (LIC-KNOWN-001), license expression syntax (LIC-SYNTAX-001), and license registry comparison (LIC-REGISTRY-001).
* **CPE Syntax & Version Consistency Checks** — Additional Doctor checks for CPE syntax and for version consistency across components.
* **Component Published Age Policy Field** — Use component publish age in policy rules for age-based compliance.
* **Jira Components in Defaults** — Set Jira Components when configuring Jira defaults for automated ticket creation.
* **Weekly Compliance Email Digest** — Automated weekly summary of compliance status for organizations.
* **Vulnerability Notification Digest** — Consolidated vulnerability alerts delivered as a digest.
* **Duplicate Jira Connection Prevention** — Block creation of duplicate Jira connections within the same organization.
* **Free-Tier Locked Menu Items** — Show locked states for custom vulnerability actions, SBOM action selector items, and component action menu items for free tier users instead of hiding them.

***

### 🐛 Bug Fixes

* Fixed deps.dev PURL encoding, Maven qualifier normalization, and cache versioning.
* Fixed `respond_to_on_destroy` signature for Devise 5 compatibility.
* Fixed ProjectGroupDeletionJob timeout and silent failures.
* Fixed support-level scan behavior for non-active SBOMs.
* Fixed stale ShareLynk session persisting when returning to the vendor dashboard.
* Fixed component data falling out of sync after updates.
* Fixed Jira issue creation failure toast to surface the full error object (dev only).
* Fixed `GetLabelsList` firing on the customer portal and scoped the ShareLynk token to customer routes.
* Fixed 429 burst on the customer SBOM versions page.
* Fixed wrong query on first render in VersionsTable by passing `isShareLynk` correctly.
* Fixed breadcrumb flicker and skeleton loading state in SBOM details.
* Fixed missing version handling in the CustomVuln component option label.
* Fixed analytics graph layout on filter cards.
* Fixed PURL delete/add display in the activity log.
* Fixed stray JSON array brackets appearing on CPE values in the activity log.
* Fixed enterprise metrics cards being visible to free-tier users.
* Fixed active compliance check incorrectly available in the free tier.
* Fixed double triggering of the `packageVersions` query.
* Fixed free-tier content flash in `ConditionalRoute`.
* Fixed unnecessary `refetchQueries` firing from onboarding mutations.
* Fixed missing empty state when no analytics charts are selected.
* Fixed `GetLabelsList` query firing for free tier users.
* Fixed Jira required field indicators, tooltip placement, and feed layout.
* Fixed `ConditionalRoute` infinite loop during render.
* Fixed `GetAttributionsData` query complexity by splitting it and adding a default page size.
* Fixed ExecutiveSummaryDrawer queries not respecting the `max_page_size` cap.
* Fixed custom field stepper preview in the VEX modal.
* Fixed `useFetchAllNodes` infinite loop caused by unstable object references in `useEffect` dependencies.
* Fixed inaccurate label counts by fetching all product groups for the dashboard.
* Fixed severity popover appearing before SBOM scan data was ready.
* Fixed drag and close actions showing on analytics page dashboard cards.
* Fixed RelationshipDrawer Card wrapper breaking dark mode.
* Fixed kbar command bar not filtering actions on the free tier.
* Fixed the Add button being enabled while custom fields were still loading.

***

### 🔧 Technical Improvements

* **Ruby 3.4.9 Upgrade** — Upgrade from Ruby 3.2.10 for performance and security.
* **Dependency Patching** — Bundle audit updates for Devise 5.0.3 and Rails 7.2.3.1, plus gem refreshes.
* **OrgVulnScanJob Optimization** — Cleanup and performance tuning for organization-wide vulnerability scans.
* **Compute-on-Read Cleanup** — Remove dead `check_results` code and drop the table after the compute-on-read migration.
* **Schema Sync** — Keep `schema.rb`, `data_schema.rb`, and annotate-gem comments aligned.
* **Doctor CheckLogic Foundation** — Scaffold `Doctor::CheckLogic::Base` and `ComponentStruct` for future checks.
* **Stale Reference Cleanup** — One-off script to fix stale `sbom_parts.part_id` references.
* **Vulns Pagination Cap** — Add `max_page_size: 100` on the vulns connection of `SbomType`.
* **GraphQL Query Leanness** — Split `ComponentColumnData` into lean table and on-demand detail queries; add dedicated lean queries for `automatedFixesEnabled`, compliance SBOM ID lookup, and onboarding-specific variants.
* **Breadcrumb Query Parallelization** — Parallelize Wave 1–2 breadcrumb queries with Wave 3.
* **Dashboard Query Deduplication** — Hoist `sbomIds` fetch to the dashboard page to eliminate duplicate queries; skip compliance queries when no compliance cards are selected.
* **React Rendering Optimizations** — `React.memo` on table cell renderers; memoize chart data transformations, vulnerability filter/map operations, global state context value, and dashboard card state; reduce vulnerabilities table default page size to 20.
* **Apollo Fetch Policy Cleanup** — Reduce unnecessary network-only fetch policies across queries.
* **Compliance Score Config** — Consolidate compliance score switch cases into a config map.
* **Label Filter Rendering** — Improved label filter rendering behavior in the product table.
* **E2E Test Coverage** — Add Playwright tests for the Free SBOM Compliance Checker, compliance report export, Jira Components field selection, and stabilize product-delete timing.
* **Color Mode Hygiene** — Document and clean up `useColorMode` non-color usages.

***

## 🚀 Release v3.9.0 — April 2026

### ✨ Highlights

* **Free Tier Onboarding Experience** — Introduce a complete guided onboarding flow for free tier users, including automated ShareLynk creation, compliance selection, animated SBOM scoring, and email notification setup.
* **Manual Scan for Webhook-Connected Projects** — Trigger on-demand scans for projects connected via webhooks, starting with Bitbucket support.
* **Free Tier UX Overhaul** — Replace hidden features with locked states, upgrade prompts, and clear plan limits across the dashboard, sidebar, and product tabs — giving free tier users full visibility into available capabilities.
* **Compliance Report Export** — Export compliance reports directly from the dashboard with a new dedicated export action.
* **pkg:hex Package Manager Support** — Add Hex package manager client, extending supply chain visibility to the Elixir/Erlang ecosystem.

***

### 🆕 New Features

* **Guided Onboarding Flow** — Walk new free tier users through product creation, SBOM upload, compliance configuration, and score reveal with back navigation and loading feedback.
* **Auto-Created ShareLynk on Onboarding** — Automatically generate a ShareLynk during onboarding and display a share card on the score reveal step.
* **Auto-Created Email Notifications on Onboarding** — Set up email notifications automatically as part of the onboarding flow.
* **Manual Scan for Webhook Projects** — Add a manual scan option for projects with webhook connections (Bitbucket).
* **pkg:hex Package Manager Client** — Resolve and enrich Hex packages for Elixir/Erlang ecosystem support.
* **Compliance Summary Dashboard Cards** — Display compliance summary cards on the main dashboard.
* **Basic Compliance Report Export** — Export compliance reports from the compliance dashboard.
* **Upload Date Sorting for SBOMs** — Add an upload date column for sorting SBOMs and versions.
* **Dedicated ShareLynk Button** — Add a dedicated ShareLynk button to the product table for faster sharing.
* **Free Tier API Token Access** — Ungate API token create/delete for free tier users with a 1-token limit.
* **Viewer Notification Preferences** — Allow Viewer-role users to edit their personal notification preferences.
* **Locked Feature Components** — Introduce reusable locked feature components with upgrade CTAs for gated enterprise features.
* **Free Tier Plan Limit Constants** — Add global constants for free tier plan limits for consistent enforcement.
* **SBOM Lifecycle Phase in Checks** — Wire SBOM lifecycle phase to SBOM checks for lifecycle-aware compliance.

***

### 🐛 Bug Fixes

* Fixed ImportedRepositoryType crash for GitLab and GitHub repositories.
* Fixed stale compliance scores caused by untracked import and license run status.
* Fixed free-tier 5-SBOM-per-product and 5-product limits not enforced server-side.
* Fixed parts and VEX data lost on same-version SBOM displacement.
* Fixed "Assigned On" displaying detection date instead of disposition date for VEX assignments.
* Fixed Debian release suffix handling in CPE version comparison.
* Fixed per-SBOM vulnerability stats regression affecting parts aggregation.
* Fixed pre-release version handling.
* Fixed OAuth connection validation before dispatching manual scan.
* Fixed SBOM deletion job errors not re-raised for Sidekiq retries.
* Fixed free-tier vulnerability count restriction in grouped queries.
* Fixed Apollo cache infinite loop and missing ID normalization.
* Fixed personal Slack connection deletion failure.
* Fixed environment switcher accessible to free tier users.
* Fixed SBOM delete mutation errors not surfacing in the delete modal.
* Fixed check modal using incorrect component ID.
* Fixed NVD alias ID field displaying misleading information.

***

### 🔧 Technical Improvements

* **SbomRetentionJob Overhaul** — Switch to async deletion with throttled concurrency, batched loading, and per-project error isolation.
* **N+1 Query Prevention** — Complete eager loading in DeleteServiceSync to eliminate N+1 queries.
* **Jira Rate-Limit Backoff** — Add rate-limit backoff to BulkAutoTicketCreationJob for more reliable Jira integration.
* **Attributions Pagination** — Add max page size of 100 to the attributions connection on QueryType.
* **Remove Demo Data on Org Creation** — Stop auto-creating demo data when a new organization is created.
* **ComplianceCard Extraction** — Extract ComplianceCard component and optimize list rendering performance.
* **Safe URL Construction** — Replace string concatenation with URL API for secure URL building.
* **Stable React Keys** — Replace array index keys with stable unique identifiers across components.
* **Apollo Client Cleanup** — Remove deprecated variables option from useLazyQuery.
* **E2E Test Reporting** — Integrate neeto-playwright-reporter and stabilize flaky Playwright tests.
* **CI/CD Improvements** — Fix SBOM workflow env vars and skip signing when SBOM is not generated.

***

## v3.8.9

Mar 19th 2026

***

### ✨ Highlights

* **Compliance Framework Expansion** — Add BSI TR-03183-2 v2.1.0 and OpenChain Telco SBOM Guide v1.1 compliance frameworks, enabling organizations to validate SBOMs against the latest European and telecom industry standards.
* **Vulnerability Performance Overhaul** — Fix a 48x regression in global vulnerability list pagination and optimize SbomVulnsJob and SbomPolicyScanJob with batched Redis operations, bulk inserts, and up to 100x fewer queries.
* **New Package Manager Support** — Add pkg:composer and pkg:github package manager clients, expanding supply chain visibility to PHP and GitHub-hosted components.
* **SBOM Parts Visualization** — Introduce an interactive D3 tree drawer for visualizing SBOM component relationships directly from the Parts tab.
* **PostHog Product Analytics** — Integrate PostHog analytics to capture product usage patterns and support data-driven feature decisions.

***

### 🆕 New Features

* **BSI TR-03183-2 v2.1.0 Compliance** — Compute-on-read quality checks and a full compliance framework for BSI TR-03183-2 v2.1.0, supporting European SBOM regulatory requirements.
* **OpenChain Telco SBOM Guide v1.1 Compliance** — Add compliance support for the OpenChain Telco SBOM Guide, targeting telecom industry supply chain requirements.
* **pkg:composer Package Manager Client** — Resolve and enrich PHP Composer packages for improved supply chain coverage.
* **pkg:github Package Manager Client** — Resolve GitHub-hosted packages with support for tag-only repos, abbreviated SHAs, and expired token handling.
* **RubyGem Package Manager** — Add RubyGem package manager and client implementation for Ruby ecosystem support.
* **CSV Export for Licenses Table** — Export license data to CSV directly from the licenses table view.
* **Custom Vulnerability Editing and Deletion** — Add edit and delete support for custom vulnerabilities.
* **SBOM Parts Relationship Tree** — View interactive D3-based component relationship trees from the Parts tab via a new "View Relations" button.
* **Organization Manufacturer Defaults** — Add organization manufacturer to project setting defaults and environment defaults.
* **External Issue Tracker "Other" Provider** — Support "Other" as an issue tracker provider for external issue tracker links.
* **Paginated Projects in Project Groups** — Implement paginated projects connection for project groups, improving load times for large groups.
* **Webhook Management Rake Task** — Add rake task to manage webhooks for organizations.
* **API Token Expiry Notifications** — Send expiry warning and expired emails for API tokens approaching or past their expiration date.

***

### 🐛 Bug Fixes

* Fixed **CPE/NVD matching gaps** across seven identified scenarios for more accurate vulnerability correlation.
* Fixed **orphaned records** left behind during SBOM deletion by expanding hard-delete coverage to all soft-deleted orphans.
* Fixed **policy rule violation cleanup** for orphaned violations from removed SBOM parts.
* Fixed **SbomVulnsJob retracting vulnerabilities** across different sources incorrectly.
* Fixed **NoMethodError in ComponentVulnCustomField** during bulk VEX update by filtering empty custom field values.
* Fixed **CPE handling** to use only the first CPE from SPDX external refs and replace hand-rolled CPE parsing with a dedicated library.
* Fixed **vulnerability bulk action overlap** issue in the UI.
* Fixed **product progress overview** not being visible.
* Fixed **delete button visibility** in dark mode.
* Fixed **Jira create button** remaining enabled before required fields are filled.
* Fixed **stale chunk errors** with hardened lazy import error recovery.
* Fixed **auth debug logs leaking** in production builds.
* Fixed **Risk Analysis text wrapping** in vulnerability detail textbox.
* Fixed **Apollo cache** being completely disabled, restoring proper cache behavior with HttpLink in development and BatchHttpLink in production.
* Fixed **missing rules** in policy scanning.
* Fixed **levenshtein comparison crash** when either version string is nil.
* Fixed **demo SBOM creation reliability** with async job processing and retries.

***

### ⚙️ Technical Improvements

* **SbomVulnsJob Optimization** — Batch Redis operations, bulk inserts, and pluck-based queries for significantly faster vulnerability processing.
* **SbomPolicyScanJob Optimization** — Reduce query count by 100x through scan policy restructuring.
* **GetComponentColumnData Query Optimization** — Optimize component column data query performance.
* **GetGlobalVulnerabilityList Fix** — Resolve 48x page-fetch regression in global vulnerability listing.
* **Webhook Reliability** — Add retry logic for webhook job errors, reconciliation support, and race condition prevention during repository imports.
* **SBOM Alternative Depth Limiting** — Cap SBOM alternative depth to 3 per primary to prevent unbounded traversal.
* **NVD ID in Exported SBOMs** — Use NVD ID in exported SBOMs when available for improved interoperability.
* **Jira Connection Factory** — Replace duplicated Jira connection patterns with a centralized factory.
* **Compute-on-Read Quality Checks** — Move SBOM quality checks to compute-on-read for fresher results without batch processing.
* **PostHog Analytics Integration** — Integrate PostHog for product analytics and route-change tracking.
* **AppSignal Breadcrumbs** — Add breadcrumbs for SBOM upload, download, compare, delete, and route-change events for improved debugging.
* **Apollo Client Optimization** — Reduce GraphQL query complexity, optimize label queries, and remove unused query exports.
* **PURL Library Migration** — Migrate PURL utilities to `@interlynk-io/purl-js` and sync purl package types with the official purl-spec.
* **Error Handling Hardening** — Add `safeJsonParse`, guard against `MissingAttributeError`, and add error handling to unguarded `useQuery` calls.
* **Playwright Test Migration** — Migrate 54 litmus tests to Playwright with global auth setup, auto-recovery, and stabilized test selectors.
* **GraphQL Cleanup** — Remove deprecated `onError` usage, fix Apollo Client `onCompleted` deprecation warnings, and consolidate product-related queries.
* **SBOM Download Optimization** — Minimize network requests during SBOM download operations.

***

## v3.8.8

Mar 5th 2026

***

### ✨ Highlights

* **Service Token Support** — Introduce service tokens for machine-to-machine authentication, enabling secure programmatic access to the platform without tying credentials to individual users.
* **Command Bar Version Search** — Expand the command bar with version-level search, making it faster to locate specific product versions across the organization.
* **Dashboard Performance Overhaul** — Significant dashboard speed improvements through batched GraphQL queries, inlined SBOM stats, and migrated vulnerability charts to a new grouped resolver, eliminating waterfall loading patterns.
* **Security Hardening** — Prevent shell injection in CI workflows, add OAuth URL validation with SafeRedirect, sanitize URL schemes against XSS, and ban specific email addresses from API access.
* **Server-Side Health Scoring** — Replace client-side health score calculations with server-side values for both SBOM and component health, ensuring consistent and accurate scoring across all views.

***

### 🆕 New Features

* **Service Tokens for Machine-to-Machine Access** — Create and manage service tokens with dedicated permissions, allowing CI/CD pipelines and automation tools to authenticate without user-bound credentials. Includes a refactored security token table with reusable columns.
* **Version-Level Command Bar Search** — The command bar now supports searching across product versions org-wide, powered by a new `project_versions` GraphQL resolver.
* **SBOM Expiration Fields** — Add `expiresInDays` and `isExpired` field support, with a server-side `expiringVersionsCount` field on the Project type replacing client-side expiration counting.
* **Vulnerability Counts Grouped Resolver** — New `VulnCountsGroupedResolver` enables efficient aggregated vulnerability count queries, used by the dashboard pie charts.
* **Branded Cover Pages** — Executive summary reports now feature branded cover pages aligned with the design system.
* **Vendor Sidebar Navigation Groupings** — Add section groupings to the vendor sidebar navigation for improved discoverability.
* **Conditional SBOM Download** — The SBOM download resolver now supports a `requireCompleted` argument to ensure only fully processed SBOMs are downloaded.
* **SBOM Retention Expiration Fix** — Correctly count expiring SBOMs for retention periods shorter than 7 days.

***

### 🐛 Bug Fixes

* Fixed **OAuth token handling** to read tokens from URL fragments instead of query params, and resolve `flatMap` returning undefined when token refresh fails.
* Fixed **SBOM vulnerability finder** crash caused by empty UNION queries.
* Fixed **batch GraphQL error isolation** so per-query errors no longer cascade across requests.
* Fixed **DefectDensityMetrics 500 error** by replacing N+1 queries with batch SQL.
* Fixed **SBOM import crash** when supplier, author, and tool fields are all blank.
* Fixed **OSV false positives** by filtering affected entries by distro ecosystem.
* Fixed **unauthorized response format** to return JSON instead of an empty 401.
* Fixed **Jira vulnerability management config** resolver and skip Jira config query when org has no Jira connection.
* Fixed **notification preference update** crash when organization user is nil.
* Fixed **primary component editing** with missing SBOM ID.
* Fixed **license field clearing** on input blur.
* Fixed **stale vulnerability parts** by clearing `partIds` when SBOM ID changes.
* Fixed **ProductInfo error** when project setting is null.
* Fixed **CustomList crash** when options prop is undefined.
* Fixed **height mismatch** in EPSS and policy expanded views.
* Fixed **sidebar icon shift** on hover and increase icon size.
* Fixed **missing PURL value** in executive summary view.
* Fixed **vulnerability status history** with misnamed entries.
* Fixed **default vulnerability sort order** to use published date.
* Fixed **GraphQL query guard** against invalid SBOM IDs.
* Fixed **org registration warning flicker** after logout.
* Fixed **SbomDownloadFinder crash** on ShareLynk downloads.

***

### ⚙️ Technical Improvements

* **Dashboard Query Optimization** — Replace `getProductsByStage` with `getVersionLifestage`, inline SBOM stats into `GetLatestVersions`, and reduce GraphQL batch interval for faster dashboard response times.
* **Component Log Processing Optimization** — Prevent statement timeouts and reduce N+1 queries during component log processing.
* **SafeRedirect Concern** — Implement OAuth URL validation and update controllers to use `safe_redirect_to` for secure redirects.
* **XSS Prevention** — Validate URL schemes and escape HTML in `value_format_helper`.
* **Shell Injection Prevention** — Harden GitHub Actions workflows against command injection.
* **DRY Violation Cleanup** — Fix DRY violations across CRUD services and add `frozen_string_literal` pragma to service files.
* **Time Handling Standardization** — Replace `DateTime.now` with `Time.current` for consistent time zone handling.
* **Transient Error Handling** — Handle EOF errors in GraphQL requests and stop reporting client `JSON::ParserError` to AppSignal.
* **Activity Log Optimization** — Skip logging redundant system events to reduce noise.
* **GraphQL Query Organization** — Move vulnerability, organization settings, and user management queries into dedicated files; create shared `SbomStatsFields` and `VulnerabilityMetricsFields` fragments.
* **Refactored Organization Creation** — Streamline organization creation and AWS entitlement sync flow.
* **OrgProjectSettings Job** — Move to Sidekiq for background processing.
* **Playwright Test Migration** — Migrate 23 litmus tests to Playwright system tests.
* **Performance Micro-Optimizations** — Memoize handlers in SBOM checks header, replace framer-motion with CSS transitions, add passive scroll listeners.

***

## v3.8.6

Feb 19th 2026

***

### ✨ Highlights

* **Project-level TLP Classification** — Set Traffic Light Protocol (TLP) classifications at the project and organization level, with automatic cascade down to SBOMs and override support at export time.
* **CRAN (R Package) Support** — The Component Library now supports CRAN, the R package manager, enabling automated support status determination for R components.
* **Dedicated API Token Permissions** — A new `manage_api_tokens` permission allows Operators and Developers to manage API tokens for CI/CD pipelines without requiring full organization settings access.
* **Batch Enrichment for Component Library** — GitHub repository enrichment now uses batch fetching for significantly faster component library processing.
* **Rails 7.2 Upgrade** — The backend has been upgraded to Rails 7.2, bringing improved performance, security patches, and framework modernizations.

***

### 🆕 New Features

* **Project-level TLP Classification with Cascade to SBOMs** — TLP classification can now be set at the Project level and Organization level, with SBOM-level override. The effective classification cascades from SBOM → Project → Organization, and export supports `tlpClassificationOverride` at download time.
* **CRAN (R Package Manager) Support** — Added a CRAN API client and package manager for fetching R package metadata. Includes two-tier archived detection and mapping of R license formats to SPDX identifiers.
* **Dedicated API Token Management Permission** — Introduced a `manage_api_tokens` permission decoupled from `update_organization`, so users with Operator or Developer roles can create and manage API tokens without needing org-settings access.
* **Batch API for Component Library Enrichment** — GitHub repository enrichment now leverages batch fetching and improved rate limit handling for faster and more reliable component library processing.
* **Free Tier Scan Limitation Banner** — Vulnerability and policy pages now display an informational banner for Free Tier users, clearly communicating scan limitations.
* **Auto-Switch Organizations on Product Links** — Following a product page link now automatically switches to the correct organization context, improving navigation for users managing multiple organizations.
* **GraphQL Query Complexity & Depth Monitoring** — Added complexity and depth analyzers for GraphQL queries to monitor and protect against expensive operations.
* **Environment Tagging for Notifications** — All internal Slack messages and mailer subjects now include environment tags (e.g., `[Dev]`, `[Staging]`), making it easy to distinguish notifications across environments.
* **SHA-256 Compatibility** — Added support for SHA-256 hash matching across the platform.
* **Conditional Compliance Check Preview** — Compliance check links now show a conditional preview, improving the user experience when reviewing compliance results.

***

### 🐛 Bug Fixes

* Fixed **sidebar freezing** that occurred randomly while navigating between pages.
* Fixed **multi-tab logout synchronization** — logging out in one tab now properly reflects across all open tabs.
* Fixed **login page crash** and resolved raw server error strings being rendered in the login form.
* Fixed **password lingering in React state** after form submission — credentials are now properly cleared.
* Fixed **cookie expiry not being set**, which caused authentication tokens to persist indefinitely.
* Fixed **vulnerability scan warning flicker** that appeared briefly during page navigation.
* Fixed **SPDX validator marker rendering** issue that occurred on input blur.
* Fixed **project environment breadcrumbs** navigation not working correctly.
* Fixed **tier check error** that showed a misleading "upgrade your plan" message when organization context was missing.
* Fixed **401 errors for unauthenticated batch GraphQL queries** — batched operations like invitation acceptance now work correctly for unauthenticated users.
* Fixed **org registration email errors** caused by jobs executing before the database transaction committed.
* Fixed **foreign key violation** when deleting policy results.
* Fixed **component supplier delete** failing on row expand.
* Fixed **custom vulnerability fields validation** not working correctly.
* Fixed **SBOM vulnerability stats tooltip** display issue.
* Fixed **repeated logout API requests** being sent unnecessarily.
* Fixed **incorrect license stats link** appearing in the SBOM relation table.
* Fixed **filter data not syncing** when an SBOM part is removed.
* Fixed **free tier check** missing from the analytics graph.
* Fixed **transient 401 errors** during JWT refresh window being incorrectly reported.
* Fixed **products policy table** row background color inconsistency.

***

### ⚙️ Technical Improvements

* **Upgraded Rails from 7.1 to 7.2** — Includes updated framework defaults, refactored transaction blocks, and preparation for Rails 8.0 compatibility.
* **Optimized Docker image** — Updated base image to `ruby:3.2.10-slim-trixie`, removed unnecessary runtime packages (AWS CLI, Docker CLI), and optimized layer caching, reducing image size by \~400 MB.
* **Standardized data tables** — Extracted separate column configurations for consistent table rendering across the platform.
* **Centralized color management** — Consolidated theme color logic into a single source, replacing scattered `useColorModeValue` usage.
* **Optimized GraphQL queries** — Extracted shared `PaginationFields` fragment, merged duplicate `GetProductData` queries, and reduced unused fields in sharelynk queries.
* **Improved page load performance** — Hoisted SBOM detail queries out of the loading gate for faster parallel data fetching.
* **Migrated GitHub client from PAT to App tokens** — Component Library now uses GitHub App authentication for improved security and rate limits.
* **Dependency updates** — Updated bootsnap, framer-motion, markdown-it, eslint-plugin-unused-imports, and other

## v3.8.5

Feb 12th 2026

***

### ✨ Highlights

* **AppSignal Integration** — Migrated error monitoring from Sentry to AppSignal with full coverage across the frontend, GraphQL, REST controllers, and background jobs.
* **Vulnerability Query Performance** — Major optimizations delivering up to 64% faster wall time and 51% fewer database queries on vulnerability pages.
* **Policy Filtering** — New filtering capabilities on policy results by product, environment, and version for faster compliance workflows.
* **Auto Org-Switching** — Following an SBOM link now automatically switches to the correct organization context.
* **Security Hardening** — Closed email parser differential vulnerabilities, added Subresource Integrity for CDN resources, and disabled developer tooling in production.

***

### 🆕 New Features

* **HubSpot Analytics & Chat Integration** — Centralized analytics module with user identification, page tracking, and an embedded HubSpot chat widget for in-app support.
* **Auto Organization Switching** — When following a shared SBOM link, the platform now automatically switches to the correct organization so users land directly on the right content.
* **Policy Results Filtering** — Filter policy results by product, environment, and SBOM version directly within a policy's detail view. Version display now shows the format *"version (product name)"* for clarity.
* **Jira Severity Mapping** — Auto-set severity on Jira issues created from policy violations, with configurable severity mappings.
* **Enhanced Ticket Titles** — Auto-created Jira/Linear tickets now include the project name and environment for quick identification (e.g., *"Policy Violation: my-app (production): CVE-2025-XXXX in lib-foo"*).
* **GraphQL Batch Queries** — The API now supports batching multiple GraphQL queries in a single HTTP request, reducing network overhead for complex pages.
* **Risk Region Age in Policy Engine** — Policy rules can now evaluate vulnerability risk based on the age of the affected region.
* **Improved Package Search** — Search results are now sorted by most recently updated, version is optional for packages without one (e.g., file paths), and trigram indexes make ILIKE searches significantly faster.
* **Optimized Command Bar Search** — Product search in the command bar now fetches results only when the user types, with a loading skeleton for better feedback.
* **Reusable Component List** — The component list has been refactored for global usage, removing duplicate implementations and reducing over-fetching.

***

### 🐛 Bug Fixes

* Fixed email parser vulnerabilities that could allow "Splitting the Email Atom" attacks via special characters in email addresses.
* Fixed CycloneDX export crash when TLP classification is null — the spec-violating `distributionConstraints` field is now omitted.
* Archived SBOM versions no longer trigger notifications.
* Invalid component relation types are now rejected at the GraphQL schema level.
* Fixed vulnerability counts showing a dash when data exists but the scan status is `NOT_STARTED`.
* Fixed SBOM, tools, and check-result mutations failing due to case mismatches — all mutations now use consistent PascalCase naming.
* Fixed product table action selector not rendering correctly.
* GitLab configuration warnings no longer appear outside of organization scope.
* Fixed indefinite query polling that could cause unnecessary API load.
* Fixed SBOM policy metrics mapping with correct default counts and parts handling.
* Fixed action preview rendering for the "view all" organization context.
* Notification user preferences no longer auto-reset when no notification channels exist.
* Fixed token refresh race condition in the API client error link.
* Fixed priority field for bulk Jira ticket creation.
* Hardened frontend email validation to match backend rules and prevent email splitting attacks.

***

### ⚙️ Technical Improvements

* **Sentry → AppSignal Migration** — Full replacement of Sentry with AppSignal across the frontend, including error boundaries, Apollo error link integration, user context tagging, and source map uploads.
* **Vulnerability Query Optimizations** — CTE materialization for UNION queries, window-function-based total counts, combined duplicate finder calls, and precomputed stats via DataLoader cut vulnerability page load times by more than half.
* **DataLoader Batching** — New DataLoader sources for project group → projects and project → SBOM versions eliminate \~400 N+1 queries on the project groups page. Also fixed N+1 on polymorphic connection associations.
* **AppSignal Coverage Expansion** — Added error reporting to 9 GraphQL mutations, 20 background jobs, and all REST controllers. Dead job hooks now surface exhausted Sidekiq retries. Expected authorization errors are filtered from noise.
* **PII Removal** — User email addresses replaced with user IDs in all monitoring tags.
* **Docker Security** — Containers now run as a non-root user and Docker socket volume mounts have been removed.
* **Rate Limit Adjustments** — Webhook and GraphQL per-user rate limits increased to 2,000 requests/minute to accommodate heavier integration workloads.
* **Frontend Performance** — Reduced table re-renders by decoupling hover state from column memoization and minimizing action callback dependencies. Removed over-fetching in several queries. Apollo DevTools disabled in production.
* **CDN Subresource Integrity** — External CDN scripts and stylesheets now include SRI hashes to prevent tampering.
* **Dependency Updates** — Gem updates and Axios upgraded to patch a denial-of-service vulnerability.

***

## v3.8.4

Feb 5th 2026

***

### ✨ Highlights

* **SBOM Parts Archiving** — Archive SBOM parts along with selectable related part versions, giving you more control over your software inventory lifecycle.
* **View Products from Components** — Quickly navigate from any component or package version to see all associated products directly from the SBOM view.
* **Partial Package Name Search** — Find packages faster with partial name matching support across the platform.
* **Policy Violations Quick Access** — New "View Violations" action in the policy actions menu for faster compliance workflows.
* **Major Security Hardening** — Comprehensive security improvements including SQL injection fixes, rate limiting, OAuth hardening, and access control enhancements.

***

### 🆕 New Features

* **SBOM Parts Archiving** — When archiving an SBOM, you can now select and archive related part versions alongside the parent, with clear visibility into which parts are eligible for archiving.
* **View All Products for a Component** — A new action lets you view all products associated with a component directly from the SBOM and package version tables.
* **View Violations from Policy Table** — Quickly access policy violations from the policy actions menu for streamlined compliance review.
* **Partial Package Name Matching** — Package search now supports partial name matching, making it easier to locate packages across your organization.
* **NVD Feed Sync Monitoring** — Automated monitoring detects stale or stuck NVD feed syncs and alerts the team, ensuring vulnerability data stays current.
* **VEX Disposition Timestamp Preservation** — When VEX dispositions are copied during duplicate version processing, original detection dates and patch velocity metrics are now preserved accurately.
* **Executive Summary Improvements** — Enhanced metadata and vulnerability overview section in executive summaries for clearer reporting.
* **Keyboard Shortcuts Update** — The keyboard shortcuts modal now includes additional details to help you navigate the platform more efficiently.

***

### 🐛 Bug Fixes

* Fixed organization list sorting when using certain column orderings.
* Fixed joined date display for users with pending invitations.
* Fixed tab reset and alert behavior when switching between views.
* Fixed CVSS vector links in SBOM vulnerability and PURL lookup tables.
* Fixed parts vulnerability stats navigation not directing to the correct view.
* Fixed environment name display on the "Also Affected" drawer.
* Fixed inactive tabs from rendering and running unnecessary side effects in settings and other views.
* Fixed component health score view not displaying correctly.
* Fixed inconsistent summary title in the Linear issue creation modal.
* Fixed import actions layout in organization environment defaults.
* Fixed tab navigation not reflecting correct counts.
* Fixed breadcrumb navigation not resizing to ideal length.
* Fixed alignment issue in the component insights drawer.
* Fixed Jira ticket creation failing when no reporter value is set.
* Fixed vulnerability sorting when using string-based search.
* Fixed issue tracker field rendering for all issue types.
* Fixed user notification preferences saving incorrect payload.
* Fixed "All Products" listing not returning expected results.
* Fixed error handling when creating or deleting external issue tracker links.
* Fixed package lookups incorrectly handling global vs. organization-scoped packages.
* Fixed AWS SQS message polling logic and moved to scheduled jobs.
* Fixed CPE version comparator producing incorrect match results.
* Fixed duplicate VEX processing jobs running concurrently.
* Fixed NVD feed sync getting stuck due to stale locks and broken job chains.

***

### 🔒 Security Improvements

* Fixed SQL injection vulnerabilities across multiple GraphQL queries and service layers.
* Resolved broken access control issues by scoping all resource lookups to the user's organization.
* Added rate limiting for login, password reset, webhook, and OAuth endpoints to prevent abuse.
* Hardened GitHub OAuth flow with JWT-based token verification and nonce validation.
* Fixed open redirect vulnerability in OAuth redirect URI handling.
* Applied consistent cookie security flags across all authentication flows.
* Upgraded frontend dependencies (jsPDF, react-router) to address known vulnerabilities.

***

### ⚙️ Technical Improvements

* Memoized React context providers and filter handlers to reduce unnecessary re-renders.
* Reduced redundant API calls for parts filter data, improving page load times.
* Optimized Jira sync status check with a dedicated lightweight query.
* Enabled Sentry error reporting for production environments.
* Improved activity column display in the SBOM changelog table.
* Updated component vulnerability table columns with consistent layout.
* Set default field ordering for the global policy table.
* Updated upstream products drawer header to include target vulnerability ID.

***

## v3.8.3

January 29th 2026

***

### Highlights

* **Debian ecosystem support** — Full support for Debian packages, including metadata enrichment, license extraction, and version comparison.
* **Smarter Jira integration** — Jira ticket creation now dynamically adapts to your project's supported fields, with new bi-directional sync across all issue types and test ticket creation.
* **Component vulnerability insights** — New vulnerability metrics and status tracking at the component and package instance level.
* **Performance optimizations** — Reduced data overfetching and optimized queries across vulnerability logs, custom fields, and Jira-related views.

***

### 🆕 New Features

* **Debian package support** — The component library now supports Debian and Ubuntu packages. Metadata including descriptions, licenses (via DEP-5 copyright files), repository URLs, published dates, and version comparison is automatically enriched from Debian sources.
* **Jira supported fields detection** — Jira issue creation now queries your Jira project's create metadata to only render and submit fields that are actually supported, preventing ticket creation failures.
* **Jira test ticket creation** — A new option lets you create a test Jira ticket directly from the configuration screen to validate your integration setup.
* **Jira bi-directional sync for all issue types** — VEX bi-directional sync is now available across all configured Jira issue types, not just Interlynk-specific ones.
* **Jira affected versions** — When creating Jira issues, the affected software version is now automatically included.
* **Component vulnerability metrics** — Components now display vulnerability counts and status breakdowns, available in both the component detail view and the package instances table.
* **Policy condition operator selector** — A new UI selector allows choosing operators when defining policy conditions, along with product group selection.
* **Async product label selector** — Product label selection now uses async search, handling large label lists without performance issues.
* **Automation rule name validation** — Automation rules now enforce unique names to prevent duplicate configurations.
* **Label search** — Labels can now be searched by name in queries and filters.
* **PURL and CPE validators** — New validators for Package URL and CPE identifiers ensure data integrity during ingestion.
* **Improved component information view** — The component detail card and identifiers section have been redesigned with additional metadata and a cleaner layout.

***

### 🐛 Bug Fixes

* Fixed Jira ticket creation failures when reporter, assignee, or parent fields are not available on the Jira create screen.
* Fixed policy results query error caused by incorrect database table references.
* Fixed email delivery failure handling.
* Fixed Debian package metadata updates and PURL decoding issues.
* Fixed vulnerability column display in the package instances table.
* Fixed license status column name in the license table.
* Fixed ticketing delete confirmation showing incorrect product name.
* Fixed product label ordering issue on creation.
* Fixed SBOM download dropdown overflow.
* Fixed tooltip overflow for organization environment default fields.
* Fixed NVD alias ID link in vulnerability expanded view.
* Fixed empty column behavior in archived vulnerabilities and license tables.
* Fixed hover actions incorrectly appearing on archived license rows.
* Fixed breadcrumb and dropdown not updating after product rename.
* Fixed automation rule override logic.
* Removed unused API call from the SBOM compliance tab.

***

### ⚙️ Technical Improvements

* Optimized organization scan processing with additional metadata.
* Reduced overfetching in custom fields queries used for CSV export.
* Added lightweight custom fields query for VEX status views.
* Optimized component vulnerability log queries in the status history drawer.
* Removed unused fields from Jira-related GraphQL queries.
* Optimized license import field states and create parts state handling.
* Refactored date formatting into a reusable `RelativeDate` component.
* Refactored compliance list view with conditional checks.
* Refactored PR vulnerability comment job enqueuing logic.
* Removed redundant and unused props from product tab components.
* Added end-to-end test selectors for automation, product filters, and labels.
* Updated dependency versions for `allure-playwright` and `@react-pdf/renderer`.

***

## v3.8.2

January 22nd 2026

***

### ✨ Highlights

* **📦 Comprehensive Package Details Page** – New full-featured package details page with instance listing, filtering, and version tracking across your organization
* **📊 Enhanced Analytics Product Filter** – Improved analytics experience with async product selection for better performance
* **🔗 External Links Management** – Added ability to manage and delete external links directly from the ticketing tab
* **🎨 Improved Component Insights** – Refreshed layout for component insights providing better visibility into your software components

***

### 🆕 New Features

* **Package Details & Instance Tracking** – View comprehensive details for any package including all instances across your organization with advanced filtering options and version counts
* **Connected Products API** – New APIs to view all products connected with a specific component, enabling better dependency tracking
* **Export Scope Display** – Attribution report exports now display the export scope for clearer context
* **External Links Delete Action** – Delete external links directly from the ticketing tab with a streamlined interface
* **Async Analytics Product Filter** – Enhanced product filtering in analytics with async selection and improved search performance

***

### 🐛 Bug Fixes

* Fixed policy results display for deleted projects
* Resolved TLP classification defaulting to CLEAR instead of empty
* Corrected policy checks in label mutations for update and delete actions
* Fixed authorization checks in custom vulnerability mutations
* Resolved component support field state issues during SBOM checks
* Fixed empty state messaging in package instances table
* Corrected product select behavior in Import Vulnerability Status Wizard
* Fixed import license status product selection
* Resolved relationship creation logic for add component flow
* Fixed custom vulnerability create validation
* Corrected document title during logout flow
* Fixed end-of-support date handling in component creation
* Resolved async product filter making unnecessary API calls
* Fixed TLP classification indicator display in Customer View
* Corrected Adjusted CVSS Vector preview in Customer View
* Fixed cryptography date sequence validation
* Resolved sidebar z-index conflicts with navbar
* Fixed purl/cpe validation before custom vulnerability creation
* Prevented downloading empty support level CSV files

***

### ⚙️ Technical Improvements

* **Performance Optimizations** – Debounced async product filter search and optimized changelog operations for faster load times
* **Component Stats Optimization** – Improved memoization and reduced array recreation for better performance
* **Refactored Vulnerability Import** – Cleaner status field handling with improved error states
* **Unified Error View** – Consistent error display across all pages
* **System Log Loading** – Enhanced loading experience for system logs
* **Security Updates** – Updated lodash dependencies to address security vulnerabilities
* **Code Cleanup** – Removed unused loaders and utility functions
* **State Persistence** – Preserved step 1 state when navigating back in vulnerability import wizard
* **Date Validation** – Added relational validation for custom vulnerability date fields
* **SBOM Download UX** – Locked checkbox state during submission to prevent accidental changes
* **Role-Based Restrictions** – Restricted organization environment default updates for Viewer and Operator roles; restricted operators from package version override
* **Automation Rules** – Added ability to overwrite existing automation rules on copy; restricted field updates for system-level rules

***

## v3.8.1

January 15th 2026

***

### ✨ Highlights

* **Organization Environment Settings** — Configure default environment fields at the organization level and apply them across all projects
* **Enhanced Policy Custom Fields** — Full support for custom fields in policy rules with proper validation and field type metadata
* **Improved Jira Integration** — Enhanced auto ticket creation with severity details, CVSS scores, and bulk operations
* **Redesigned Sidebar Navigation** — New hover-based sidebar expansion with smooth transitions for a cleaner interface
* **Comprehensive Timezone Handling** — Fixed date handling across the platform to prevent timezone drift issues

***

### 🆕 New Features

#### Organization Settings

* **Default Environment Fields** — Configure environment field defaults at the organization level with options to apply settings to all projects or only future projects
* **Organization Project Setting Defaults** — Enhanced settings management with clear tracking of applied actions for all and future projects

#### Policy Management

* **Custom Field Support in Policies** — Create policy rules using custom fields with automatic field type detection (TEXT vs RANGE) for appropriate input validation
* **Policy Subject Operator Mapping** — Exposed custom field metadata to distinguish between static subjects and custom fields

#### Jira Integration Enhancements

* **Enhanced Ticket Descriptions** — Auto-created Jira tickets now include severity level and CVSS score information
* **Bulk Delete for Issue Tracker Links** — New mutation to bulk delete external issue tracker links with success status response
* **Optimized Bulk Operations** — Improved batch processing to comply with Jira API limits

#### Navigation & Discovery

* **KBar Navigation for Environment Rules** — Quick keyboard-based navigation to environment rules
* **Category-Specific Admin Navigation** — Updated admin navbar with category-specific default tabs for easier navigation

#### User Experience

* **Hover-Based Sidebar** — New sidebar that expands on hover with smooth transitions for a cleaner workspace
* **Floating Actions in Request Table** — Improved request table with floating action buttons
* **Enhanced Loading States** — Added loading indicators for dashboard activities, integration cards, and compliance cards

#### Role & Permission Updates

* **View Support Level** — Added view support level to all existing roles
* **Viewer Role Enhancements** — Viewers can now access SBOM relationships and component relationship actions

***

### 🐛 Bug Fixes

* **Timezone Handling** — Fixed date-only expiry calculations and UTC date handling to prevent timezone drift across the platform
* **SBOM Vulnerability Permissions** — Corrected edit permissions for SBOM vulnerabilities and custom vulnerabilities
* **Null CVSS Score** — Fixed bug caused by null effectiveCvssScore values
* **Sidebar Overflow** — Resolved sidebar overflow issues during logout and general navigation
* **Version Actions** — Hidden version action menu in customer view for cleaner interface
* **Primary Component Actions** — Hidden SBOM edit primary component action when no primary component exists
* **Assessment Display Logic** — Fixed assessment expiry date display with proper timezone handling
* **Future Date Validation** — Prevented selection of future dates in custom vulnerability creation
* **Automation Rules** — Fixed duplicate automation rule copies by disabling existing rules in menu
* **KBar Z-Index** — Corrected z-index to prevent sidebar highlight conflicts
* **Admin Page Layout** — Fixed height issues in admin page layout
* **Support Status Preview** — Fixed support status actions preview display
* **VEX Field Restrictions** — Enforced proper VEX field restrictions for viewer role
* **Request Modal Validation** — Implemented inline email validation in request modal
* **Request Resend UX** — Added confirmation dialog and status validation for request resend

***

### 🔧 Technical Improvements

* **Sidekiq Job Priority** — Updated job queue priority for bulk auto ticket creation with better project prioritization based on policy inclusions
* **SBOM Signing Workflow** — Added SBOM signing workflow for development environments
* **Vulnerability Scan Notifications** — Enhanced notifications with scan metadata and improved link formatting
* **ActiveStorage Uploads** — Added organization-scoped key generation for secure file uploads
* **GraphQL Organization** — Centralized GraphQL query and mutation definitions for better maintainability
* **Component Support Cleanup** — Removed duplicate component support files
* **Token Modal Refactor** — Improved TokenModal component readability
* **Support Status Drawer** — Merged view/edit states for streamlined component
* **Loading State Optimization** — Removed redundant loading states for enterprise trial mutation
* **Playwright Test Maintenance** — Cleaned up unused tests and fixed tests affected by sidebar changes

***

## v3.8.0

January 9th 2026

***

### ✨ Highlights

* **PDF Export for Executive Summary** - Generate professional PDF reports of your executive summary for easy sharing and documentation
* **Enhanced Policy Violation Metrics** - New organization-level policy violation metrics with improved dashboard visualizations
* **Improved Component Navigation** - Tab-based navigation in component tree view for better exploration of component hierarchies
* **Streamlined Action Menus** - New hover-enabled action menus across SBOM and vulnerability tables for a cleaner, less cluttered interface
* **Free Tier Access Controls** - Improved feature access management for organizations on the free tier

***

### 🆕 New Features

* **PDF Export for Executive Summary** - Export your executive summary as a professionally formatted PDF document directly from the dashboard
* **Organization-Level Policy Violation Metrics** - New aggregated policy violation metrics at the organization level, powering enhanced policy charts on your dashboard
* **Clickable Status Badges** - Status badges now support click interactions with automatic filter reset for streamlined navigation
* **Tab-Based Component Tree Navigation** - New tab interface in the component tree view for improved navigation between different component aspects
* **Enhanced SBOM & Vulnerability Tables** - Dropdown action menus added to SBOM and vulnerability tables for quick access to common operations
* **Component & License Table Actions** - New dropdown actions in component and license tables for easier management
* **Organization Table Updates** - New update action available directly from the organization table
* **Expandable Policy Descriptions** - Policy descriptions now support expandable text for better readability of longer content
* **Improved SBOM Actions** - New "View Relationship" option added to the SBOM actions menu
* **Product Labels Display** - Product details page now shows assigned labels for better visibility
* **Active Notification Channel Detection** - Global hook for checking active notification channels across the platform

***

### 🐛 Bug Fixes

* Fixed Jira vulnerability management update permissions
* Resolved CVSS 4.0 metric mapping issues for accurate scoring
* Fixed custom vulnerability updates to properly allow field modifications while protecting PURL/CPE data
* Standardized date handling across all components for consistent timezone behavior
* Improved error handling for email connection configuration
* Enhanced SBOM download modal with consistent preview functionality
* Fixed CSV export modal behavior in SBOM vulnerability views
* Resolved component filter triggering unnecessary API calls
* Fixed license filter data fetching to only load on menu interaction
* Corrected SBOM changelog table activity column rendering
* Fixed stale CPE, PURL, and supplier data in component drawers
* Resolved Jira workType and sync reset logic issues
* Fixed compliance details navigation from SBOM download modal
* Corrected version navigation from latest import table
* Fixed versions list loading when navigating from Latest Imports to product page

***

### ⚙️ Technical Improvements

* **Multi-Architecture Docker Support** - Dockerfile refactored for full multi-architecture compatibility (amd64/arm64)
* **Performance Optimizations** - Memoized action handlers across Support, Versions, Components, and Vulnerability tables for improved rendering performance
* **Query Caching** - Implemented query caching for Download Modal to reduce redundant network requests
* **Policy Modal Performance** - Optimized Policy Modal rendering and fixed state management issues
* **Code Cleanup** - Removed unused imports and cleaned up deprecated files
* **Security Updates** - Updated dompurify and lodash-es dependencies to latest secure versions
* **Refactored Action Menus** - Standardized hover-enabled ActionMenu component for consistent UI behavior
* **Enhanced Role-Based Access** - Improved viewer role restrictions for licenses, authors, TLP, and tools editing
* **Operator Access Controls** - Restricted operator access to source control integrations (Bitbucket, GitHub, GitLab)

***

## v3.7.9

December 26th 2025

***

### 🌟 Highlights

* **CVSS Score Editing** - Edit CVSS scores directly within the platform, now available for all organizations
* **Row-Based Floating Actions** - New intuitive UI pattern with floating action buttons across table views for improved user experience
* **Enhanced Modal Context** - Improved modal dialogs now display relevant context such as target names, user details, and license information
* **Executive Summary Improvements** - Optimized performance and improved accuracy in executive summary data processing

### ✨ New Features

* **CVSS Score Editing**: Edit CVSS scores for vulnerabilities with conditional preview action and integrated mutation support
* **Environment Selection for Policies**: Added environment selection capability for policy project groups
* **CVE ID Validation**: Implemented CVE ID validation in custom vulnerability modal to ensure data accuracy
* **Event Type in SBOM Changelog**: Display event type in SBOM changelog table for better context and traceability
* **Keyboard Navigation**: Enter-key submission support for vulnerability link creation flow
* **Security Token Confirmation**: Added confirmation modal when deleting security tokens
* **Row-Based Floating Actions**: Implemented across manufacturers, users, roles, security tokens, and other table views
* **Token Table Enhancements**: Added modal title and refresh action to token management table
* **Role Table Updates**: Added system check and refresh action for improved role management
* **Uniqueness Validation**: Added validation for event type and target branch pattern combinations in project environment rules

### 🐛 Bug Fixes

* Fixed Jira VEX status field changes not being properly synchronized
* Fixed connection deletion for notification channels
* Fixed unintended row expansion behavior in global license table
* Restored component name column in license table
* Fixed custom select placeholder styling for consistent appearance
* Fixed security token deletion by passing API key ID correctly
* Enhanced component checksum validation with improved error handling
* Fixed executive summary data processing accuracy issues
* Fixed TLP classification field options for consistent behavior
* Fixed CPE select placeholder rendering and styling
* Replaced inconsistent select components with LynkSelect in global policy columns
* Optimized vulnerability scanning to only schedule scans for active project groups
* Fixed AppSignal monitoring issue
* Eliminated duplicate version text in SBOM info title

### 🔧 Improvements

* Improved PURL lookup description for better context
* Enhanced automation modals with target rule name display
* Updated global license modals to include target license context
* Improved global support modals with target product details
* Enhanced user action modals with relevant user context
* Improved identifiers column in global support table
* Added error handling for SBOM parts creation
* Optimized component insights query by removing unused fields
* Optimized executive summary drawer component structure and performance
* Improved UI consistency and SBOM description user experience
* Updated vulnerability finder to use vuln\_lookup method for improved accuracy
* Updated component relation mutation with improved authorization logic

***

## v3.7.8

December 18th 2025

***

### 🌟 Highlights

* **AWS Marketplace Integration**: Full support for contract-based pricing and SQS polling capabilities, enabling seamless AWS Marketplace operations
* **Enhanced SBOM Management**: Improved SBOM import functionality with better error handling and policy exclusion management for active SBOMs
* **Improved UI/UX**: Significant improvements to navigation, filtering, and data visualization across the platform
* **Performance Optimizations**: Reduced bundle size through optimized imports and improved data handling across components

### ✨ New Features

#### AWS Marketplace & Integration

* Added comprehensive AWS Marketplace API support with contract-based pricing capabilities
* Implemented SQS polling support for real-time event processing
* Integrated AWS Marketplace connections into the platform UI

#### Enhanced Filtering & Search

* Added EPSS (Exploit Prediction Scoring System) filter with custom range UI and visual feedback
* Converted SBOM vulnerability import fields to searchable inputs for better accessibility
* Implemented persistent filter state across product detail tabs

#### Improved Notifications & Visibility

* Enhanced notification check indicator for better visibility
* Added conditional preview for CVSS (Common Vulnerability Scoring System) actions
* Implemented auto-disable for notifications when mediums are deleted

#### UI/UX Enhancements

* Added ExpandableText component for long descriptions in checks and vulnerability tables
* Standardized large drawer placement to bottom for improved user experience
* Added delete action capability for SBOM support status
* Improved product label selection popup with enhanced UX

### 🐛 Bug Fixes

#### SBOM & Component Management

* Fixed SBOM import functionality
* Resolved SBOM component stats data handling issues preventing undefined values
* Fixed SBOM components license filter issues in customer view
* Corrected SBOM changelog date column NaN issues
* Fixed component log edit job execution

#### Navigation & Routing

* Fixed breadcrumbs navigation issues
* Resolved product details page navigation from product name
* Fixed versions list display when switching environments via breadcrumb
* Added missing Ticketing route to KBar navigation
* Fixed environment switch issues from product details page

#### Data Handling & Processing

* Fixed JSON file upload functionality
* Improved JSON error handling
* Resolved infinite loop issues
* Fixed AppSignal integration issues
* Fixed support status CSV export verification

#### Jira & VEX Integration

* Handled resolution\_date properly based on vex\_status in Jira sync
* Set default connection mapping to JIRA

#### Policy & Permissions

* Refactored policy exclusion deletion to use active SBOMs
* Added data migration for support level permissions
* Fixed ComponentSupportOverride mutations

#### UI Components & Display

* Fixed notification issues for archived/deleted products
* Resolved incorrect sorting fields in product changelog table
* Fixed support status bulk update mixed selection issues
* Prevented PDF overflow by optimizing font size and spacing
* Resolved PDF version name overflow and alignment issues
* Replaced array index keys with stable identifiers for better React performance

#### Validation & Security

* Fixed AWS account\_id access issues during organization creation
* Tightened automation rule import validation
* Disabled add label button for whitespace-only names
* Added clear functionality and tooltip improvements to product settings

#### Performance

* Optimized lodash imports to reduce bundle size
* Refactored product tabs component for better performance
* Fixed various test specifications

***

## v3.7.7

December 11th 2025

***

### ✨ Highlights

* **Jira VEX Integration Enhancement** - Push VEX action statements directly to Jira issues for streamlined vulnerability management workflows
* **Jira Epic Support** - Create and manage Jira Epics from within Interlynk for better issue organization
* **Assigned Age Policy** - New policy condition to track and enforce actions based on vulnerability assignment duration
* **CVSS Post-Remediation Reporting \[Demo Only]** - New metrics and analysis for CVSS vectors to track remediation progress
* **Redesigned Dashboard Filters** - New grid layout for filter menu eliminates scrolling and improves navigation
* **Enhanced Command Palette** - Improved accessibility and UX for keyboard-driven workflows

***

### 🆕 New Features

* **VEX Action Statement in Jira** - Include VEX action statements when creating Jira issues, providing additional context for vulnerability triage and remediation
* **Jira Epic Support** - Select Epic as an issue type in Jira defaults for better project organization
* **Multiple Jira Projects** - Query and work with multiple Jira projects simultaneously
* **Jira VEX Push** - Push VEX information directly to Jira for centralized vulnerability tracking
* **Assigned Age Policy Condition** - Create policies based on how long vulnerabilities have been assigned
* **CVSS Vector Metrics** - New metrics for tracking CVSS vectors with post-remediation analysis capabilities
* **Clickable Product Labels** - Click on product labels to quickly filter the products table
* **Dashboard Filter Grid Layout** - Redesigned filter menu with an organized grid layout for easier access
* **Theme Preference Persistence** - Theme selection now persists and syncs across the command palette and navigation menu
* **Label Name Character Limit** - Visual feedback showing character limits when creating labels
* **Clear All Label Filter** - New option to easily clear all label filters with improved UX

***

### 🐛 Bug Fixes

* Fixed environment switch logic causing tab mismatch when navigating between environments
* Resolved VEX status policy violations not correctly applying to parent dispositions
* Fixed Assigned Age condition value input in policy modal
* Corrected theme synchronization between command palette and navbar menu
* Fixed parts breadcrumbs preview display issues
* Resolved Progress Overview version list not updating after SBOM upload
* Fixed product table column alignment for environment and updated fields
* Improved ShareLynk drawer error messaging and user clarity
* Fixed partsOf version navigation
* Corrected vulnerability display ID rendering
* Fixed dark mode support for checkmark components
* Resolved glitch in environment switching from Product Details page

***

### ⚙️ Technical Improvements

* Refactored OAuth integration services for improved maintainability
* Implemented pagination for Jira API calls to handle large datasets efficiently
* Optimized API fetch logic for Jira and Linear settings pages
* Streamlined first page load query for package viewer, improving performance
* Refactored SBOM stat cards and compliance health score cards for consistency
* Added loading states to delete buttons for labels, component links, vulnerability links, and manufacturers
* Enhanced command palette with improved accessibility features
* Improved theme switcher with visual feedback and alignment fixes
* Enhanced ShareLynk drawer date selection experience
* Updated integrated products table with edit functionality improvements
* Ordered SBOM alternative data by import time for better organization

***

## v3.7.5

December 04th 2025

***

### ✨ Highlights

* **PURL Vulnerability Lookup** - New capability to search and retrieve vulnerabilities for any Package URL directly
* **Enhanced Jira Integration** - Visual indicators for integrated products, VEX fields support in issue creation, and improved error handling
* **Performance Optimizations** - Significant speed improvements across SBOM details, compliance, and label filtering with query caching
* **Improved Form Validation** - Standardized validation patterns preventing duplicate entries and invalid submissions

***

### 🆕 New Features

* **PURL Vulnerability Lookup** - Search vulnerabilities by Package URL (PURL) to quickly assess package security risks
* **Jira VEX Fields Support** - Add VEX (Vulnerability Exploitability eXchange) fields when creating Jira issues for better vulnerability context
* **Integrated Products Overview in Jira** - New overview displaying products connected to Jira workflows for better visibility
* **Visual Indicator for Jira Integrated Products** - Easily identify which products are connected to Jira at a glance
* **CSS Color Name Support for Labels** - Create labels using standard CSS color names in addition to hex codes
* **Context-Aware External Issue Tracker Links** - Filter and display relevant external issue tracker links based on context
* **License Filter Menu Enhancement** - Updated license filter with additional instructions for easier navigation
* **Cryptography and User Table Selectors** - Added selectors for improved accessibility in cryptography and user tables

***

### 🐛 Bug Fixes

* Fixed SBOM part delete functionality
* Resolved missing Jira workflow status issues
* Fixed GitHub app token configuration for production environments
* Corrected environment breadcrumb visibility on product details page
* Fixed global vulnerability navigation breadcrumb display
* Fixed navbar order inconsistency between direct and part navigation
* Resolved vulnerability CSV export "ID" column formatting
* Fixed global vulnerability view CSV export ID column
* Fixed pagination display logic for exact page size matches
* Corrected license expression check logic
* Fixed author modal title display
* Prevented UI crash on Jira vulnerability provisioning failure
* Fixed display of actual Jira provisioning errors with clearer messaging
* Fixed expandable text link from breaking across lines
* Standardized terminology from "Lifestage/Lifecycle" to "Life stage/Life cycle"
* Fixed redundant organization switch when selecting current org
* Fixed dynamic title flicker on product environment reload
* Corrected Jira config modal validation to match Slack/Teams pattern

***

### ⚙️ Technical Improvements

* **Performance**: Implemented query caching for SBOM detail page eliminating loading delays
* **Performance**: Added query caching for compliance page for faster load times
* **Performance**: Cached queries for LabelFilter and LabelSelect components
* **Performance**: Optimized product details header with query caching
* **Performance**: Optimized organization vulnerability scan operations
* **License Handling**: Normalized license expressions to comply with SPDX specification
* **Notification Messages**: Improved notification message formatting
* **Form Validation**: Standardized form validation by disabling buttons for empty required fields
* **Duplicate Prevention**: Added validation to prevent saving policies, support overrides, automation rules, and contacts with duplicate entries
* **Error Handling**: Improved error handling in Jira issue creation service with corresponding tests
* **UX Improvements**: Enhanced SBOM upload modal UX and error handling
* **State Preservation**: Preserved field states across navigation in tools page, license import drawer, product labels, and import fields selection
* **Refactoring**: Centralized validation utilities and error messages for consistency
* **Refactoring**: Refactored ticket description rendering using new TicketTextRenderer class
* **Code Cleanup**: Removed unused queries and mutations from codebase
* **SBOM License Table**: Enhanced SBOM license table interactions
* **Alternative SBOM Table**: Updated with new changes and consistent columns

***

<br>

## v3.7.3

November 26th 2025

***

### ✨ Highlights

* **GitHub App Token Integration** - Enhanced runner now uses GitHub App tokens for improved security and reliability
* **Internal Components Editing** - Full edit functionality for internal components is now available
* **PR Comments for Non-Imported Projects** - Expanded support for pull request comments across all project types
* **Auto-Save Notification Preferences** - Personal notification settings now save automatically for a smoother experience
* **ShareLynk Component Enhancements** - Part SBOM components are now included in ShareLynk queries

***

### 🆕 New Features

* **GitHub App Token Migration** - Runner has been migrated to use GitHub App tokens for better authentication and security
* **PR Comments for Non-Imported Projects** - Pull request commenting is now supported for projects that haven't been imported
* **Internal Components Editing** - Users can now edit internal components directly from the interface
* **Manual Issue Tracker Link Editing** - Added support for manually editing issue tracker links
* **Auto-Save Notifications** - Personal notification preferences now auto-save when clicking checkboxes
* **Environment Breadcrumbs** - Parts navigation now includes environment breadcrumbs for better context
* **External Link Timestamps** - Vulnerability external links now display the creation timestamp
* **CVE Export Enhancement** - Missing attributes are now included in CVE export data
* **ShareLynk Component Query** - Part SBOM components are now included in ShareLynk component queries
* **Super Admin Role Editing** - Super admins can now edit their own role assignments

***

### 🐛 Bug Fixes

* Fixed scheduled job notifications not triggering correctly
* Resolved NVD sync issues affecting vulnerability data
* Fixed vulnerability reports generation issues
* Corrected notification behavior when "All" checkbox is unchecked
* Fixed license details view logic for accurate display
* Resolved label options not updating correctly after deleting labels
* Fixed "null" appearing in author delete confirmation modal
* Corrected product name overflow in SBOM PDF header ensuring version visibility
* Fixed Add Link button remaining enabled when no provider is selected
* Resolved modal mode detection for single-row ticket creation actions
* Fixed layout issues caused by column widths in policy table
* Corrected license filter data not updating after changes
* Fixed entries with "+" in license names showing no data
* Resolved version field options in analytics page
* Fixed SBOM build function issues
* Corrected CSV export "Created On" column showing NA values
* Fixed Test Expressions icon visibility and regex matching issues
* Resolved field validation issues for vulnerability links
* Fixed author updates not saving correctly
* Resolved status column cropping in vulnerability table

***

### ⚙️ Technical Improvements

* Added logging to library clients for better debugging and monitoring
* Removed unused fields from ticket description formatter
* Optimized vulnerability filters query by removing unused fields
* Optimized author modal by reducing redundant API calls
* Refactored PolicyModal into smaller, maintainable components
* Centralized duplicate row error messages with improved grammar
* Refactored primary/internal checks into reusable components
* Unified duplicate-row validation into shared helper
* Removed deprecated GitHub import demo files and cleaned up unused code
* Improved column visibility on product details page
* Enhanced policy modal project groups selection UI/UX
* Improved Jira project field options preview
* Enhanced dynamic titles with GitHub-style dot separators
* Improved bulk actions UX for vulnerability ticket creation
* Improved error message for assessment expiry field
* Improved product settings tab layout
* Improved edit label action in products table
* Improved UX of error message preview for custom vulnerabilities
* Improved layout for organization health fields
* Added default checks to SBOM duplicate modal
* Added error handling to multiple mutation promise chains
* Improved permission modification alert preview
* Updated policy details section with consistent preview
* Added selectors for product label fields

***

## v3.7.0

November 19th 2025

***

### ✨ Highlights

* **Automated SBOM Archiving** - SBOMs can now be automatically archived based on project settings, streamlining lifecycle management
* **Enhanced Jira Integration** - Expanded Jira synchronization with support for part SBOMs, advanced VEX fields, and parent SBOM tracking for better traceability
* **Advanced SBOM Duplication** - New options to include patches and support levels when duplicating SBOMs, giving you more control over your SBOM workflows
* **Pull Request Comments** - Enable automatic PR comments to provide inline feedback and insights directly in your development workflow
* **Security Hardening** - Critical security improvements including IDOR vulnerability fixes and sensitive data protection enhancements

### 🎯 New Features

* **Auto-archive SBOMs** - Configure automatic archiving of SBOMs based on project settings toggle, reducing manual maintenance overhead
* **External Issue Tracker Integration** - New mutation and API support for creating external issue tracker links, expanding integration possibilities
* **Jira Sync for Part SBOMs** - Synchronize part-level SBOMs with Jira for granular component tracking and management
* **Advanced VEX Fields in Jira** - Create Jira issues with comprehensive VEX (Vulnerability Exploitability eXchange) field support for richer vulnerability context
* **Parent SBOM ID Tracking** - Pass parent SBOM identifiers when creating Jira tickets for part vulnerabilities, maintaining clear hierarchical relationships
* **SBOM Duplication Options** - Enhanced duplication feature with selectable options for including patches and support levels
* **Confirmation Modal for Auto-archive** - User-friendly confirmation dialog when enabling auto-archive to prevent accidental configuration changes
* **PR Comments Feature** - Automated pull request commenting capability for seamless CI/CD integration
* **Organization Scope Management** - Improved organization-level scoping for better multi-tenancy support

### 🐛 Bug Fixes

* **IDOR Security Vulnerabilities** - Fixed insecure direct object reference vulnerabilities to prevent unauthorized access
* **Organization Data in LocalStorage** - Removed sensitive organization data from browser localStorage to enhance data security
* **Support Level Permissions** - Corrected view support level permissions for custom roles
* **Latest Version Resolution** - Fixed issues with resolving latest ecosystem and package versions
* **SBOM Duplication Data Loss** - Resolved missing data issues during SBOM duplication operations
* **Jira Integration Crashes** - Stabilized Jira integration to prevent unexpected crashes
* **Import Status Tracking** - Corrected import status reporting for better visibility
* **Vulnerability Logging** - Fixed vulnerability log generation and error reporting
* **Organization Scopes** - Resolved organization scope management issues
* **Package Resolver Crashes** - Fixed crashes in package version resolver
* **GitHub Actions Integration** - Corrected GitHub Actions workflow issues
* **Organization Update Function** - Fixed organization update functionality
* **Internal Component Checkbox State** - Corrected checkbox state initialization for internal components
* **Global Theme Issues** - Resolved undefined styling in global theme configuration
* **Product Table Label Updates** - Fixed state management when updating labels in product table
* **Parts Tooltip Display** - Corrected tooltip rendering in SBOM license table customer view
* **Row Hover Styling** - Fixed style overlap between row hover effects and tag styling
* **Linear Field Dropdown** - Corrected dropdown placement for linear custom fields
* **Custom License Field Defaults** - Fixed default value handling for custom license fields
* **Vulnerability ID Display** - Corrected to use display ID instead of internal vulnerability ID in vulnerability cards

### 🔧 Technical Improvements

* **Enhanced Error Logging** - Improved job context logging in component vulnerability processing for better debugging
* **Job Logger Concern** - Added centralized job logging module for consistent log management
* **ShareLynk Authorization Module** - Implemented dedicated authorization handling for ShareLynk requests
* **Database Formatting Optimization** - Improved JSON formatting for aggregate values to ensure clean parsing
* **Modal Consistency** - Enhanced modal dialogs with trimmed whitespace and consistent layouts
* **Version Table Navigation** - Disabled expand-on-click for version table rows to improve user experience
* **Label Selection UI** - Improved label selection interface in product tables
* **Custom Select Component** - Enhanced select component with unified single-value configuration
* **Production Source Maps** - Disabled source maps in production builds for improved performance and security
* **Concluded License Modal** - Updated modal layout for better consistency
* **System Logs Preview** - Enhanced preview functionality for system logs
* **Selectors and Accessibility** - Added data selectors for manufacturer tables, vulnerability fields, and SBOM components to improve testability
* **Version Expand Actions** - Updated version expansion behavior for better usability
* **Parts Navigation** - Streamlined navigation between SBOM parts
* **Dependency Updates** - Updated js-yaml dependency to latest version for security and stability
* **Build Configuration** - Standardized build configuration with improved environment variable handling and removed error masking

***

## v3.6.9

November 13th 2025

***

### 📋 Highlights

***

This release brings significant enhancements to the Interlynk Platform with improved GitHub integration, enhanced compliance capabilities, and a redesigned import experience. Key highlights include:

* **🔗 GitHub App Integration** - Seamlessly connect your GitHub repositories through our new GitHub App and OAuth integration
* **🏥 FDA OTS Compliance \[Alpha]** - New compliance feature to help organizations meet FDA Off-The-Shelf Software requirements
* **🎨 Multi-Step Product Import Wizard** - Completely redesigned import experience with provider-specific flows and GitHub repository support
* **👥 Enhanced User Roles** - New operator and viewer user roles for better access control
* **🔐 Security Improvements** - Removed hard-coded credentials and upgraded GitHub Actions for enhanced security

### ✨ New Features

#### Authentication & Integration

* **GitHub OAuth Integration** - Native GitHub authentication support for seamless repository access (#8053)
* **GitHub App Integration** - Full GitHub App support for improved repository management (#2695)
* **GitHub Repository Import** - Import products directly from GitHub repositories in the Product Import Wizard (#8171)

#### Compliance & Security

* **FDA OTS Compliance Feature** **\[Alpha]**- Comprehensive compliance tracking for FDA Off-The-Shelf Software requirements (#8098)
* **Enhanced Jira VEX Integration** - Support for new VEX fields in Jira integration (#2823)

#### User Management

* **Operator and Viewer Roles** - New user roles for granular access control (#2813)

#### Policy & Notifications

* **Policy Scan Execution** - Automated policy scanning in vulnerability update service (#2820)
* **Manual Scan Notifications** - Enable vulnerability notifications for manual scans (#2830)
* **Enhanced Notification Preferences** - Improved notification response structure (#2819)

#### Data Management

* **License Filtering** - New exclude\_licenses filter for components and licenses pages (#2809, #8147)
* **Component Insights Navigation** - Navigate to component insights directly from support status table (#8144)
* **License Details View** - View license details directly in component table (#8168)
* **GitHub Repository Pagination** - Pagination support for GitHub API repositories (#2829)

#### User Experience

* **Multi-Step Import Wizard** - New provider-specific import flows with improved UX (#8055)
* **Dynamic Page Titles** - Context-aware page titles for product, version, and tab views (#8157)
* **Auto-Focus Input Fields** - Automatically focus primary input fields for faster data entry (#8170, #8158)
* **Conditional Previews** - Preview changes for parts filter and license deletions (#8180, #8166)

### 🔧 Improvements & Enhancements

#### Component & Vulnerability Management

* **Organization-Specific Component Scoring** - Component scoring now utilizes organization-specific weights and thresholds (#2811)
* **Improved Vulnerability Comparison** - Use top\_n\_latest\_sboms method for better vulnerability comparison (#2832)
* **Enhanced Vulnerability Details** - Consistent styling and improved VEX details popover (#8187, #8145)

#### UI/UX Enhancements

* **Import Wizard UI Updates** - Improved layout and styling for product import wizard (#8189)
* **Responsive Compliance Cards** - Optimized connections and compliance card layout for responsive screens (#8169)
* **Bitbucket & GitLab Imports** - Enhanced project imports for Bitbucket and GitLab (#8154)

#### Code Quality & Refactoring

* **Notification Code Refactor** - Streamlined notification codebase (#2812)
* **Bitbucket Integration Refactor** - Removed app password support in favor of OAuth (#2802)
* **Executive Summary Refactor** - Removed repetitive code in executive summary drawer (#8153)
* **JIRA Settings Cleanup** - Removed deprecated Jira-related fields and methods (#2810, #8148, #8132)

#### Testing & Infrastructure

* **Version Sorting Specs** - Added comprehensive specs for version sorting (#2833)
* **Test Stability** - Resolved flaky Playwright tests and runner inconsistencies (#8190, #8194)

### 🐛 Bug Fixes

#### Import & Integration

* Fixed single provider import wizard flow (#8192)
* Fixed import product wizard flickering with single provider configuration (#8181)
* Fixed Nuget package handling (#2808)

#### Vulnerability Management

* Added error handling for vulnerability diff notifications (#2836)
* Fixed vulnerability status update with fixed version (#8179)
* Fixed Support Status Analysis re-run crashes in UI (#8177)
* Fixed null severity and score values in vulnerability export (#8172)
* Fixed target vulnerability ID preview in affected products drawer (#8156)

#### UI & Display

* Resolved overflow issue in product label list (#8191)
* Fixed field focus highlight inside tab view (#8155)
* Fixed styling issue in product progress drawer (#8152)
* Fixed missing color key error in executive summary drawer (#8150)
* Removed vulnerability status popover from customer view (#8186)

#### Data & Queries

* Fixed pagination issue in notification preferences (#8173)
* Fixed project settings update query (#8164)
* Ensured EOS dates store and display correctly in UTC (#8149)
* Added conditional rendering for expander in version table (#8185)
* Fixed general issue #2569 (#2840)

### 🔐 Security Enhancements

#### Credentials & Secrets Management

* Removed hard-coded GitHub token and PostgreSQL credentials from environment (#2835)
* Removed hard-coded credentials from self-hosted runner configuration (#8193)
* Aligned self-hosted runner configuration across workflows (#8193)

#### Infrastructure & Dependencies

* Updated GitHub Actions versions to v4 for improved security and performance (#2834)
* Updated deploy\_release.yml to resolve critical issues and improve workflow stability (#2831)
* Setup GitHub app config for staging and production environments (#2838)

***

## v3.6.8

November 6th 2025

***

### 📋 Highlights

Version 3.6.8 brings significant improvements to the Interlynk Platform with enhanced component relationship visualization, TLP classification support for exports, and improved import wizard capabilities. This release includes 52 commits focused on user experience enhancements, accessibility improvements, and important bug fixes.

***

### ✨ New Features

#### Component Management

* **Enhanced Component Hierarchy View** 🌳 - Improved visualization of component relationships with better tree view navigation
* **Component Relationship Tree Enhancements** - Added `dependency_of_count` field to SBOM component type for better dependency tracking
* **Flexible Component Matching** - Import wizard now supports name-based matching for components, making imports more flexible and accurate

#### Security & Compliance

* **TLP Classification Support** 🔒 - Added Traffic Light Protocol (TLP) marking options across multiple export formats:
  * TLP Classification Banner for Attribution HTML exports
  * User-controlled TLP marking for Excel and PDF SBOM exports
  * User-controlled TLP marking for Attribution PDF exports
* **Custom License Management** - Full support for deleting custom licenses with confirmation modals
* **Concluded License Deletion** - Added ability to delete concluded license values from License tab with confirmation

#### Integration Improvements

* **GitLab Integration** 🦊 - Added pagination support for GitLab projects import, enabling better handling of large project lists
* **Jira Integration** - Added Interlynk SBOM Link field in Jira ticket creation for better traceability
* **Import VEX Status** - Added search feature in Import VEX Status wizard for easier navigation

#### Notification System

* **Parent Notifications** 🔔 - Refactored notification handling to support parent notifications, improving notification hierarchy and management

#### Export & Reporting

* **Status Support CSV Export** - Improved CSV export functionality with better data handling

***

### 🐛 Bug Fixes

#### UI/UX Fixes

* **Vulnerability Display** - Fixed vulnerability ID preview and links display issues
* **Project Notifications**
  * Fixed issue where existing categories weren't preserved when editing project notification preferences
  * Fixed refresh button not working on project-specific notification preferences table
* **Dark Mode** - Adjusted dark mode colors for SBOM page keyboard shortcuts
* **License Filtering** - Fixed license exclude filter showing duplicate options in ShareLynk
* **Product Labels** - Fixed product label filter behavior
* **Import Wizard** - Improved layout and spacing in import status wizard parts mapping

#### Policy & Settings

* **Policy Management** - Fixed policies edit functionality bug after conditions modification
* **Vulnerability Alerts** - Resolved incorrect alert behavior for vulnerability scan settings
* **Compliance Settings** - Enabled search functionality for compliance settings fields

#### Data Accuracy

* **Status Support Export** - Fixed "N/A" being shown incorrectly for components in Status Support CSV export
* **Vulnerability Links** - Fixed Jira ticket links for vulnerabilities sourced via parts
* **SBOM Processing** - Fixed CycloneDX authors detection in SBOM Zen

***

### 🎨 UI Improvements

#### Accessibility

* **Accessibility Enhancements** ♿ - Removed multiple accessibility errors across the platform
* **Org Notifications** - Added accessibility improvements to organization notification checks

#### Consistency & Styling

* **Custom Select Fields** - Updated custom select fields with consistent styling across the platform
* **Vulnerability ID Column** - Updated with reusable component for better consistency
* **TLP Classification Fields** - Improved with required selectors and better UX
* **Select Fields** - Improved select fields with consistent preview functionality
* **Project Environment Breadcrumb** - Updated with new styling and navigation improvements

#### Navigation & Usability

* **Keyboard Shortcuts** - Improved keyboard shortcuts details view with new changes
* **Selectors** - Added better selectors for:
  * SBOM download actions
  * Project environment breadcrumbs
  * JIRA and Linear settings fields

***

### 🔧 Technical Improvements

#### Infrastructure

* **Docker Configuration** 🐳 - Improved Docker setup with multi-platform support and optimizations
* **GitHub Actions** - Fixed deprecated set-output syntax
* **Environment Variables** - Replaced hardcoded values with GitHub variables and secrets for better security
* **Git Configuration** - Updated git environment variables for improved CI/CD

***

## v3.6.7

October 30th 2025

***

### 📋 Highlights

This release brings significant enhancements to the Interlynk Platform with comprehensive support for **CycloneDX 1.7**, advanced **TLP Classification** features, and an improved **Import Status Wizard**. We've also focused on enhancing user experience with interactive hover details, better accessibility, and numerous bug fixes across the platform.

***

### ✨ New Features

#### 🔐 TLP Classification Support

* **TLP Classification in SBOM General Tab** - Manage Traffic Light Protocol (TLP) classifications directly within SBOM general settings (#8054)
* **TLP in PDF and Excel Exports** - TLP classification now included in SBOM PDF and Excel exports for better data classification (#8083)
* **TLP in Attribution Exports** - Attribution PDF exports now display TLP classification information (#8094)
* **ShareLynk TLP Banner** - Added TLP classification banner for ShareLynk to clearly indicate data sensitivity (#8082)

#### 📦 CycloneDX 1.7 Support

* **Full CDX 1.7 Compatibility** - Complete support for importing and exporting CycloneDX 1.7 format (#8064, #2753)
* **Enhanced Detection** - Upgraded sbom-zen with CDX 1.7 support and improved component detection capabilities (#2748)
* **Spec Version Display** - SBOM download modal now shows spec version details for better clarity (#8076)

#### 🎯 Import Status Wizard Enhancements

* **Parts Selection Feature** - New capability to select specific parts during the import process (#8073)
* **Part Mappings API** - Added dedicated API endpoint for retrieving part mappings (#2755)
* **Search Functionality** - Implemented search in intersectingVulns for easier vulnerability filtering (#2766)
* **Filter Propagation** - Filters from intersectingVulns now properly pass to componentVulnVexImport mutation (#8092)

#### 🎨 User Experience Improvements

* **Vulnerability Details on Hover** - Quick access to vulnerability information through hover interactions (#8024)
* **Component Details on Hover** - Instant component information preview on hover (#8013)
* **CVSS Vector Details on Hover** - View CVSS vector details without navigation (#8021)
* **Product Environment Breadcrumb** - Enhanced navigation with product environment breadcrumbs (#8011)
* **Product Delete Modal** - Improved modal with auto-focus input for safer deletion (#8042)

#### 📊 Export & Reporting

* **New Attribution Export Check** - Added quality check for attribution exports (#8065)
* **Part Version in CSV Export** - Vulnerabilities CSV export now includes part version field (#8045)

#### ♿ Accessibility Enhancements

* **Organization Role Management** - Improved accessibility for role management features (#8047)
* **Role Creation Fields** - Enhanced role creation with proper accessibility support (#8049)

#### 🔄 Integration Improvements

* **Bitbucket OAuth Sync** - Automatic repository sync when Bitbucket OAuth connection is reset (#2761)
* **Bitbucket Delete Service Sync** - Proper handling of OAuth connection during Bitbucket delete operations (#2773)
* **SBOM Reprocess Visibility** - Reprocess SBOM option now properly visible (#2769)

***

### 🐛 Bug Fixes

#### Import Status Wizard

* Fixed bugs preventing proper operation of import status wizard (#2772)
* Environment field now populates with default values correctly (#8093)
* Import Status wizard properly populated with default values (#8091)

#### Component Management

* Fixed edit primary component inconsistency for hashes (#8070)
* Resolved component checksum selector issues (#8067)
* Updated checksum selectors in component edit drawer (#8069)
* Fixed default component selection in custom vulnerability create modal (#8077)
* Resolved UI freeze in edit components license field (#8048)

#### Data Integrity

* Fixed attribution deduplication logic (#2760)
* Corrected SBOM update process for TLP classification (#2756)
* Fixed parts breadcrumbs preview (#8050)

#### User Interface

* Fixed inconsistent select fields in Tools page (#8072)
* Updated SBOM relation tables with consistent layout (#8035)
* Fixed default user role field in SSO config modal (#8046)
* Show short ID in license detail modal for custom licenses (#8081)
* Updated VEX modal header with conditional vulnerability ID preview (#8031)

#### Webhooks & Notifications

* Fixed webhook URL validations for Microsoft Teams integration (#2762)

#### Settings & Configuration

* Fixed ChangeLog display for project settings (#2749)
* Removed unwanted props in VEX history logs (#8051)
* Hide run support analysis option for EOS or EOL product versions (#8039)

#### Testing & Quality

* Fixed SBOM check e2e test (#8079)
* Fixed SBOM check action selectors (#8078)
* Added selectors for graphs menu and product overview table (#8041)
* Added selector for include parts checks (#8068)
* Removed duplicate role test (#8066)

#### Performance

* Optimized settings lists tab with cached querying and removed duplicate components (#8052)

#### Filters & Search

* Enhanced license exclude filter with duplicate component options (#8075)

#### Security & Authentication

* Reverted problematic automatic token refresh implementation (#8080)
* Re-implemented token refresh with proper fix (#7231)

***

### 🔧 Technical Improvements

* **Ticket Formatting Refactor** - Refactored ticket description formatting to skip custom fields for cleaner output (#2775)
* **SBOM Validation Logic** - Simplified VulnDiffService by removing unnecessary project group check (#2754)
* **Dependency Update** - Bumped Vite from 7.1.11 to 7.1.12 (#8059)

***

### 📈 Summary

This release demonstrates our commitment to:

* 🔒 Enhanced security with TLP Classification
* 📦 Industry standard compliance with CycloneDX 1.7
* 🎯 Improved user workflows and productivity
* ♿ Better accessibility for all users
* 🐛 Continuous quality improvements

***

## v3.6.5

October 23rd 2025

***

### ✨ Highlights

* 🦊 **Complete GitLab Integration** - Full OAuth authentication and webhook support for GitLab
* 🔒 **Enhanced Vulnerability Tracking** - Improved NVD local matching and CVSS 3.1 scoring prioritization
* 📊 **VEX Enhancements** - New details pop-up and history export with NVD Alias ID
* ♿ **Accessibility Focus** - Comprehensive accessibility improvements across the platform

***

### 🎉 New Features

#### GitLab Integration

Complete GitLab integration with full OAuth and webhook support (#2704, #2723, #2729, #2738, #7988)

* 🔐 OAuth authentication flow for GitLab connections
* 🏢 Support for GitLab groups, repositories, and webhook handling
* 💬 PR comments support for GitLab merge requests
* ✅ GitLab integration health check service
* 🔧 Environment rules and runner tokens for GitLab CI/CD
* 🏷️ Tag push and webhook event processing
* 📥 GitLab project import functionality
* ⚙️ Configuration and deletion capabilities for GitLab connections

#### Enhanced License Management (#8016)

* ✏️ Improved License Editor with enhanced feedback for LicenseRef
* 🌐 Better handling of global license states

#### Notification System Improvements (#7990)

* 📋 Implemented expandable notification preferences table with edit mode
* 🎛️ Enhanced user control over notification settings

#### VEX Enhancements

* **VEX Details Pop-up (#7985):** Added mouse-over pop-up for VEX details on Global View status column
* **VEX History Export (#7991):** Added "NVD Alias ID" and "Assigned" fields to VEX history export

#### API Enhancements

* 🔌 New SBOM activity API (#2718)
* 📊 Introduced `PartVersionsForOrganizationResolver` for enhanced vulnerability tracking (#2722)

#### Performance Optimization (#7981)

* ⚡ Added caching logic to refetching in organization settings tabs queries for improved performance

***

### 🐛 Bug Fixes

#### GitLab-Related Fixes

* Fixed tag push event handling for GitLab webhooks (#2738)
* Fixed project scopes validation for GitLab connections (#2740)
* Updated webhook event processing to properly handle tag pushes and ignore branch push events (#2729)

#### Vulnerability Management

* Fixed error handling in `CommonVulnerabilitiesFinder` and `intersecting_vulns_resolver` (#2736)
* Fixed VEX copy bug (#2739)
* Improved vulnerability matching for 'is\_part' vulnerabilities by project group names (#2710)
* Refactored vulnerability fetching to separate source and destination SBOM handling (#2710)
* Fixed vulnerability imports (#2718)
* Fixed UI issues in add hash select field (#8038)
* Enabled importing vulnerability status from EOL/EOS product versions (#8036)
* Applied NVD alias ID fallback logic in VEX modal (#8026)
* Applied NVD\_ALIAS\_ID fallback logic in component View Vulnerabilities drawer (#7977)

#### Integration Fixes

* Fixed Jira vulnerability management provisioning to properly filter issue types by scope (#2730)
* Fixed notification titles for all notification types (#2727)
* Fixed license resolution (#2718)
* Fixed project field in JIRA vulnerability management modal (#8023)

#### UI/UX Fixes

* Fixed long license name overflow in SBOM details page (#8025)
* Fixed SBOM upload modal issues (#8012)
* Removed invalid ">" character from JSX element in Button component (#7976)

#### Data Management

* Fixed importing status filter bug in import status wizard (#8000)
* Removed cached query fetching in paginated query (#8020)
* Improved version table refresh logic (#8027)

#### Team Management

* Fixed inability to revoke invitation in team management table (#7978)

#### General Fixes

* Fixed duplicator SSL issues in dev environment (#2726)
* Fixed crash in vulnerability processing (#2712)
* Detect proper previous version for version comparison (#2718)
* Various spec fixes (#2721, #2715)

***

### ⚡ Improvements

#### Performance & Matching

* 🎯 Enforce strict matching on parts by default (#2745)
* 🔍 Start using NVD local matching for improved vulnerability detection (#2711)
* 📈 Prioritize CVSS 3.1 scoring and OSV data backfilled from NVD (#2720)
* 🚀 Optimized copy logs (#2719)

#### Process Improvements

* 📋 Copy VEX data only on imports (not on reconciliation) (#2713)
* ⏱️ Updated timeout configurations (#2714)
* 🔧 Enhanced `CommonVulnerabilitiesFinder` with improved querying capabilities (#2722)

#### Refactoring

* 🧹 Removed unwanted props, queries, and logic from Product Details Vulnerability component (#8017)

***

### ♿ Accessibility Improvements

Significant accessibility enhancements across multiple components to improve platform usability:

* Added accessibility props for webhook fields (#8029)
* Added selectors for declared and concluded license (#8019)
* Enhanced SSO connection accessibility (#7979)
* Updated notification accessibility (#7982)
* Updated component identifiers accessibility (#7975)
* Updated component checksum fields accessibility (#7974)
* Updated analytics fields with proper selectors (#7983)
* Added dynamic selector for package actions (#8018)
* Added notification preference check selectors (#8037)
* Added selector for component details links (#8032)
* Updated OAuth action selectors (#8022)

***

### 🔄 Changes & Rollbacks

#### Feature Rollback

* Reverted: Detailed Parts selection feature in vulnerability status import wizard (#8030)
  * Note: Initial implementation was in #8015, rolled back for further refinement

***

## v3.6.2

October 15th 2025

***

### 🎉 Highlights

This release brings powerful new capabilities for vulnerability management, improved hash and checksum support, and significant accessibility enhancements across the platform. Notable additions include VEX copy across versions, vulnerability status history exports, and a comprehensive keyboard shortcuts interface.

***

### ✨ New Features

#### Vulnerability Management

* **Vulnerability Status History CSV Export** 📊\
  Export complete vulnerability status history logs to CSV format for reporting and analysis
* **VEX Copy Across Versions** 🔄\
  Copy VEX statements across multiple product versions, streamlining vulnerability disclosure workflows
* **Custom Fields Support** 🏷️\
  Added custom fields support to VEX status mouseover popups and vulnerability status log history
* **Enhanced Status Tracking** 👁️\
  Mouse over popup displays detailed status information in the import status wizard

#### Component & Hash Management

* **Hash Management** #️⃣\
  Full support for adding and editing component hashes with validation
* **Checksum Support** ✅\
  Added checksum arguments to component create and update operations with built-in validation
* **Tooltip Guidance** 💡\
  Informative tooltips added to checksum hashes field in component creation and editing

#### Import & Data Management

* **Advanced Import Filters** 🔍\
  New filtering capabilities in the import status wizard for better data management
* **Enhanced Import Status Table** 📋\
  New columns added to align with vulnerabilities tab, providing consistent data views
* **Searchable License Fields** 🔎\
  License import fields are now fully searchable for easier data discovery
* **NVD Local Support** 🗄️\
  Local NVD database support for improved performance and offline capabilities

#### User Experience

* **Keyboard Shortcuts Modal** ⌨️\
  New keyboard shortcuts interface on SBOM page displaying all available shortcuts
* **Executive Dashboard Enhancements** 📈\
  Added clarification texts for Policy Results to improve understanding

***

### 🐛 Bug Fixes

#### Component Issues

* Fixed component details card missing data for parts components
* Resolved Component Hierarchy GraphQL errors for parts components
* Fixed version license table column display when no license data is available

#### VEX & Vulnerability Fixes

* Fixed upstream checkbox visibility in VEX modal - now only shows when all selected vulnerabilities have connected upstream
* Corrected VEX status column tag UI mismatch in Also Affected drawer

#### System & Performance

* Eliminated unwanted crypto assets query hitting system logs
* Fixed incorrect help texts in Product Settings

***

### 🚀 Improvements

#### Accessibility Enhancements

* Added unique accessibility props to actions for easier Playwright test selectors
* Enhanced accessibility props on license subheader buttons
* Updated SBOM and Vulnerability actions with accessibility identifiers
* Improved users action menu with accessibility props
* General accessibility improvements across the platform

#### Data Management

* Added vulnerability status filters to import query capabilities
* Enhanced changelog tracking for VEX import

***

## v3.6.1

October 9th 2025

***

### ✨ Highlights

This release brings significant improvements to vulnerability management, Jira integration, and system performance. Key highlights include enhanced VEX status handling, multi-project Jira associations, and a comprehensive executive summary dashboard with dynamic data visualization.

### 🎯 New Features

#### Vulnerability Management

* **Enhanced Component Relationships** ✅ - Component relationship view now includes `dependencyOf` relationships for better dependency tracking
* **VEX Status Filtering** - Added filtering by status in product vulnerabilities tab for easier vulnerability triage
* **Version Profile Memory** - Implemented memory-based version profiling.
* **CVE ID Visibility** - CVE IDs are now displayed by default in the Import Status Wizard for better transparency
* **VEX Details Enhancement** - Added mouse-over functionality for VEX details popup for improved user experience
* **"Unspecified" VEX Status** - Added support for "unspecified" VEX status in Jira custom fields

#### Jira Integration 🎫

* **Multi-Project Support** - Support for associating multiple Jira projects with vulnerability management
* **Integrated Vuln Management Strategy** - Vulnerability management strategy is now fully integrated into JiraFields
* **Enhanced Jira Configuration** - Improved Jira vulnerability management configuration with better error handling
* **Bitbucket OAuth Setup** - Configured Bitbucket OAuth consumer for staging and production environments

#### Dashboard & Analytics 📊

* **Executive Summary Drawer** - Implemented comprehensive executive summary drawer with dynamic data visualization
* **Clarified Dashboard Cards** - Added clarification sub-texts to executive dashboard cards for better understanding
* **System Log Performance** - Significantly improved system log loading speed by fetching activity details only on expand

#### License Management 📄

* **License Attribute Review** - Added ability to review license attributes directly from version license tab
* **License Edit Error Handling** - Improved error feedback for license edit API failures

#### User Experience 💫

* **Upstream Product Clarity** - Enhanced "Also Update Upstream Products" feature with an upstream product drawer for better visibility
* **Keyboard Navigation** - Added keyboard navigation options for working between version tabs on macOS
* **Dynamic Multi-Select Height** - Fixed dynamic height for multi-select component for better responsiveness

### 🐛 Bug Fixes

#### Critical Fixes

* **Setup Script Repair** - Fixed broken setup script
* **Application Crash Fix** - Resolved critical application crash issue
* **NVD Link Visibility** - Fixed NVD link visibility for vulnerabilities with and without aliases

#### VEX Status Issues

* **VEX Count Update** - Fixed issue where VEX status changes did not update counts correctly
* **Default VEX Status** - Corrected VEX status defaulting incorrectly to "Affected"

#### Jira Integration Fixes

* **Custom Fields Creation** - Fixed Jira issue custom fields creation
* **Issue Type Selection** - Prevented selection of InterlynkVuln issue type without proper JiraVulnManagementConfig

#### User Interface Fixes

* **Success Toast Prevention** - Fixed issue where success toasts appeared even when mutations failed
* **Package Override Tests** - Fixed package override E2E test locators
* **Bitbucket Repository Viewing** - Added error handling for viewing Bitbucket repositories

#### Performance Optimizations

* **Changelog Query Optimization** - Optimized changelog queries for better performance
* **System Log Optimization** - Improved system log performance by fetching activity details on demand

#### Security & Access Control

* **User Removal** - Enhanced user removal functionality
* **NVD Keys Expansion** - Added additional NVD keys for broader vulnerability coverage

#### Notifications

* **Trial Started Notification** - Implemented trial started notification system
* **PR Comment Service Trigger** - Fixed PR comment service to trigger only in import mode during SbomVulnsJob

***

## v3.6.0

October 2nd 2025

***

### ✨ Highlights

This release focuses on **performance optimization**, **enhanced Jira integration**, and **improved user experience** across the platform. We've significantly reduced query overhead, streamlined workflows, and introduced powerful new capabilities for vulnerability management.

***

### 🎉 New Features

#### Jira Vulnerability Management Integration

* **Full Jira integration** for vulnerability management workflows
* **Custom field synchronization** including VEX status from Jira
* **Project type API** support for better project management
* Enhanced configuration options for seamless Jira connectivity

#### Enhanced Filtering & Search Capabilities

* **Array support** for product filters in notification preferences
* **Label IDs filtering** for more granular notification control
* **IDs filter** added to AttributionsFinder and GraphQL resolver
* **Searchable product filter** on policy details page
* **Short-ID based license queries** for easier lookups

#### UI/UX Improvements

* ✅ **Component Details modal** now available in the vulnerabilities tab
* ✅ **Sortable label options** with drag-and-drop ordering
* ✅ **Improved component filter** usability for large lists
* ✅ **Visual hierarchy enhancements** in component insight drawer
* ✅ **Consistent preview** experience on policy details page
* ✅ **PURL recommendation logic** updates for better accuracy

#### Workflow Simplification

* ✅ **Single state model** for vulnerability import wizard
* ✅ **Consolidated props** in license import wizard
* ✅ Streamlined notification preference management

***

### 🐛 Bug Fixes

#### Performance Optimizations

* ⚡ **Reduced N+1 queries** in Checks functionality
* ⚡ **Optimized GraphQL queries** across multiple modules:
  * GetActivities (system logs)
  * GetCustomVulns
  * CveLookup
  * GetAttributionsData (license attribution)
  * PolicyRuleViolations
  * Attribution data export
* ⚡ **Removed GraphQL batch** processing for improved performance
* ⚡ **Improved CI build time**

#### General Fixes

* 🔧 Fixed rake delete task
* 🔧 Resolved unique short-ids generation issue
* 🔧 Fixed project IDs scoping
* 🔧 Corrected trial status indicator display
* 🔧 Fixed product tab navigation from command bar
* 🔧 Resolved custom vulnerability creation by removing unused fields
* 🔧 Fixed component name rendering and clickable areas in tables
* 🔧 Fixed license text override sync across multiple tabs
* 🔧 Prevented page scroll jump when opening component details modal
* 🔧 Fixed CheckOauthConnection query skip logic for free tier and customer view

#### Code Quality & Maintenance

* 🧹 Removed login notification logic from ApiKeyService
* 🧹 Removed duplicate cryptography component
* 🧹 Enhanced author extraction logic in cdx\_importer
* 🧹 Improved component card modal by removing unwanted logic
* 🧹 Added ecosystem information to component cards
* 🧹 Updated JavaScript config to include absolute paths
* 🧹 Added fallback matching for intersecting vulnerabilities
* 🧹 Refactored policy subject field with loading indicator

***

## v3.5.7

September 25th 2025

***

### ✨ Highlights

This release focuses on **performance optimization**, **UI/UX improvements**, and **code organization** to deliver a more efficient and user-friendly experience. Key improvements include significant query optimizations, enhanced component organization, and the introduction of new trial and recommendation features.

***

### 🆕 New Features

#### 🏢 **Enterprise Trial System**

* Comprehensive Enterprise Trial system with dedicated UI components
* New trial flow implementation for better user onboarding
* Enhanced trial management capabilities

#### 📧 **Enhanced Email Notifications**

* Added Debug support for production emails in NotificationMailer
* Improved email delivery and tracking capabilities

***

### 🎨 UI/UX Improvements

#### 🔧 **Component Organization & Structure**

* Restructured forms components into organized folder structure
* Reorganized navigation components into structured directories
* Optimized UI components with better folder organization
* Centralized selectors for improved test architecture

#### 💳 **Connection Cards Enhancement**

* Enhanced connection cards UI with improved visual design
* Fixed Bitbucket connection card overflow layout issues
* Updated Bitbucket repository list preview

#### 📊 **Product & Component Details**

* Improved product settings page with smaller, readable components
* Enhanced component details card preview
* Better product progress overview card with consistent layout
* Updated component overview links in support and license tables

#### 📝 **Form & Field Improvements**

* Enhanced fields with copy-to-clipboard functionality
* Refactored VEX and license import fields with consistent preview
* Unified form labels component to remove duplicates
* Added ability to edit General fields without requiring deletion
* Sorted labels in product/edit/import/relationship views

#### 🔍 **Modal & Navigation Enhancements**

* Improved version details modal functionality
* Enhanced package page navigation via command bar
* Better CPE checks modal layout
* Fixed navigation and layout breaking issues

***

### ⚡ Performance Optimizations

#### 🗄️ **Database Query Improvements**

* Optimized SBOM Comparison GetVulnDiff Query for better performance
* Enhanced GetVulnDiffSharelynk query for SBOM comparison
* Optimized SBOM comparison components tab GetSbomDrift Query
* Improved GetSbomDriftSharelynk query performance
* Streamlined SBOM policy results query
* Optimized GetPackageData query by removing unused fields
* Enhanced vulnerability deletion query optimization
* Removed unused fields from VerifyCustomVuln and project support queries

***

### 🐛 Bug Fixes

#### 🔧 **Component & Import Fixes**

* Fixed component import errors
* Resolved custom loader import issues
* Fixed Bitbucket button incorrectly showing as active on products
* Corrected support permission checks

#### 🔐 **Permission & Role Management**

* Added permission checks to disable Save as Rule button in checks modal
* Fixed disable action buttons for viewer role across modals
* Resolved support level update permissions from SBOM checks table

#### 📊 **Data & Display Issues**

* Fixed CustomVulnCreate to include reported, published, and last modified dates
* Corrected License Type & List Filter in Components and License tabs
* Fixed author update mutation bugs
* Resolved package search functionality issues

#### 🧪 **Testing & E2E Improvements**

* Fixed Jira E2E test locator failures
* Stabilized flaky SBOM list functionality E2E tests
* Improved vulnerability parts status update E2E test stability
* Resolved general E2E test failures due to UI changes
* Added exported package override E2E test to main suite

#### 🏗️ **Infrastructure & Configuration**

* Updated docker-compose configurations with new variable names
* Fixed deployment configurations for staging environment
* Resolved Bitbucket repository is\_imported field logic
* Addressed trial feature implementation issues

***

### 🔄 Code Quality & Maintenance

* Removed duplicate delete SBOM logic into centralized component
* Eliminated duplicate queries across the platform
* Improved code organization and component structure
* Enhanced test architecture with centralized selectors

***

## v3.5.6

September 18th 2025

***

### ✨ Release Highlights

This release focuses on enhancing security integrations, improving user experience across the platform, and delivering significant performance optimizations. We're excited to introduce **Bitbucket OAuth Integration** as our flagship feature, along with numerous UI/UX improvements and critical bug fixes.

***

### 🆕 New Features

#### 🔗 Bitbucket OAuth Integration

* **Complete OAuth workflow** for seamless Bitbucket authentication
* **Enhanced repository management** with secure token handling
* **Streamlined connection setup** with improved user guidance
* **Integrated configuration modal** with required field validation

#### 📊 Enhanced Bulk Operations

* **Vulnerability bulk operations menu** - Manage multiple vulnerabilities efficiently with a floating action menu
* **Improved automation rules feedback** - Better user experience when creating and managing automation rules
* **Environment rules in KBar** - Quick access to environment rules through the command palette

#### 🎨 UI/UX Improvements

* **Standardized modal layouts** - Consistent header design across all application modals
* **Enhanced avatar management** - Upload overlay and visual cues for better user interaction
* **Improved component styling** - Updated parts cards and CPE cards with conditional previews
* **Better breadcrumb handling** - Overflow management and consistent navigation experience

***

### 🐛 Bug Fixes

#### 🔐 Security & Permissions

* **Fixed license page rendering bug** - Resolved display issues on license attribution pages
* **Enhanced OAuth connection policies** - Proper permission handling for OAuth integrations
* **Restricted operator permissions** - Operators can no longer delete existing connections
* **Viewer role restrictions** - Proper permission enforcement for SBOM lifecycle editing and environment rule updates

#### 📈 Performance Optimizations

* **Semantic version sorting fix** - Proper version comparison and ordering
* **Optimized database queries** - Removed unnecessary queries from product vulnerabilities, automation rules, and vulnerability tabs
* **Enhanced search functionality** - Resolved package search issues and improved component identifiers
* **Streamlined OAuth connections** - Removed unused fields to improve query performance

#### 🛠️ Data & Display Fixes

* **CSV export corrections** - Fixed component support status data export
* **Vulnerability table improvements** - Resolved severity column preview and archived SBOM display issues
* **License compliance fixes** - Corrected license tab modals and document license checks
* **Support status accuracy** - Fixed end-of-support display in expanded columns

#### 🏗️ System Improvements

* **Workspace access handling** - Better management of blank workspace scenarios
* **Component parts optimization** - Removed create limits and improved breadcrumb previews
* **Notification controls** - Proper disabling when permissions are missing
* **Version name formatting** - Consistent string formatting across license text and version columns

***

### 🔧 Technical Improvements

* **Refactored connection hooks** - Improved `useBitbucketConnection` implementation
* **Enhanced component architecture** - Standardized `LynkAction` component usage across tables
* **Unit test coverage** - Added comprehensive tests for SBOM metrics data lazy query hooks
* **Code organization** - Better separation of concerns with manufacturer query optimization

***

## v3.5.5

September 11th 2025

***

### 📋 Release Highlights

This release brings significant improvements to platform stability, performance optimizations, and enhanced integration capabilities. We've focused on fixing critical bugs, optimizing database queries, and improving the overall user experience across vulnerability management, SBOM handling, and integration workflows.

### ✨ New Features

#### 🌐 Environment Management

* **Git Events to Environment Mapping** - Automatically map Git events to specific environments for better tracking and deployment visibility
* **Global Environment Filter** - Added environment filtering capabilities in vulnerability details view for improved context
* **Environment Rules Implementation** - New Bitbucket webhook integration for automated environment rule enforcement

#### 🔗 Enhanced Integrations

* **ShareLynk Vulnerability Diff Support** - Extended ShareLynk integration to support vulnerability difference analysis
* **Health Checks for Messaging Platforms** - Added comprehensive health monitoring for Slack and Teams integrations
* **Improved Error Handling** - Enhanced error management for Slack and Teams configuration processes

#### 🔐 Authentication & Security

* **SAML Auto-Registration Fix** - Resolved issues with SAML auto-registration for existing user identities
* **Updated License Lists** - Refreshed and expanded supported license database

### 🛠️ Improvements & Optimizations

#### ⚡ Performance Enhancements

* **Query Optimization** - Removed redundant fields and optimized multiple database queries across:
  * Bitbucket repositories and connection checks
  * Jira configuration modals
  * SBOM comparison components
  * Vulnerability tab queries for free tier
  * SBOM alternatives and parts queries
* **State Management** - Eliminated redundant loading states in Linear and Jira configuration modals
* **Component Restructuring** - Reorganized modal and drawer components into structured feedback hierarchy

#### 📊 Data Export & CSV Improvements

* **Enhanced CSV Exports** - Fixed and improved data accuracy in:
  * SBOM vulnerability CSV exports
  * Vulnerability CSV exports with correct assigned and updated dates
  * Automation export functionality

#### 🎨 User Interface Enhancements

* **Table Management** - Improved row selection logic across project, SBOM, and support status tables
* **Filter Consistency** - Enhanced filter behavior with proper row selection clearing
* **Component Styling** - Applied consistent styling to component and vulnerability columns
* **Tab Layout** - Improved tab layouts with auto-wrapping for overflow scenarios
* **Modal Improvements** - Enhanced component add modal with conditional preview capabilities

### 🐛 Bug Fixes

#### 🔧 Critical Fixes

* ✅ **Bulk Issue Creation** - Resolved logic errors in bulk issue creation workflow
* ✅ **NVD Link Display** - Fixed missing NVD (National Vulnerability Database) links
* ✅ **Policy Editing** - Resolved bug preventing policy modifications
* ✅ **Environment Switching** - Fixed environment switch functionality issues

#### 🎯 UI/UX Fixes

* ✅ **VEX History Alignment** - Corrected alignment issues in VEX history listings
* ✅ **License Import Drawer** - Fixed layout problems in license import interface
* ✅ **Policy Violation Preview** - Improved component list preview in policy violation drawer
* ✅ **EPSS Percentile Column** - Corrected EPSS percentile data display
* ✅ **SSO Form Layout** - Updated Single Sign-On form layout with design improvements

#### 📈 Data Accuracy Fixes

* ✅ **Vulnerability Counts** - Fixed incorrect vulnerability counts in Parts view
* ✅ **Support Status Functions** - Resolved create/update function issues for support status
* ✅ **Component Hierarchy** - Fixed rendering issues in component hierarchy from violation drawer
* ✅ **ShareLynk UI Errors** - Resolved user interface errors in ShareLynk integration

#### 🔄 Workflow Improvements

* ✅ **Notification Preferences** - Prevented updates to notification preferences without enabled mediums
* ✅ **Table Column Labels** - Fixed missing column labels in version and automation tables
* ✅ **Custom Vulnerability Modal** - Corrected modal title display
* ✅ **Project Table Refetch** - Updated query refresh logic for product tables

***

## v3.5.3

September 04th 2025

***

### ✨Release Highlights

This release focuses on **performance optimization**, **enhanced user experience**, and **expanded integration capabilities**. We've introduced bulk operations for Linear tickets, improved SBOM management workflows, and resolved numerous UI/UX issues to deliver a smoother platform experience.

***

### ✨ New Features

#### 🎫 Enhanced Ticket Management

* **Bulk Linear Ticket Creation**: Create multiple Linear tickets simultaneously for improved workflow efficiency
* **Linear Defaults Support**: Streamlined ticket creation with pre-configured default values
* **JIRA Verification Details**: Enhanced JIRA configuration with comprehensive verification workflows

#### 📊 Vulnerability Management Improvements

* **EPSS Percentile Sorting**: New sortable column for EPSS percentile in vulnerability tables
* **Created At Column**: Added timestamp column with sorting capabilities to vulnerability tables
* **Improved Vulnerability Diff**: Enhanced notification system for vulnerability differences

#### 🔧 SBOM & Components Enhancements

* **Optimized SBOM Performance**: Removed redundant queries for free-tier and customer views
* **Enhanced CSV Export**: Updated column names and values for SBOM components export
* **Supplier Field Fallbacks**: Added graceful handling for empty supplier field values
* **Component Relationship Tree**: Improved logic for parts component relationship visualization

***

### 🐛 Bug Fixes

#### 🔐 Authentication & SSO

* Fixed error messaging when tenant is not found during SSO authentication
* Resolved Bitbucket configuration issues by using `enabled` instead of `webhookEnabled`

#### 🎨 User Interface

* **Fixed UI Flickering**: Resolved flickering issues in:
  * Notification bell on environment switch
  * SBOM components filters
  * Parts filters
  * Create parts action on SBOM archive page
* **Layout Improvements**:
  * Fixed breaking UI layout in global vulnerabilities page
  * Updated environment selector list alignment
  * Improved fields alignment in policy modal
  * Enhanced markdown preview background color

#### 📈 Performance Optimizations

* **Reduced Redundant Queries**: Eliminated duplicate queries in:
  * Version breadcrumb components
  * Project group hooks
  * Environment filters
  * Notification bell connections
* **Optimized Components**:
  * Streamlined export CSV modal
  * Improved SBOM table with declarative tab configuration
  * Enhanced notification menu stability and async handling

#### 🔍 Data & Filtering

* Fixed custom license filtering logic in AttributionsFinder and SBOM components
* Resolved vulnerability column data display issues for EPSS and created\_at in ShareLynk
* Fixed direct filtering not working in ShareLynk vulnerability view
* Corrected component license state clearing behavior

#### 🛠️ Developer Experience

* **E2E Testing**: Optimized end-to-end test files for better stability and consistency
* **Code Refactoring**: Improved component architecture across multiple areas for better maintainability
* **Activity Logs**: Enhanced icon styling and tooltip functionality

***

### 🔧 Technical Improvements

#### 📝 Code Quality

* Refactored multiple components to remove redundant states and code duplication
* Improved error handling across SBOM supplier creation and field validation
* Enhanced preview logic in various modals and comparison views

#### 🏗️ Architecture Updates

* Restructured notification settings folder hierarchy for better organization
* Moved query logic into SbomInfo for cleaner ProductDetailsSbomNew component
* Consolidated environment filter logic to reduce component nesting

#### 📦 Dependencies

* Updated `react-syntax-highlighter` from 15.6.5 to 15.6.6

***

### 🎯 User Experience Enhancements

* **Auto-close Modals**: Download excel modals now automatically close after file download
* **Improved Tooltips**: Enhanced compare action tooltips based on user selection
* **Conditional Actions**: Added smart row expansion handling in version tables
* **Better Validation**: Improved field validation preview in author modals
* **Enhanced Navigation**: Fixed kBar menu refetch issues after SBOM operations

***

## v3.5.2

August 28th 2025

***

### ✨ Highlights

This release brings significant improvements to vulnerability management, notification systems, and user experience. Key highlights include automated ticket creation for policy violations, enhanced notification management, and comprehensive UI/UX optimizations across the platform.

### 🆕 New Features

#### 🎫 Automated Ticket Creation

* **Jira Integration**: Auto-create tickets on vulnerability policy violations with proper metadata
* **Linear Integration**: Enhanced pull-request information integration for external issue trackers
* **Policy Management**: Bulk policy inclusions support with improved validation checks
* **Preview Mode**: Enhanced validation for tickets created in preview mode

#### 🔔 Enhanced Notification Management

* **Granular Controls**: Independent organization and user notification settings
* **Channel Support**: New SBOM\_UPLOAD\_FAILED notifications for user/org channels
* **Internal Notifications**: Slack integration for ticket and connection lifecycle events
* **Permission System**: Dedicated notification management permissions

#### 🔗 Repository Integration Improvements

* **Bitbucket Webhooks**: Repository-level webhook control for better integration management
* **GitHub Standardization**: Consistent casing and naming across GitHub and Bitbucket integrations

#### 🔐 SSO & Authentication

* **Enhanced SSO**: Support for issuer configuration in Single Sign-On
* **Organization Management**: Improved error handling in organization creation flow
* **User Invitations**: Enhanced form validation for user invite processes

#### 📊 ShareLynk Enhancements

* **Performance**: Optimized ShareProductData queries with unused field removal
* **UI Improvements**: Better vulnerability status display and drawer functionality
* **Delete Operations**: Improved loading states for delete button actions

### 🛠️ Improvements & Optimizations

#### 💾 Performance Enhancements

* **Query Optimization**: Reduced database load through optimized SBOM and product data queries
* **Free Tier**: Specialized optimizations for free-tier accounts to improve response times
* **Component Loading**: Split SBOM table data queries for faster load speeds

#### 🎨 User Interface Improvements

* **Table Styling**: Consistent layout and styling applied across all changelog tables
* **Component Cards**: Enhanced component card actions and navigation
* **Notification Tabs**: Segmented control design for better notification management
* **Modal Behavior**: Prevent accidental modal closures on backdrop clicks

#### 📱 Component Management

* **Vulnerability Status**: Better display of vulnerability status from parent SBOMs
* **License Handling**: Improved license dropdown functionality and auto-complete display
* **Archive Support**: Enhanced permissions and UI for archived SBOM operations

#### 🔍 Search & Navigation

* **KBar Integration**: Added notification route to KBar actions for better discoverability
* **Breadcrumbs**: Optimized parts breadcrumbs with redundant query removal
* **Folder Structure**: Reorganized folder structure for better maintainability

### 🐛 Bug Fixes

#### 🔧 Core Functionality

* Fixed custom license name handling and display issues
* Resolved validation checks for auto-ticket creation in preview mode
* Fixed bug in notification logic affecting user/org settings
* Corrected vulnerability status imports and VEX status validation

#### 🖥️ User Interface Fixes

* Fixed license dropdown cropping issues in component details drawer
* Resolved component vulnerability navigation problems
* Fixed invalid date display in license list tooltips
* Corrected placeholder styling in product settings tabs

#### 🔗 Integration Fixes

* Fixed webhook toggle control display when importing Bitbucket repositories
* Resolved missing field values in role update modals
* Fixed SBOM restore and promote to version functionality for archived items
* Corrected menu placement for license field selections

#### 📊 Data & Query Fixes

* Always use short-id first for component lookups
* Fixed part name display in vulnerability status imports
* Removed unused queries for original SBOM downloads in ShareLynk view
* Added proper creation timestamps to component vulnerabilities

***

## v3.5.1

August 21th 2025

***

### ✨ Highlights

This release focuses on **performance optimization**, **security enhancements**, and **user experience improvements** across the Interlynk Platform. We've significantly optimized database queries, enhanced the notification system, and introduced new vulnerability comparison features.

#### 🎯 Key Improvements

* **Enhanced Security**: Upgraded Rails framework to address critical security vulnerabilities
* **Performance Boost**: Optimized 25+ database queries for faster page loads
* **\[Early Release] Smart Notifications**: Introduced comprehensive Notification Manager system
* **Vulnerability Analysis**: New vulnerability comparison and filtering capabilities
* **UI/UX Enhancements**: Consistent styling and improved user interactions
* CI/CD: Pylynk new version with auto CI/CD detection and extraction.

***

### 🆕 New Features

#### 📊 Vulnerability Comparison

* **Feature**: vulnerability comparison
* Compare vulnerabilities across different versions and components
* Enhanced vulnerability diff table with severity filtering

#### 🔔 Notification Manager

* **Notification Manager**
* Centralized notification system for better user communication
* Enhanced integration health check failure email templates
* Bug fixes and optimizations for improved reliability

#### 📝 Enhanced Patch Management

* **Persist PR Information on Webhook Runners**
* **Add change logs to patch** functionality
* **Add log changes to patch update** tracking
* Better visibility into patch history and changes

#### 🔗 External Issue Tracking

* **Add schema for external\_issue\_tracker\_links**
* **Restrict creation of multiple issue tracker links** for Jira and Linear
* Improved JIRA configuration with proper validations

#### 🎨 User Interface Improvements

* **Add clear indicator to license select field**
* **Improved layout of multiple fields preview** in config modal
* **Consistent styling** across rules modal, profile actions, and SBOM tables
* **Enhanced component name preview** in SBOM checks tables

***

### 🔧 Technical Improvements

#### ⚡ Performance Optimizations

Multiple query optimizations have been implemented to improve platform performance:

* **Optimize health score setting query** by removing unused fields
* **Optimize archived versions query** by removing unused fields
* **Optimize build sbom primary component query** by removing unused fields
* **Optimize product list page** by removing redundant total count query
* **Optimize sbom page** by removing redundant component total count query
* **Remove redundant primary component data** query from relationships drawer
* **Optimize GetComponentPath query** call location
* **Remove redundant GetCustomFields query** from FieldModal
* **Optimize GetProjectSettings, GetPolicy, GetVersionsTable** queries

#### 🔄 Component Management

* **Update component on patch edit** functionality
* **Lower purl match with package-versions** for better accuracy
* **Improved CompSupplier component** for cleaner validation
* **Enhanced component add modal** with consistent preview

#### 🔍 Search & Navigation

* **Add SSO tab to KBar navigation** for easier access
* **Fix refresh to update checks filter options**
* **Minimize redundant API calls** during SBOM checks update

***

### 🐛 Bug Fixes

#### 🔒 Security

* **Upgrade Rails to 7.1.5.2** to fix critical security issues

#### 🔧 System Fixes

* **Allow user to logout without auth** for better user experience
* **Fix bugs in notification manager** for improved reliability
* **Fix some issues in Notification manager** additional stability improvements
* **Repo name could be blank** handling edge cases
* **Fix archive and unarchive sbom version error**

#### 🎨 UI/UX Fixes

* **Fix scrollbar not working** for archived version tabs
* **Fix profile action styling** in user settings page
* **Resolve unintended auto-open behavior** on modal/drawer initialization
* **Fix supplier delete option missing** in general tab
* **Fix policy update function** for proper policy management
* **Resolve field alignment issue** in linear config modal

#### 📊 Data & Display Fixes

* **Fix license attribution data query refetch** not working in ShareLynk view
* **Fix components dropdown showing null** when version is unavailable
* **Fix vulnerability import e2e test** locator updates
* **Fix typo in component insights drawer**
* **CERT-IN SBOM Guidelines link updated** to new address

#### 🧪 Testing & Quality

* **Optimize E2E automation** and changelog spec tests
* **Fix package e2e tests** by correcting wrong locators
* **Update dependencies to latest patch versions**

***

## v3.4.9

August 14th 2025

***

### ✨ Highlights

This release focuses on **performance optimization**, **enhanced vulnerability management**, and **improved user experience** across the platform. Key improvements include advanced vulnerability diffing capabilities, streamlined SBOM processing, and significant UI/UX enhancements.

***

### ✨ New Features

#### 🔍 **Advanced Vulnerability Analysis**

* **Vulnerability Diff Service**: Compare vulnerabilities between different SBOM versions to track security changes over time
* **Automated Vulnerability Diff Notifications**: Receive instant notifications when vulnerability differences are detected after imports
* **Enhanced Global Vulnerability Export**: Export vulnerability data with additional comprehensive fields for better analysis

#### 🔗 **Enhanced SBOM & CI/CD Integration**

* **CI/CD Metadata Support**: Full support for CI/CD metadata in SBOM uploads, enabling better traceability
* **Pull Request Information Capture**: Pylynk now captures detailed PR information for enhanced development workflow tracking
* **Improved SBOM Processing**: Streamlined SBOM import and processing workflows

#### 👥 **Identity & Access Management**

* **SAML SSO User Role Selection**: Administrators can now select specific user roles during SAML SSO configuration
* **Default Role Selection**: Enhanced SSO configuration with default role assignment capabilities
* **Auto-register Checkbox**: Improved alignment and functionality in SSO configuration modal

#### 📊 **Enhanced Filtering & Search**

* **Reusable EPSS Filter Component**: Consistent EPSS (Exploit Prediction Scoring System) filtering across the platform
* **Reusable Severity Filter Component**: Standardized severity filtering for better user experience
* **Reusable License Filter Component**: Consistent license filtering functionality
* **Improved Relationship Tree Search**: Enhanced search capabilities in relationship tree views

***

### 🔧 Major Improvements

#### ⚡ **Performance Optimizations**

* **Optimized GetPartPolicies Query**: Significantly reduced payload size for faster policy loading
* **Streamlined Check Filter Queries**: Removed unused fields to improve query performance
* **Enhanced Product Data Queries**: Optimized by removing unnecessary stats and metrics
* **Improved Check Results Queries**: Created specialized optimized queries for author modals
* **Reduced Redundant Queries**: Eliminated unnecessary license queries when LicenseParts are hidden

#### 💡 **User Interface Enhancements**

* **Chart Legend Interactivity**: Mouse hover effects on chart legends with opacity changes
* **Enhanced Profile Compliance Checks**: Improved component design and functionality
* **Dark Mode Improvements**: Fixed datepicker styling issues in dark mode
* **Improved Navigation**: Enhanced parts navigation and breadcrumb functionality
* **Better Component Icons**: Added default cases for component package icons

#### 🔄 **Workflow Improvements**

* **Nightly Health Checks**: Automated health monitoring for organization integrations
* **Bitbucket Connection Health Checks**: Proactive monitoring of Bitbucket integrations
* **Improved Primary Component Handling**: Better confirmation workflows and error handling

***

### 🐛 Bug Fixes

#### 🔒 **Critical Fixes**

* **Fixed Organization Switching**: Resolved E2E test locator issues for organization switching
* **Package Override Operations**: Fixed create and update E2E test locators
* **Attribution Export Data Loss Prevention**: Excluded search filters from attribution exports to prevent data loss
* **Primary Component Update Error**: Fixed errors when no component is selected during updates

#### 🎯 **UI/UX Fixes**

* **Vulnerability Chart Labels**: Fixed label overlap issues in product progress overview PDF exports
* **Pagination Overlap**: Resolved overlap issues in license import tables
* **Modal UI Crashes**: Fixed crashes in checks modal due to variable access before initialization
* **Bulk Update Issues**: Resolved bulk update problems for support status
* **Version Breadcrumb Issues**: Fixed breadcrumb problems on check primary component pages

#### 🔧 **Functional Fixes**

* **Vulnerability Scanning**: Fixed polling issues after vulnerability scan completion in parts
* **Global VEX Updates**: Resolved refetch issues on global VEX updates
* **Project Switching**: Fixed project switch functionality triggered via breadcrumbs
* **Vulnerability Parts Filter**: Corrected filter logic for vulnerability parts
* **EPSS Column Display**: Fixed EPSS column issues in global vulnerability table

#### 🧹 **Code Quality Improvements**

* **Removed Unused Code**: Cleaned up unused queries, mutations, and state logic from SBOM actions
* **Component Refactoring**: Improved SbomDetails component for better readability and maintainability
* **Optimized State Usage**: Reduced unnecessary state usage for SBOM action buttons
* **Enhanced Component Structure**: Refactored organization feeds and package tabs components

***

### 🔄 **System Updates**

#### 🛠️ **Backend Improvements**

* **Disabled TicketSync Job**: Temporarily disabled for system stability improvements
* **JIRA Integration Refactoring**: Updated JIRA defaults to use ExternalIssueTrackerSettings
* **Apollo Error Restrictions**: Limited Apollo error reporting in staging environment
* **Enhanced Error Handling**: Improved error handling across various components

#### 📊 **Data Management**

* **Default Graph Settings**: Set default graphs for all subscription tiers
* **Policy and Automation Rules**: Updated action handling for policy and automation rules
* **Version Expand View**: Added additional fields to version expand view for better information display

***

### 🎯 **Developer Experience**

#### 🧪 **Testing Improvements**

* **E2E Test Optimization**: Fixed intermittent E2E test failures and optimized test cases
* **Better Test Locators**: Improved test locators for more reliable automated testing

#### 📝 **Code Organization**

* **Component Modularity**: Enhanced component structure for better maintainability
* **Query Optimization**: Streamlined GraphQL queries for better performance
* **State Management**: Improved state management patterns across the application

***

###

## v3.4.7

August 7th 2025

***

### ✨ Release Highlights

This release brings improvements to SBOM management, enhanced user experience across the platform, and major accessibility upgrades. We've focused on performance optimizations, UI consistency, and expanding our GraphQL capabilities.

### 🆕 New Features

#### 🔍 Enhanced SBOM Querying

* **GraphQL Enhancement**: Added new `part_of` query type to efficiently search SBOMs containing specific parts
* **SBOM Navigation**: New ability to navigate up the hierarchy from parts SBOM, improving workflow efficiency
* **Version Switching**: Added support for switching versions of associated parts with improved API integration

#### 🎯 Improved Component Management

* **Unified Display**: Combined component name and version into a single column for better readability
* **Package Consolidation**: Unified package name and version display across all tables
* **Enhanced Overview**: Improved SBOM parts overview cards with better visual design

#### ♿ Accessibility Improvements

* **Keyboard Navigation**: Enhanced LynkSelect component with better keyboard accessibility and navigation controls
* **Component Migration**: Migrated multiple UI components to the new LynkAsyncSelect for consistent accessibility
* **Dark Mode**: Unified keyboard and mouse hover effects for improved dark mode experience

### 🔧 User Experience Enhancements

#### 📊 Table & Filter Improvements

* **Sorting Capabilities**: Enabled sorting for required columns in global license tables
* **Filter Standardization**: Standardized filter order across all tables
* **Status Filtering**: Fixed status filter functionality in SBOM request tables
* **Date Input**: Restricted typing in date fields to prevent invalid entries

#### 🎨 UI & Performance Updates

* **Tab Performance**: Improved product tab switching performance with optimized UI updates
* **Modal Layouts**: Resolved layout issues in patch manager and policy modals
* **Column Previews**: Updated column preview functionality in customer license and SBOM license tables
* **Loading Optimization**: Optimized component support level queries by removing unused fields

#### 📋 Policy & Automation

* **Policy Conditions**: Fixed policy condition fields and total count calculations
* **Rule Management**: Resolved sorting issues in organization rules table
* **Automation Rules**: Fixed automation rule view issues from SBOM checks table

### 🐛 Bug Fixes

#### 🔒 Security & Data Integrity

* **Vulnerability Sorting**: Fixed vulnerability name sorting functionality
* **EPSS Updates**: Prevented updates with blank EPSS values to maintain data quality
* **License Logic**: Corrected concluded license column logic on license tabs

#### 🔄 Authentication & Permissions

* **Auth Flow Cleanup**: Removed redundant v1 authentication flow code
* **Role Restrictions**: Removed health recheck trigger on SBOM download for viewer roles
* **Project Selection**: Auto-select current project in vulnerability import forms

#### 🖥️ UI Component Fixes

* **Icon Display**: Fixed icon display issues in edit concluded license modals
* **Border Issues**: Corrected incorrect bottom borders on selected enclosed variant tabs
* **Scroll Problems**: Resolved scroll issues on support status updates
* **Form Validation**: Enhanced organization drawer and registration modal validation logic

#### 📄 Report Generation

* **PDF/HTML Rendering**: Fixed data rendering issues for attribution reports
* **Markdown Support**: Added markdown preview functionality in license expand sections

### 🔨 Technical Improvements

#### ⚡ Performance Optimizations

* **Query Efficiency**: Optimized SBOM health recheck functions
* **Table State Management**: Reset table state to default on product changes
* **Form State**: Improved form state optimization across organization modals

***

##

## v3.4.5

July 31st 2025

***

### ✨ Release Highlights

This release brings significant improvements to license management, enhanced role-based access controls, and major optimizations across the platform. Key highlights include a completely revamped License Attribution UI, improved SBOM processing performance, and enhanced security with internal component redaction capabilities.

### 🆕 New Features

#### 📋 New License Management

* **New License Attribution UI**: Complete replacement of the legacy License Tab with a modern, intuitive License Attribution interface
* **License Import Wizard**: Streamlined process for importing license expiration data
* **License Resolution Jobs**: Background processing for automatic license resolution with manual trigger capability
* **Enhanced License Display**: Improved readability with "read more" toggle for lengthy license texts

#### 🔐 Enhanced Security & Access Control

* **Internal Component Redaction**: New capability to redact sensitive internal components in SBOM exports
* **Role-based Restrictions**: Comprehensive viewer role limitations across attribution tables, package-level actions, and bulk operations
* **Free Tier Controls**: Targeted feature restrictions for free tier users including parts filtering and attribution features

#### 🔍 Advanced Filtering & Search

* **Part ID Filtering**: New filtering capabilities across SBOM vulnerabilities, components, and support level queries
* **Attribution API Enhancements**: Added status column and filtering capabilities
* **ShareLynk Integration**: Enhanced sharing capabilities for attribution data
* **Display Name Filters**: Improved part filtering with display name support

#### 📊 Performance & Optimization

* **SBOM Load Optimizations**: Significant performance improvements for SBOM processing
* **Query Optimization**: Separated base and expanded queries for vulnerability tables
* **API Overhead Reduction**: Streamlined automation rule creation process

### 🐛 Bug Fixes

#### 🔧 Core Platform Fixes

* Fixed authorize view crashes for attribution types
* Resolved policy deletion issues when policy scans are in progress
* Fixed VEX vulnerability copy functionality
* Corrected EPSS scoring issues
* Fixed vulnerability ID sorting problems
* Resolved license type filter issues in components tab

#### 🎨 UI/UX Improvements

* Fixed checkbox wrapping issues causing unintended toggles
* Corrected checkbox width in SBOM duplicate modal
* Resolved broken vulnerability source links
* Fixed license view modal display issues
* Improved alignment in SBOM details cards
* Enhanced authentication layout for smaller viewports

#### 📋 Data & Filtering Fixes

* Fixed visibility filter issues for internal components
* Resolved custom license creation problems
* Corrected vulnerability status reporting from parts
* Fixed missing component names in edit patch modals
* Resolved vulnerability sorting behavioral issues

#### 🔄 Workflow Enhancements

* Fixed E2E test execution with fail-fast locator access
* Improved breadcrumb dropdown width handling
* Enhanced error feedback for password reset failures
* Fixed UI breaking issues in CVSS modal expansions

### 🛠️ Technical Improvements

#### 🏗️ Code Quality & Structure

* Refactored compliance update modal for better maintainability
* Improved CBOM code structure and organization
* Optimized version columns component logic
* Enhanced latest imports component performance
* Streamlined vulnerability link drawer component

#### 🧪 Testing & Reliability

* Wrapped all locator accesses with fail-safe execution patterns
* Fixed multiple E2E test failures with targeted enhancements
* Improved test reliability across various components

#### 🔧 API & Backend Enhancements

* Added component support level ID tracking
* Enhanced AttributionsResolver and ComponentSupportLevelResolver filtering
* Improved vulnerability information processing
* Optimized license attribution update operations

### 📈 Performance Metrics

* **SBOM Processing**: Up to 40% faster load times
* **API Response**: Reduced overhead in automation rule creation
* **UI Rendering**: Optimized table components for better performance
* **Query Efficiency**: Separated queries reduce unnecessary data loading

### 🎯 User Experience Enhancements

* **Simplified License Management**: New UI reduces complexity while adding powerful features
* **Better Visual Feedback**: Enhanced error messages and status indicators
* **Improved Navigation**: Better breadcrumb handling and dropdown sizing
* **Mobile Responsiveness**: Authentication layout improvements for smaller screens

***

## v3.4.2

July 24th 2025

***

### ✨ Release Highlights

This release focuses on **performance optimization** and **user experience improvements** across the platform. We've significantly reduced API calls throughout the application, resulting in faster load times and improved responsiveness. Additionally, we've enhanced security features and resolved critical accessibility issues.

### 🆕 New Features

#### 🔒 Enhanced Security & Access Control

* **Restricted View Implementation**: Added comprehensive access denial scenarios handling to improve security posture
* **SSO Tier Management**: Removed SSO access from free tier to better align with enterprise security requirements

#### 📋 Policy & Compliance Enhancements

* **Component Risk Conditions**: New PolicyRule creation capability for advanced component risk management
* **SBOM Lifecycle Management**: Disabled activities for end-of-life and end-of-support SBOMs to maintain data integrity

#### 🔗 Attribution & Licensing

* **Declared License Support**: Added `declaredLicense` field to attribution API for comprehensive license tracking
* **License Import Improvements**: Enhanced license import functionality with better error handling

#### 📊 Data Management

* **PURL Integration**: Updated query mechanisms to include Package URL (PURL) for better component identification
* **Migration Support**: Added backfill migration for `declared_licenses_exp` field in components

### 🛠️ Bug Fixes

#### 🎯 Critical Fixes

* 🐛 **SBOM Vulnerabilities**: Resolved order bugs in SBOM vulnerabilities resolver
* 🐛 **Application Stability**: Fixed critical application crashes
* 🐛 **Organization Settings**: Resolved empty organization settings with fallback UI implementation

#### ♿ Accessibility Improvements

* ✅ **Patch Delete Button**: Fixed accessibility issues for better screen reader support
* ✅ **Navigation**: Resolved drawer close functionality issues
* ✅ **User Status Display**: Fixed text visibility issues in user status indicators

#### 🔧 User Interface Enhancements

* ✅ **Vulnerability Import**: Resolved close action issues in vulnerability import wizard
* ✅ **Component Relationships**: Fixed missing version information in component relationship view
* ✅ **Search Functionality**: Fixed package search reset behavior on clear action
* ✅ **License Display**: Improved license attributes column and expand view functionality

#### 📱 User Experience Improvements

* ✅ **Form Validation**: Added URL validation in license edit modal
* ✅ **Confirmation Dialogs**: Added confirmation modal before deleting package overrides
* ✅ **Theme Management**: Dynamic display of all theme colors on colors page
* ✅ **Navigation Links**: Component link values now render as navigable URLs
* ✅ **Form Layout**: Improved field alignment in automation rule creation forms

### ⚡ Performance Optimizations

#### 🚀 API Call Reductions

Our engineering team has implemented significant performance improvements by reducing redundant API calls:

* **Component Patch Updates**: Reduced from 27 → 1 API calls
* **Custom Vulnerability Creation**: Reduced from 9 → 1 API calls
* **Organization Rules Update**: Reduced from 6 → 1 API calls
* **User Role Updates**: Reduced from 6 → 1 API calls
* **Applicable Compliance Updates**: Reduced from 7 → 2 API calls
* **SBOM Policy Scan**: Reduced from 24 → 1 API calls
* **Crypto Property Updates**: Reduced from 27 → 1 API calls

#### 🔧 Code Optimization

* ✅ **Component Modularity**: Separated cryptoData query from component query for better performance
* ✅ **Code Cleanup**: Removed unused components and repeated styling
* ✅ **Query Optimization**: Improved CBOM analysis data queries to prevent over-fetching
* ✅ **Connection Updates**: Optimized connection update functions for better response times

### 🧹 Code Quality Improvements

* **Component Refactoring**: Enhanced component expand view and cryptography drawer components
* **URL Formatting**: Centralized URL formatting logic into reusable utility functions
* **Search Logic**: Improved search filter preview and usage validation
* **Form Management**: Refactored edit cryptography and CBOM analysis components

***

## v3.4.1

July 17th 2025

***

### ✨ Highlights

* Azure AD Single Sign-On support for seamless enterprise authentication
* Component Health Status Filtering to quickly isolate critical issues
* Support for Custom License Strings in attribution reports (HTML + PDF)
* Apply policy selectively to direct dependencies only
* Improved license interpretation settings with support for custom and inferred licenses
* Optimized SBOM request functions — API calls reduced from 6 ➡️ 1
* Dozens of bug fixes, E2E test improvements, and UX consistency tweaks

***

### 🌟 New Features

* Component Health Status Filtering\
  Easily filter components by health status in the SBOM view
* Azure AD Single Sign-On Integration\
  Enterprise SSO just got easier
* Custom License String Support\
  Parsed and rendered in attribution PDFs & HTML
* Settings to Control License Interpretation\
  Choose how license lists are inferred or enforced
* Apply Policies to Direct Dependencies Only\
  Greater control over compliance scope
* Organization Name in Notification Emails\
  Clearer context for multi-org users
* SBOM Part Logs & Deletion Support\
  Operational visibility and control on part-level artifacts

***

### 🐞 Bug Fixes & Improvements

* License attribution search improvements
* Drawer overflow fixes and alignment issues for long product names
* CVE entries now correctly link to NVD only
* VEX updates work reliably for SBOM parts
* Global search reflects latest data after product changes
* Component edit and insights drawers now work as expected
* SAML users now correctly associated with existing organizations
* Fixed crash when viewing certain SBOM part combinations
* UI consistency improvements across components, licenses, patches, and modals
* Enhanced stability of E2E tests, including organization switching and SBOM workflows

***

### 🧰 Developer & Platform Updates

* Reduced SBOM request API calls (from 6 → 1)
* Optimized health status filter queries for speed
* Introduced ecosystem metadata field to component model
* Improved component and vulnerability edit experiences
* Cleaned up policy terms and improved accessibility
* Refactored CVE ID update logic for background jobs
* Better reliability in Playwright-based tests

***

### 🗑️ Deprecations & Changes

* Package Feature Removed from Free Tier

***

## v3.3.9

July 10th 2025

***

### ✨ Release Highlights

This release brings significant improvements to vulnerability management, enhanced authentication capabilities, and substantial performance optimizations across the platform. Key highlights include Alpha Azure SAML SSO support, CBOM Visualizations & Editing , EPSS for OSV and major UI/UX enhancements.

### 🆕 New Features

#### 🔐 Authentication & Security

* **Azure SAML SSO Support** - Added comprehensive support for Azure SAML Single Sign-On integration
* **Enhanced Security Token Management** - Refactored security token table into modular components for better maintainability

#### 📊 Vulnerability Management

* **EPSS Integration** - Enhanced EPSS (Exploit Prediction Scoring System) support for OSV vulnerabilities
* **Advanced Filtering & Sorting** - Implemented comprehensive filters and sorting capabilities across all organizations
* **Environment-Based Filtering** - Added environment filtering for vulnerability counts on the vulnerability page
* **Global Search Functionality** - Introduced powerful search capabilities across the platform

#### 📈 Reporting & Analytics

* **Compliance Dashboard Cards** - Added new compliance cards to the main dashboard
* **Attribution HTML Export** - Improved layout and styling for attribution HTML export pages

#### 🔍 Component Management

* **CBOM Cryptography Editing** - Implemented comprehensive CBOM (Cryptographic Bill of Materials) edit functionality
* **Async Component Loading** - Enhanced component lists with lazy loading and async dropdowns for better performance
* **License Text Import** - Added capability to import and manage license text data

### 🐛 Bug Fixes

#### 🔧 Core Platform Fixes

* **SBOM Upload Issues** - Resolved various SBOM (Software Bill of Materials) upload errors and reliability issues
* **CPE and PURL Parsing** - Fixed critical parsing issues with Common Platform Enumeration and Package URL formats
* **Component Support Level** - Corrected component support level calculation and display
* **Authentication Context** - Fixed unauthenticated operations with proper current\_user context

#### 🎨 UI/UX Improvements

* **Modal Scroll Handling** - Fixed modal scroll behavior for large content areas
* **External Link Icons** - Resolved missing external link icons when vulnerability source is NVD
* **Breadcrumb Navigation** - Fixed incorrect breadcrumb behavior on KBar navigation from Global Vulnerability page
* **Long Name Truncation** - Implemented proper truncation for long project group names across the application
* **EPSS Column Display** - Fixed EPSS column rendering issues in vulnerability tables

#### 📱 Frontend Optimizations

* **Component Creation Optimization** - Reduced API calls from 25 to 7 for component creation operations
* **Table Refactoring** - Refactored users, requests, and organization tables for better performance
* **Modal State Management** - Improved modal state handling and component organization
* **E2E Test Stability** - Resolved multiple failing end-to-end tests across various workflows

#### 🔄 Backend Improvements

* **Global Package Manager Optimization** - Enhanced performance of global package manager operations
* **AppSignal Error Reporting** - Implemented comprehensive error reporting and monitoring
* **Deployment Workflow Updates** - Improved staging deployment processes with S3 build upload optimization

### 🧪 Testing & Quality Assurance

* **Enhanced E2E Test Coverage** - Fixed and improved end-to-end tests for SBOM, components, security tokens, and organization workflows
* **Conditional Data Fetching** - Implemented smart data fetching on table refresh operations
* **Test Reliability Improvements** - Resolved failing tests in package, security token, and component workflows

### 🏗️ Infrastructure & DevOps

* **S3 Build Upload Optimization** - Updated staging deployment workflow for improved build management
* **Source Map Removal** - Enhanced staging deploy workflow to exclude source maps for security
* **Error Monitoring Integration** - Added comprehensive AppSignal error reporting and issue tracking

## v3.3.6

July 3rd 2025

***

## Highlights ✨

This release brings significant improvements to performance, security, and user experience across the Interlynk Platform. We've focused on optimizing key workflows, enhancing SBOM management capabilities, and streamlining the user interface for better productivity.

**Key Improvements:**

* 🔧 Major refactoring of API authentication flows for enhanced security
* ⚡ Comprehensive query optimization reducing load times across the platform
* 🛠️ Enhanced SBOM management with improved upload and processing capabilities
* 🎨 UI/UX improvements for better user experience and accessibility
* 📊 Advanced filtering and search capabilities for components and vulnerabilities

### New Features 🌟

#### Authentication & Security Enhancements

* **🔐 Refactored API Key Flow**: Complete overhaul of API key management and GraphQL controllers for improved security
* **🛡️ Enhanced OAuth Flow**: Streamlined OAuth authentication with better error handling
* **🔒 Conditional Authorization**: Updated authorization checks with conditional organization permissions
* **🌐 Unauthenticated Operations**: Added support for whitelisted queries without authentication requirements

#### SBOM Management

* **📦 CBOM Support**: New support for Cryptographic Bill of Materials (CBOM) functionality
* **📤 Improved SBOM Upload**: Enhanced upload process with better error handling and validation
* **🔄 Draft SBOM Handling**: Improved management of draft SBOMs with conditional actions and logging
* **🚫 System Log Protection**: Prevented unauthorized access to system logs on draft SBOMs

#### Component & Vulnerability Management

* **🏷️ NVD Alias Integration**: Added NVD alias ID to vulnerability table columns for better identification
* **📋 Component Metadata**: Enhanced component metadata handling in attribution reports
* **🔍 Advanced Filtering**: Implemented license value filtering in attribution table filters
* **⚡ Patch Management**: Added patch edit options in component action menus

#### User Interface Improvements

* **📊 Custom Vulnerability Table**: Refactored vulnerability tables for improved performance
* **🎯 Column Width Optimization**: Adjusted column widths in global vulnerability tables for better visibility
* **🔧 Internal Component Modal**: Enhanced internal component modal interface
* **📈 Project Support Table**: Modular refactoring of project support tables

### Performance Optimizations ⚡

#### Query Optimization

* **🚀 GetProjectGroups Query**: Optimized queries for create parts modal, compare component tools, and import wizard
* **📊 SBOM Licenses Table**: Removed unused fields from license table queries and CSV exports
* **⏱️ Resolution Metrics**: Optimized queries for resolution age, velocity, and patch velocity
* **📝 Policy Results**: Streamlined policy results queries by removing unnecessary fields
* **📋 Changelog Queries**: Optimized changelog queries for better performance
* **🔄 Project Automations**: Enhanced project automation queries with field optimization

#### Frontend Performance

* **⚡ SBOM Build Optimization**: Improved SBOM build processes for faster loading
* **🔄 Gradual Polling**: Fixed gradual polling issues on versions column for draft SBOMs
* **📊 Custom Field Updates**: Optimized custom field update operations
* **🔍 Version Visibility**: Enhanced version display with truncation and tooltip improvements

### Bug Fixes 🐛

#### Authentication & Permissions

* **🔧 OAuth2 Flow**: Fixed critical issues with OAuth2 authentication flow
* **👥 User Permissions**: Resolved edit connection permissions at user level
* **📧 Invite System**: Fixed resend invite functionality that was triggering invalid email errors
* **🔐 Reset Password**: Corrected issues with password reset page functionality

#### SBOM Management

* **📤 SBOM Upload**: Fixed various SBOM upload issues and validation problems
* **🔄 SBOM Activity Logging**: Prevented unnecessary activity logging for draft SBOMs
* **🔄 SBOM Refetch**: Fixed SBOM update refetch issues
* **📊 SBOM Check Actions**: Prevented SBOM check actions from appearing in draft mode

#### Component & Vulnerability Management

* **🔄 Policy Rescan**: Fixed policy rescan bug affecting component updates
* **⚠️ Violation Reset**: Fixed bug preventing violation reset when components are updated to internal
* **🔍 Component Creation**: Resolved refetch issues on component creation
* **📋 Component Metadata**: Fixed rendering of empty component metadata fields in attribution exports
* **🔗 Package Lookup**: Fixed package lookup functionality in add component modal

#### User Interface Fixes

* **🍞 Version Breadcrumb**: Fixed breadcrumb updates when changing primary components
* **🔍 Project Group Search**: Resolved search functionality issues in customer view
* **📊 Component Column Sorting**: Fixed sorting issues in vulnerability tab component columns
* **🔔 Notification Bell**: Fixed layout issues with notification bell icon
* **🔗 Vulnerability Links**: Fixed NVD link functionality in vulnerability details
* **📊 Vulnerability Status**: Fixed status field indicators in vulnerability displays
* **📋 Component Table Preview**: Enhanced handling of empty fields in component table previews

#### Testing & Quality Assurance

* **🧪 E2E Tests**: Fixed product E2E test issues and add product button locators
* **📊 Attribution Data**: Resolved missing licenses in attribution data queries
* **🔍 Version Table Actions**: Fixed conditional display of version table actions based on lifecycle status

### Technical Improvements 🔧

#### Code Quality

* **🧹 Component Cleanup**: Removed unused components and optimized codebase
* **🎨 Icon Consistency**: Cleaned up inconsistent icons across the platform
* **📝 Copyright Update**: Updated copyright year to 2025
* **🔧 Modal Refactoring**: Enhanced attribution license modal with full license text display

#### Attribution & Licensing

* **📄 Attribution PDF**: Improved PDF rendering by omitting empty fields in component metadata
* **📝 License Management**: Enhanced license edit modal with read-only fields and copy functionality
* **🔍 License Filtering**: Implemented comprehensive license type and value filtering in components table

#### Development Experience

* **🔧 Sharelynk Dashboard**: Removed version search step from dashboard tour for streamlined experience
* **⚙️ Manufacturer Updates**: Optimized organization manufacturer update processes
* **📊 Vulnerability Metrics**: Updated vulnerability metrics request handling

## v3.3.4

June 26th 2025

***

### ✨ Highlights

This release brings significant performance improvements, enhanced authentication capabilities, and a more streamlined user experience across the platform. We've focused on optimizing key queries, refining the SBOM workflow, and improving component management features.

***

### 🆕 New Features

🔐 SBOM Formats & Import & Exports

* CycloneDX 1.6 fully supported.
* CycloneDX and SPDX Annotations Import & Exports now supported.
* CycloneDX Pedigree for patches Import & Export now supported.

#### 🔐 Enhanced Authentication System

* **Refactored JWT-based authentication flow** with improved security and performance
* **V2 authentication flow** now enabled across staging and production environments
* **Enhanced share user authentication** with refined JWT handling

#### 📊 Attribution Report Enhancements

* **Patch management support** in attribution reports with comprehensive patch data export
* **Visual indicators for license differences** in SBOM Attribution Table
* **Enhanced filtering capabilities** for empty and unresolved licenses in attribution report exports
* **Selected item indicators** to improve user visibility in attribution reports

#### 🎯 Component Management Improvements

* **Component metadata handling** with automatic add/update when global data is missing
* **Enhanced component identifier fields** for better component tracking
* **Improved component visibility filters** with required feature integration
* **Support level streamlining** for component management

#### 📋 SBOM Workflow Enhancements

* **SBOM draft functionality** now available in free tier plans
* **Improved SBOM duplicate modal** with updated interface
* **Enhanced SBOM general tab** with better organization
* **Streamlined SBOM progress bar preview** for better user experience

#### 🔍 Search and Navigation

* **Search functionality** added to organization selector dropdown
* **Sorting capabilities** by project version in version tables
* **Improved breadcrumb consistency** across product and component updates

***

### 🛠️ Improvements

#### ⚡ Performance Optimizations

* **Massive query optimization initiative** across multiple platform areas:
  * Health score update optimization
  * Users query optimization for CSV export
  * API keys query optimization
  * Latest versions query performance improvement
  * Organization rules query optimization
  * Permissions query enhancement
  * Dashboard imports table performance boost
  * SBOM versions table load time improvement with lazy loading

#### 🎨 User Interface Enhancements

* **Accessibility warnings removal** for better compliance
* **Layout consistency updates** in latest import tables
* **Progress overview card improvements**
* **Product label filter and list drawer refactoring**
* **Global license table enhancements**
* **Component vulnerabilities table improvements**
* **Health score details view updates**

#### 📄 License and Compliance

* **Standardized license filters** across attribution API and components API
* **Improved license expression formatting** for proper display
* **Enhanced license type filter display strings**

***

### 🐛 Bug Fixes

#### 🔧 Core Platform Fixes

* **Fixed metrics collection issues** across live and standard metrics
* **Resolved assembly relations problems**
* **Fixed Global Package View** to properly display all unique components scoped to organization
* **Corrected data migration issues**
* **Fixed ID generation bugs**
* **Resolved component types handling**

#### 🎯 User Interface Fixes

* **Fixed refetch issues** on product updates and primary component checks
* **Resolved loading issues** on policy submission
* **Fixed external link preview** in component and vulnerability tables
* **Corrected breadcrumb inconsistencies** on product and component updates
* **Fixed SBOM download issues** in customer view
* **Resolved vulnerability status typos** ("not affected")

#### 📊 Attribution and Components

* **Fixed bugs** on attribution page
* **Resolved global package manager query bugs**
* **Fixed component visibility and filtering issues**
* **Corrected vulnerability run status visibility**
* **Added gradual polling** for SBOM metrics

#### 🔐 Security and Access

* **Removed custom vulnerabilities** when associated with PURL or CPE
* **Fixed share user JWT authentication flow**
* **Resolved permission and access control issues**

***

### 🔧 Technical Improvements

#### 🏗️ Infrastructure Updates

* **Updated deployment configurations** with new git access tokens
* **Staticized staging docker compose file** for better consistency
* **Environment variable updates** for V2 authentication flow

#### 📡 API Enhancements

* **Refactored AttributionsFinder** with improved filtering capabilities
* **Enhanced notifications** for all severity levels
* **Improved package manager performance** across the platform

#### 🎛️ Configuration Management

* **Default configuration handling** for V2 authentication flow
* **Project settings optimization** with minimal vulnerability scanning queries
* **Enhanced lifestage modal** with project name and version details

## v3.3.2

June 19th 2025

***

### ✨ Release Highlights

This release focuses on **attribution filters, sbom duplication and bug-fixes** across the platform. We've significantly optimized query performance, introduced new attribution APIs, and resolved critical bugs to deliver a more reliable and efficient platform.

***

### 🆕 New Features

#### 📊 Attribution API Integration

* **License and Component Attribution Management**: New comprehensive API for managing license and component attributions
* **Enhanced Attribution Reports**: Improved PDF and HTML export layouts with better font styling and formatting
* **Attribution Report Optimization**: Better layout design using Arial font and enhanced styling for professional documentation

#### 🔄 SBOM Management Enhancements

* **SBOM Duplication**: Added ability to duplicate manually built SBOMs with editing capabilities
* **Semantic Version Sorting**: Implemented proper semantic versioning for SBOM sorting and organization
* **Product Lifecycle Filtering**: Enhanced SBOM count filtering by product lifecycle stages
* **Draft Mode Improvements**: Updated SBOM draft mode preview with new changes and prevented downloads in draft state

#### 📈 Performance Optimizations

* **Query Performance**: Massive improvements across vulnerability, component, and user permission queries
* **API Call Reduction**: Optimized refetch logic and minimized unnecessary API calls throughout the platform
* **Database Optimization**: Enhanced query performance for product vulnerability tables and customer views

***

### 🛠 Improvements

#### 💡 User Interface Enhancements

* **Table Consistency**: Ensured consistent layout across all platform tables
* **Column Updates**: Added status columns to version tables and updated parts table columns
* **CVSS Display**: Fixed CVSS cards to properly display missing vector values
* **Vulnerability Information**: Enhanced vulnerability info section display

#### 🔧 System Optimizations

* **Refetch Logic**: Optimized refetch mechanisms for primary component, automation, policy, and project updates
* **ShareLynk Drawer**: Refactored and improved ShareLynk drawer functionality
* **Package Management**: Streamlined package update flow to minimize API requests
* **Global Updates**: Optimized global support and license update processes

#### 📱 User Experience

* **Email Configuration**: Resolved email configuration integration issues
* **Customer View**: Removed unnecessary status columns and API calls from customer views
* **Search Performance**: Optimized kbar query by removing unwanted fields
* **Role Management**: Improved create role modal performance and optimized role queries

***

### 🐛 Bug Fixes

#### 🔧 Critical Fixes

* **Slack Notifier**: Fixed `NoMethodError` for undefined method 'msg' in `Notifier::Slack`
* **Attribution System**: Resolved attribution connection issues and crashes
* **Email Integration**: Fixed email configuration integration problems
* **Refetch Issues**: Resolved refetch problems during component updates and SBOM lifecycle changes

#### 🛡 Stability Improvements

* **Duplicate Definition**: Fixed duplicate method definition issues
* **Semver Sorting**: Corrected semantic version sorting functionality
* **JIRA Integration**: Fixed E2E test issues with JIRA integration
* **Product Status**: Resolved refetch issues on product status updates

#### 🎯 Minor Fixes

* **Typos and Display**: Corrected various typos and improved display strings
* **Code Cleanup**: Refactored compliance checks component and removed redundant props
* **Lifecycle Filters**: Fixed lifecycle stage filter preview functionality

***

## v3.3.1

June 12th 2025

***

### 🚀 Release Highlights

This release focuses on **SBOM management improvements**, **performance optimizations**, and **enhanced user experience** across the platform. Key highlights include the introduction of SBOM draft mode, Automatic Parts Syn&#x63;**,** significant performance improvements for component queries, and streamlined PDF export functionality.

### ✨ New Features

#### SBOM Draft Mode

* **Draft Lifecycle Management**: Introduced a new 'draft' lifecycle state for SBOMs, allowing users to work on SBOM development before finalizing
* **Enhanced Preview Experience**: Improved visual feedback and preview capabilities for draft mode SBOMs
* **Conditional JIRA Sync**: Added conditional preview for JIRA sync actions to better manage integration workflows

### 🔧 Performance Improvements

#### Query Optimization

* **Component Tab Performance**: Optimized component tab queries for significantly better performance
* **Vulnerability Exports**: Added optimized vulnerability queries for both CSV and global exports
* **Cache-First Policy**: Implemented cache-first policy for SBOM components expanded fetching to reduce load times
* **Reduced API Calls**: Minimized redundant API requests during component updates and SBOM update flows

#### SBOM Management

* **Automatic Parts Sync**: Added automatic SBOM parts synchronization across projects for improved consistency
* **Streamlined Update Flow**: Optimized SBOM update process to trigger only required API calls

### 🐛 Bug Fixes

#### Access Control & Security

* **Access Control Issues**: Resolved critical access control bugs affecting user permissions
* **Permission Normalization**: Normalized permission names for consistency across the platform
* **User Authentication**: Fixed NoMethodError for ShareUser#generate\_jwt functionality

#### SBOM Operations

* **Upload Modal**: Refactored and fixed multiple issues with SBOM upload modal functionality
* **Summary Card Logic**: Fixed description preview logic in SBOM summary cards
* **Loader Issues**: Resolved SBOM upload loader display problems
* **Build Refetch**: Fixed SBOM build refetch functionality after updates
* **Delete Refetch**: Corrected refetch behavior after SBOM deletion

#### PDF Export Improvements

* **Layout Fixes**: Corrected layout misalignment issues in SBOM PDF exports
* **Vulnerability Status**: Fixed vulnerability status display in SBOM PDF exports
* **Attribution Page**: Updated both PDF and HTML export template layouts for attribution pages

#### Component Management

* **Component Details**: Enhanced component details card functionality
* **Support Modal**: Updated component support modal preview based on resolved checks
* **Query Optimization**: Fixed component query requests during component edits
* **UI Cleanup**: Removed OpenSSF scorecard field from component UI for cleaner interface

#### Policy & Project Management

* **Global Policy Layout**: Improved global policy table layout to prevent overlap issues
* **Project Settings**: Updated project settings with latest parts check functionality
* **Policy Pages**: Added excluded column to product and version policy pages
* **Project Deletion**: Fixed critical project deletion functionality

#### Automation & Validation

* **Component Checks**: Fixed NoMethodError when automation component checks encounter nil values
* **Support Level Validation**: Resolved 'Actively Maintained' support level validation errors
* **Priority Determination**: Updated system to skip determining priority from severity when appropriate
* **Organization Issues**: Fixed organization deserialize error

### 🔄 Technical Improvements

* **Modal Refactoring**: Comprehensive refactoring of SBOM upload modal for better maintainability
* **API Efficiency**: Reduced redundant API calls across multiple workflows
* **Error Handling**: Enhanced error handling for edge cases and nil value scenarios
* **Data Consistency**: Improved data synchronization and consistency across projects

## v3.2.9

June 6th 2025

***

### ✨ Highlights

This release brings significant enhancements to the Interlynk Platform with improved performance, new integrations, and enhanced user experience. Key highlights include:

* 🔗 **Linear Issue Tracker Integration** - Seamlessly connect your vulnerability management with Linear
* 📊 **Enhanced SBOM Scanning** - Improved policy, support level, and vulnerability tracking in scan jobs
* 🔔 **Smart Notifications** - Incremental notifications for policy violations and new vulnerabilities
* ⚡ **Performance Optimizations** - Multiple query optimizations for faster data loading across the platform

***

### 🆕 New Features

#### 🎯 Linear Issue Tracker Integration

* Complete Linear integration for streamlined issue tracking
* Support for markdown preview in issue descriptions
* Generic ticket sync functionality for better workflow management

#### 📋 Enhanced SBOM Capabilities

* **SBOM Parts in Scan Jobs**: Now includes comprehensive policy, support level, and vulnerability data
* **Component Data Enhancement**: Extended support for copying additional fields from primary components
* **Improved SBOM Comparison**: Added end-to-end testing for SBOM comparison workflows

#### 🔔 Advanced Notification System

* **Incremental Policy Notifications**: Real-time alerts for policy violations
* **Vulnerability Notifications**: Configurable notification options for new vulnerabilities
* **Smart Filtering**: Enhanced notification management with better targeting

#### 📊 Reporting & Export Improvements

* **Updated Attribution Reports**: New layout for both HTML and PDF export formats
* **Enhanced Export Performance**: Optimized CSV and Excel export functionality
* **Improved Report Styling**: Consistent icon styling and better table formatting

***

### 🐛 Bug Fixes & Improvements

#### 🔧 User Interface Fixes

* ✅ Fixed package license preview display issues
* ✅ Resolved table overflow problems in version columns
* ✅ Fixed overlapping issues in parts overview cards
* ✅ Corrected component expand view functionality
* ✅ Fixed health map view rendering
* ✅ Resolved attribution report dialog issues

#### ⚡ Performance Optimizations

* **Query Optimization**: Streamlined multiple database queries across components
  * Product page labels query optimization
  * HealthMap query field limiting
  * Package versions query optimization
  * Component data query improvements
* **Component Performance**: Enhanced ProductInfo component with optimized state management
* **E2E Test Optimization**: Reduced SBOM components test execution time

#### 🛠️ Backend Improvements

* **Migration Fixes**: Resolved database migration issues
* **Policy Logic**: Fixed policy rescan functionality
* **Data Consistency**: Improved vulnerability data handling and display
* **Component Cards**: Enhanced performance and readability with better query optimization

#### 📱 User Experience Enhancements

* **Table Components**: Consistent styling across all table interfaces
* **Vulnerability Displays**: Improved popover functionality and conditional severity previews
* **Modal Improvements**: Enhanced policy modal and primary component check modal
* **Description Handling**: Better truncation for component descriptions in summary cards

***

### 🔄 Technical Improvements

* **Refactored Components**: Multiple component refactoring for better maintainability
* **Test Coverage**: Enhanced E2E test coverage for critical workflows
* **Code Organization**: Improved code structure for license expanded views
* **Automation Fields**: Updated automation action fields with required changes

## v3.2.8

May 29th 2025

***

### 🌟 Highlights

This release brings significant improvements to JIRA integration, enhanced analytics capabilities, and numerous bug fixes to improve platform stability and user experience. Key highlights include bulk JIRA ticket creation, lifecycle filtering for analytics, and Global Package Version Overrides & Management for Attributions.

### ✨ New Features

#### 🔗 Enhanced JIRA Integration

* **Bulk JIRA Ticket Creation**: Create multiple JIRA tickets at once with improved efficiency and user experience
* **JIRA Sync from Vulnerability Table**: Trigger JIRA synchronization directly from the vulnerability management interface
* **Enhanced JIRA Settings**: Updated fields and sync actions with improved configuration options
* **JIRA Description Field Updates**: Better formatting and content for automatically generated JIRA tickets
* **JIRA Ticket Association Retention**: Maintain ticket associations even when SBOM versions are updated

#### 📊 Analytics & Reporting Improvements

* **Lifecycle Filter for Analytics**: Filter analytics data by product lifecycle stage for better insights
* **Attribution Report Enhancements**: New comprehensive attribution reporting capabilities
* **Enhanced Component Insights**: Improved E2E testing and data retrieval for component analysis

#### 🔧 Platform Enhancements

* **Global Package Version Management**: Enhanced package version listing with override capabilities during attribution report generation
* **Organization Context Sync**: Maintain consistent organization context across multiple browser tabs
* **Component Filter Query Updates**: Dynamic component filters that update based on include\_parts flag

### 🐛 Bug Fixes

#### 🔒 Security & Vulnerability Management

* **Sharelynk Crash Fix**: Resolved critical crash issue on vulnerability page in sharelynk
* **SBOM Vulnerability Query**: Updated to omit retracted entries by default for cleaner results
* **Vulnerability Links Preview**: Fixed parts vulnerability links preview functionality

#### 🖥️ User Interface Improvements

* **Support Status Selection**: Fixed support status selection behavior on tab changes
* **Product Tab Switching**: Resolved onChange handler issues for seamless tab navigation
* **Settings Dropdown**: Fixed dropdown preview behavior on page refresh
* **Policy Violation Drawer**: Updated preview functionality for better user experience
* **Logs Column Preview**: Fixed logs changed by column preview display

#### 📦 Package & Component Management

* **Default Sorting**: Improved default sorting in package version global listing
* **Package Override Modal**: Enhanced UI and code improvements for better usability
* **Attribution Report Bulk Selection**: Fixed bulk source select preference handling
* **License Data Validation**: Enhanced license data validation with better expression handling

#### 🔧 System & Performance Fixes

* **API Optimization**: Removed unnecessary JIRA API calls from customer view for improved performance
* **Bitbucket Integration**: Removed bitbucket from user integrations as part of cleanup
* **Component Filter Updates**: Enhanced component filter query to properly retrieve parts data
* **Error Message Improvements**: Updated error messages for better user understanding
* **CI Fixes**: Resolved failing specs in continuous integration pipeline
* **Field Ordering**: Fixed ordering for updated\_at field across various components

## v3.2.7

May 23rd 2025

***

### Highlights ✨

* **🔧 Enhanced JIRA Integration** - Added environment-level default fields configuration for streamlined workflow management
* **📊 Advanced Dashboard Filtering** - New version lifestage filter support with improved product progress metrics visualization
* **🐛 Resolved Vulnerability Count Issues** - Fixed incorrect vulnerability calculations in dashboard analytics for accurate reporting
* **🎨 Refreshed User Interface** - Updated authentication layout, icons, and product settings for better user experience
* **⚡ Performance Optimizations** - Code refactoring and query optimizations across components for improved platform efficiency

### 🎯 New Features

#### JIRA Integration Enhancements

* **🔧 Environment-Level Default Fields**: Added support for configuring default JIRA fields at the environment level, streamlining issue creation workflows
* **🧪 Enhanced E2E Testing**: Comprehensive end-to-end test coverage for JIRA integration flows

#### Dashboard & Analytics Improvements

* **📊 Version Lifestage Filtering**: New dashboard filter support for version lifestage management
* **📈 Product Progress Metrics**: Restructured and improved product progress overview with better metrics visualization
* **📋 Parts Overview Enhancement**: Enabled parts overview cards across all dashboard tabs

#### Component Management

* **✏️ Enhanced Component Editing**: Added edit functionality for parts components with improved usability
* **🔍 Latest Version Display**: Component tables now display the latest version information for better visibility
* **👁️ Improved Visibility**: Adjusted vulnerability component columns for enhanced readability

#### User Interface Enhancements

* **🎨 Refreshed Authentication Layout**: Updated authentication page design for better user experience
* **📱 Product Automation UI**: Enhanced product automation interface and changelog table presentation
* **🎯 Updated Icons**: Refreshed icon set throughout the platform
* **📄 PDF Layout Optimization**: Improved product progress PDF generation with better layout and structure
* **🔧 Custom Components**: New reusable separator component for consistent UI elements
* **⚙️ Settings Layout**: Updated product settings interface for improved navigation

### 🐛 Bug Fixes

#### Vulnerability Management

* **🔢 Fixed Vulnerability Counts**: Resolved incorrect vulnerability count calculations in dashboard analytics
* **📊 SBOM Vulnerability Status**: Updated vulnerability run status to properly display in-progress state on SBOM pages
* **🔄 Vulnerability Resolution**: Fixed issues with vulnerability resolution workflows

#### Data Import & Processing

* **📋 SPDX Import Fix**: Resolved SPDX import functionality issues
* **📝 SBOM Request Validation**: Fixed SBOM request messaging when product name or version information is missing
* **📅 Lifecycle Modal**: Fixed SBOM lifecycle modal incorrectly saving cleared date values

#### Configuration & Validation

* **✅ Address Validation**: Added proper validation for configuration addresses before form submission
* **🔔 Slack Notifications**: Fixed internal Slack notification delivery issues

#### User Interface Fixes

* **📊 SBOM Comparison**: Updated SBOM comparison UI feedback and conditional rendering logic
* **🧪 E2E Component Tests**: Fixed E2E test reliability for component insights rendering

### 🔧 Technical Improvements

#### Code Quality & Performance

* **🏗️ Code Structure Refactoring**: Improved code structure and readability across multiple components
* **⚡ Query Optimization**: Optimized attribution report queries with improved state management and code reuse
* **🧹 Component Restructuring**: Enhanced component architecture for better maintainability

***

## v3.2.5

May 16th 2025

***

### Highlights ✨

* Attributions Reports \[Alpha Feature]
* Basic Progress Reports
* Notifications for Critical Vulnerabilities
* Jira custom fields Support.

### New Features 🚀

#### SBOM & License Management

* 📊 Added support level metrics to SBOM GraphQL type \[#2239]
* 🔍 Added expression filter to licenses resolver \[#2246]
* 🔄 Implemented fixes for SPDX license import \[#2234]
* 💾 Improved dependency storage with unique deps feature \[#2233]

#### JIRA Integration

* ⚙️ Added support for custom JIRA fields \[#2229]
* 🧩 Implemented custom JIRA fields with UI improvements \[#6323]
* 🛠️ Fixed JIRA component field functionality \[#6362]

#### Analytics & Reporting

* 📈 Implemented Basic analytics reporting \[#6250]
* 📄 Added ability to export attribution reports \[#6329]
* 📊 Improved product progress report PDF export with charts and better layout \[#6357, #6358]
* 🖨️ Enhanced attribution report export with license text \[#6356]

#### System Improvements

* 📝 Added support status scan to change log \[#2240]
* 🔔 Added notice field to component model and mutations \[#2242]
* 📋 Added support scan logging in system logs \[#2243]
* 📝 Added logging for support level field changes \[#2244]
* 📨 Fixed email saving functionality \[#2250]
* 🔄 Added filters to project\_groups field \[#2232]

#### UI Enhancements

* 🎨 Updated product labels card preview \[#6328]
* 🖼️ Updated icons for better visual consistency \[#6270]
* 🧩 Implemented conditional preview logic for part info cards \[#6307]
* 🎯 Updated compliance logo to match consistent design \[#6347]
* 📊 Updated Product Progress UI with fixes and improvements \[#6352]
* 📈 Updated EPSS, CVSS and CWE preview on vulnerability details page \[#6354]

### Bug Fixes 🐛

#### Notifications & Alerts

* 🔔 Fixed notifications not being sent for newly matched vulnerabilities \[#2241]
* ✅ Added validation for Slack and Team webhook URLs \[#6343]
* 🔔 Updated custom toast icons \[#6338]

#### UI & Display Issues

* 🖥️ Fixed incorrect affected products in vulnerability view \[#6325]
* 🔄 Fixed half-circle icon display for unspecified VEX status \[#6335]
* 📊 Fixed version table rendering in customer view \[#6339]
* ✅ Fixed VEX status form validation \[#6337]
* 📏 Adjusted column width for vulnerability status \[#6336]
* 📐 Fixed part info cards alignment \[#6348]
* 🔢 Fixed pagination issue in support status table \[#6363]
* 🏷️ Added None type to severity tag component \[#6365]
* 🔍 Fixed custom vulnerability search function \[#6366]

#### License Management

* 📋 Fixed license list display \[#2249]

### Testing & Quality Improvements 🧪

* ✅ Added E2E test for version lifecycle update flow \[#6340]
* ✅ Fixed SBOM upload E2E test \[#6353]
* 🔄 Refactored JIRA config modal for better performance \[#6324]

## v3.2.2

May 8th 2025

***

### 🌟 Highlights

* **GraphQL Subscriptions**: Added support for GraphQL subscriptions using ActionCable for real-time updates
* **Automation Improvements**: Introduced ability to copy version details from primary components
* **UI Enhancements**: Standardized selection fields with LynkSelect throughout the platform
* **Performance Optimization**: Improved component rendering to avoid unnecessary queries

### 🚀 New Features

#### Component Management

* ✨ Added support to copy version from primary component (#6289)
* 🔄 Setup code for GraphQL subscriptions using ActionCable (#2207)
* 📊 Updated parts overview card with new design changes (#6300)
* 🧩 Replaced scope dropdown with LynkSelect in component details (#6277)

#### User Experience

* 🚀 Standardized selection fields in Product Settings with LynkSelect (#6278)
* 🔗 Added navigation support to product from global vulnerability view (#6318)
* 💾 CSV export now persists selected column configuration with sessionStorage (#6302)

#### Vulnerability Management

* 📝 Added internal notes to vulnerability CSV export (#6290)
* 📊 Included status fields in vulnerability CSV export (#6305)

### 🐛 Bug Fixes

#### UI & Layout

* 🔧 Fixed UI overlap in Add Component Modal (#6282)
* 🔍 Fixed parts tooltip issue in vulnerability table (#6280)
* 🔧 Fixed VEX status layout and UI consistency issues (#6319)
* 🔧 Fixed alignment for icon and status in vulnerability status import (#6322)
* 🔧 Fixed component tree view (#6303)

#### Component Functionality

* 🛠️ Fixed component scope update issue (#6281)
* 🛠️ Fixed CWE list preview (#6291)
* 🛠️ Fixed CWE field preview when data doesn't exist (#6299)
* 🛠️ Disabled Scope Field in Component view for ShareLynk (#6283)

#### ShareLynk

* 🔧 Resolved SBOM components query failure in ShareLynk (#6274)

#### Integrations

* 🔗 Fixed Github connection card (#6316)

#### Data Management

* 🔧 Fixed multiple license submissions with loading state (#6310)
* 🔧 Fixed support CSV export (#6315)

#### Testing

* ✅ Fixed e2e tests for product settings and support status (#6288)
* ✅ Added E2E test for component notes and license status (#6317)

### 🧹 Code Improvements

* 🔄 Modified logic for env based on aidash dev workflow (#2231)
* 🧹 Removed duplicate utility functions (#6273)
* 🧹 Component Notes Logic Cleanup (#6279)
* 🧹 Removed supplier details from parts table (#6298)
* 🧹 Conditionally render ProductGraphs to avoid unnecessary queries (#6272)

###

## v3.2.1

May 2th 2025

***

### ✨ Highlights

* **Enhanced Webhook Functionality**: Added PullRequestCreated and PullRequestUpdated triggers to expand integration capabilities
* **Improved Performance**: Refactored database queries and component vulnerabilities import service for better efficiency
* **UI Improvements**: Refreshed global search bar with new designs and enhanced dashboard experience

### 🆕 New Features

#### Backend Enhancements

* 🔍 Added vulnerability\_id and environment filter to ProjectsResolver
* 🏷️ Added component\_support\_level field to query type
* 🔄 Using source branch name as version name for better traceability
* 🔑 Added GitHub token for staging environment

#### Frontend Improvements

* 📊 Added parts overview section with new cards for better component visualization
* 🗑️ Added reusable delete confirmation component for list items
* 💾 Implemented dashboard card state persistence using localStorage
* 🔎 Added async product search filter to global vulnerability view
* 📝 Added refresh action to policy table

### 🐛 Bug Fixes

#### Backend Fixes

* 🔧 Fixed incorrect number of 'unspecified' items
* 🧹 Refactored component vulnerabilities import service
* 🗃️ Optimized database queries for efficiency
* 🗑️ Improved record removal functionality

#### Frontend Fixes

* 🎨 Fixed global license table header
* 🎯 Fixed drag and drop issue for dashboard cards
* 🔍 Fixed global vulnerabilities search
* 🧩 Fixed support analysis function
* 📥 Updated support CSV download function
* 🔎 Fixed analytics filter logic
* 📋 Fixed support status E2E test
* 🔗 Fixed component link test
* 🔄 Fixed CPE Editor autocomplete disappearance issue
* 📝 Fixed ShareLynk vulnerability links
* 🎭 Fixed component filters incorrect query
* 📊 Fixed support table preview
* 📃 Fixed error when downloading SBOM excel sheet
* 🔧 Fixed status update issue for parts vulnerability
* 🔄 Fixed component license update issue
* 🛠️ Fixed admin navbar overlap issue
* 🖼️ Fixed component insights display issue
* 👁️ Fixed support status not displaying in SBOM support status tab

#### UI Improvements

* 🎨 Removed unused assets to optimize project size
* 👨‍💻 Updated executive dashboard with new changes
* 🔧 Adjusted save pending alert position in component identifiers
* 📊 Updated vulnerability table styling
* 🔄 Refactored global vulnerability table
* 🎨 Enhanced sidebar and breadcrumb with subtle colors and better interaction
* 🧹 Updated admin navbar styling
* 🎯 Implemented outline icons globally
* 📑 Refactored SBOM component table layout
* 📱 Improved initial loading experience after login

## v3.1.9

April 17th 2025

***

## Interlynk Platform Release v3.1.9 📦

### Release Highlights ✨

This release introduces several improvements to the Interlynk Platform, focusing on enhanced filtering capabilities, better label management, and improved user experience across various components. Key highlights include:

* 🏷️ **Bitbucket Project Label Support** - Integration of Bitbucket project information as labels
* 🔄 **Product Lifestage Filtering** - New filtering options at version level
* 🛠️ **SBOM Download Improvements** - Added support status parameters
* 📊 **Health Score Calculations** - Refactored to handle "NA" values properly
* 🧹 **UI/UX Improvements** - Multiple usability and interface enhancements

### New Features 🚀

#### Label Management

* 🏷️ Added Bitbucket label handling to repository service and data migration (#2173, #6118)
* 🔄 Refactored global label filter for improved performance (#6154)
* ✉️ Enhanced label delete flow with a toast message for better feedback (#6172)

#### Filtering & Export

* 🏁 Added lifestage filter at version level (#2165)
* 🏁 Enabled product lifestage filter throughout the application (#6053)
* 📊 Added include\_support\_status argument to SBOM download (#2179, #5977)
* 📋 Updated Component CSV Export with correct data and missing fields (#6113)
* 📋 Added Part column to vulnerability CSV export (#6165)

#### UI Enhancements

* 📝 Made product description expandable for large content (#6128)
* 🎨 Implemented row highlight on hover for better table navigation (#6110)
* 🔄 Updated organization activity cards layout (#6140)
* 📊 Fixed component insights preview (#6171)

### Bug Fixes 🐛

#### UI Fixes

* 🔧 Fixed graphql warnings (#2181)
* 🔧 Fixed global vulnerability sorting issues (#2192)
* 🔧 Fixed Jira users listing (#2193)
* 🔧 Fixed Product Group Breadcrumb Duplicates (#6108)
* 🔧 Fixed Vulnerability Links UI Jump and Button Disable Logic (#6114)
* 🔧 Fixed CWE list to display 'N/A' when invalid CWE values are present (#6115)
* 🔧 Fixed username preview (#6120)
* 🔧 Fixed component health score issue (#6152)
* 🔧 Fixed shared component table with part details (#6161)
* 🔧 Fixed SBOM actions spacing (#6167)
* 🔧 Added null check to prevent crash in expandable text component (#6149)

#### Functional Fixes

* 🔧 Refactored health score calculations to handle "NA" values (#2188)
* 🔧 Fixed custom vulnerability create function (#6138)
* 🔧 Fixed assessment expire field (#6153)
* 🔧 Fixed global vulnerability edit permission for non-admin users (#6162)
* 🔧 Fixed Export to only include Part name in Vulnerability CSV Export (#6176)

### Code Improvements 🧰

#### Component Refactoring

* 🧰 Improved connection card component code (#6112)
* 🧰 Made Delete Button reusable and consistent across app (#6100)
* 🧰 Cleaned up Config modal component and improved code structure (#6123)
* 🧰 Refactored support and users data export mapping for improved clarity (#6130)
* 🧰 Improved SBOM support card component code (#6136)
* 🧰 Refactored Edit Button Component for reusability and consistency (#6129)
* 🧰 Refactored SBOM alternatives drawer (#6139)
* 🧰 Refactored global policy table (#6150)

#### Testing Improvements

* 🧪 Fixed Labels E2E tests (#6119)
* 🧪 Optimized Security Token CRUD E2E Test Time (#6124)
* 🧪 Fixed role E2E test (#6125)
* 🧪 Fixed product label E2E test (#6126)
* 🧪 Updated GitHub actions schedule timing for playwright tests (#6145)

#### Security & Dependencies

* 🔒 Bumped serialize-javascript from 6.0.1 to 6.0.2 (#6117)
* 📦 Updated all patch-level dependencies to latest versions (#6104)

## v3.1.7

April 10th 2025

***

### 🚀 Highlights

Interlynk Platform v3.1.7 brings significant improvements to the user interface, vulnerability management, and SBOM functionality. This release focuses on enhancing the overall user experience with the introduction of LynkSelect components across multiple features, improved CSV export capabilities, and several critical bug fixes.

### ✨ New Features

#### UI Enhancements

* **LynkSelect Implementation** 🎨
  * Replaced standard select components with LynkSelect in multiple areas:
    * Vulnerability Edit Links (#6038)
    * Support Status Bulk Edit (#6040)
    * Relationship Drawer (#6024)
    * Automation Rule Conditions (#6056)
  * Enhanced CSV Export with Add/Remove All Columns functionality (#6059)
  * Updated action buttons in Component Links and Relationships Edit (#6058)

#### Vulnerability Management

* **Advisory System Improvements** 📋
  * Added new drawer for vulnerability advisory list (#6065)
  * Updated vulnerability expand view with advisory list (#6107)
  * Fixed advisory link issues (#6083)
  * Updated vulnerability information for non-CVE entries (#2170)

#### SBOM Enhancements

* **Component Information Access** 📦
  * Added SBOM Component PURL and CPE Modals in Customer View (#6079)
  * Implemented copy to clipboard functionality for CPE and PURL (#6095)
  * Improved Archived SBOM list drawer component and query (#6063)
  * Refactored SBOM details component for better performance (#6077)

#### Support Status Management

* **Support Status Workflow** 🔄
  * Updated component support status system (#2166)
  * Fixed support status update logic (#6066)
  * Added conditional preview for product label filter (#6075)

#### Backend Improvements

* **Security Updates** 🔒
  * Updated OSV client (#2169)
  * Fixed policy failures (#2175)
  * Updated vulnerability information query (#2176)

### 🐛 Bug Fixes

#### UI Fixes

* Fixed layout issues in policy conditions section (#6057)
* Resolved CVSS Vector display issues in main view (#6061) and customer view (#6078)
* Fixed UI breaking issue in customer view vulnerabilities (#6076)
* Corrected version data display in support status expanded component (#6067)
* Fixed incorrect rendering of policy condition fields (#6096)
* Removed accessibility warnings for improved compliance (#6097)

#### Functional Fixes

* Fixed validation for community count thresholds (#6062)
* Corrected support status drawer with required changes (#6060)
* Fixed support status preview (#6074)
* Resolved component link and relationship CRUD functionality E2E tests (#6082)
* Fixed support expand view (#6084)
* Corrected License Expression in SBOM License CSV Export (#6085)
* Fixed Support Level data in SBOM Support Status CSV Export (#6087)
* Fixed UI break in Vulnerability CWEs List when no data is present (#6103)
* Corrected typo in email connections description (#6109)
* Fixed rendering issues in policy and automation fields (#6111)
* Fixed CWE link in vulnerability expand view (#6088)
* Fixed vulnerability advisory link preview (#6094)

### 🔧 Other Improvements

* Refactored Bitbucket Config Modal for optimizations (#6064)
* Removed support action and filters from component table (#6081)
* Updated seed data (#2171)
* Updated CSV export fields and headers for Support Status (#6102)

## v3.1.6

April 4th 2025

***

### Release Highlights ✨

* **Enhanced Vulnerability Management**: Added support for CWE & Advisories persistence, improved NVD client implementation, and custom vulnerability handling
* **Improved UI Components**: Integrated LynkSelect across multiple platform areas for better user experience
* **Lifecycle Support**: Implemented SBOM lifecycle for dashboard based on project and enabled lifecycle support at the version level
* **Performance Optimizations**: Refactored package lookup and storage logic to use normalized PURL format

### New Features 🆕

#### Backend Improvements

* ✅ Added NVD client implementation
* ✅ Added support for webhook secrets
* ✅ Implemented bulk create and update capabilities for support levels
* ✅ Added SBOM lifecycle for dashboard based on project
* ✅ Implemented license notification on license components
* ✅ Refactored package lookup and storage to use normalized PURL format

#### UI Enhancements

* ✅ Refactored SBOM vulnerability table
* ✅ Integrated LynkSelect across multiple UI components:
  * Support Checks
  * Upload Modal
  * Life Stage Modal
  * Component Support
  * Component Relations
  * Request Accept Modal
  * Role Deletion
  * Links Edit
  * Policy Rule Modal
  * PURL Editor
  * Switch Environment Modal
  * Custom Vulnerability Modal
  * License Status Drawer
  * Pagination Select
* ✅ Updated support status check form
* ✅ Updated assessment expiration field
* ✅ Enhanced product and version tables
* ✅ Added dashboard card for version lifestage
* ✅ Improved component links preview

### Bug Fixes 🐛

#### Backend Fixes

* ✅ Fixed NVD client issues
* ✅ Fixed rubocop job
* ✅ Fixed EPSS KEV job
* ✅ Fixed vulnerability metrics to consider environment
* ✅ Fixed issues with custom vulnerabilities
* ✅ Removed bad data affecting system performance

#### UI Fixes

* ✅ Fixed component links preview
* ✅ Fixed automation, license and health permissions
* ✅ Fixed version breadcrumb
* ✅ Fixed request table actions
* ✅ Fixed CSV download bug - properly handling comma in strings
* ✅ Fixed version lifestage API call
* ✅ Fixed component relationship E2E tests
* ✅ Fixed breadcrumbs layout issue for product and version name
* ✅ Fixed SBOM license update issue
* ✅ Fixed bulk VEX update with required validation
* ✅ Fixed user details modal
* ✅ Fixed vulnerability severity graph

### Other Improvements 🔧

* ✅ Updated Ruby gems
* ✅ Added new test for organization score settings
* ✅ Added new test for component support status
* ✅ Added conditional preview for product label card
* ✅ Truncated long descriptions from vulnerability info page
* ✅ Added retries and updated timeout for E2E tests
* ✅ Disabled CSV download when no columns are selected

## v3.1.5

March 27th 2025

***

## Interlynk Platform Release v3.1.5

### 🌟 Highlights

* **Enhanced Component Management**: Improved SBOM vulnerability component code and refactored component links for better performance
* **Enrich Java Packages:** Enrich java components from maven central.
* **Bitbucket:** Support Searching & Pagination.
* **Security Enhancements**: Added KEV details for CSV exports from Vulnerabilities
* **Performance Optimizations**: Optimized E2E tests by reusing authentication state
* **Backend Improvements**: Added cron job for cleaning up webhook events

### 🚀 New Features

#### Backend Enhancements

* ✨ Add cron job for cleaning up webhook\_events (#2104)
* ✨ Feature/enrich maven (#2128)
* ✨ Add pagination support for bitbucket repositories (#5908)
* ✨ Update age score limit (#5936)
* ✨ Add KEV details for CSV Export from Vulnerabilities (#5955)

#### UI/UX Improvements

* ✨ Create Reusable ToggleVisibilityButton for Password Fields (#5921)
* ✨ Integrate LynkSelect in Config Modal (#5926)
* ✨ Integrate LynkSelect in Invite User Modal (#5927)
* ✨ Integrate LynkSelect in License Modal (#5932)
* ✨ Add loading indicator for license creation and update process (#5937)
* ✨ Integrate LynkSelect in Edit Custom Vulnerability Drawer (#5966)
* ✨ Integrate LynkSelect in Change Role Modal (#5967)
* ✨ Integrate LynkSelect in Vulnerability Custom Field Modal (#5968)
* ✨ Update bitbucket icon (#5947)

### 🐛 Bug Fixes

#### Security Fixes

* 🔒 Support deprecated flag for cpe & remove from CPE autocomplete (#2137)
* 🔒 Remove token create permission from user level (#5956)
* 🔒 Fixed viewer role permissions (#5976)

#### Component Management

* 🛠️ Improve SBOM Vulnerability Component Code (#5917)
* 🛠️ Fixed component tag in SBOM license table (#5930)
* 🛠️ Update the logic for previewing End-of-Support field (#5928)
* 🛠️ Refactor SBOM archived check logic for reusability (#5933)
* 🛠️ Fixed component actions preview (#5952)
* 🛠️ Refactor Component Links (#5957)
* 🛠️ Refactor SBOM component table (#5961)
* 🛠️ Fixed component relation preview logic (#5979)

#### User Interface

* 🎨 Hide Component Support Filter for Free Tier and Customer View (#5918)
* 🎨 Fix Policy CRUD E2E tests (#5920)
* 🎨 Fixed routes flag hook (#5941)
* 🎨 Update toast message for component creation (#5943)
* 🎨 Fix License Modal Bug and Refactor Code (#5946)
* 🎨 Fixed ENV filter styling on vulnerability page (#5962)
* 🎨 Remove version search field from SBOM details page (#5964)
* 🎨 Update column sizing in custom vulnerability table (#5975)
* 🎨 Fixed misc styling issue (#5980)

#### Performance & Optimization

* ⚡ Handle exceptions with specific error logging (#2139)
* ⚡ Refactor RepositoryConnection code to get value of total\_count (#2126)
* ⚡ Remove unused components (#5923)
* ⚡ Remove org connection API call from customer view (#5929)
* ⚡ Cleanup unused queries (#5931)
* ⚡ Refactor request modal (#5938)
* ⚡ Remove licenseAutoComplete API call from customer view (#5939)
* ⚡ Add conditional preview for global vuln filters (#5940)
* ⚡ Refactor vuln product drawer (#5942)
* ⚡ Refactor component links tab (#5944)
* ⚡ Cleanup Unused Utility Functions (#5950)
* ⚡ Optimize E2E Tests by Reusing Auth State (#5948)
* ⚡ Update Patch Dependencies (#5958)
* ⚡ Optimize SBOM Request E2E Test (#5959)
* ⚡ Optimize Policy CRUD E2E Test (#5960)
* ⚡ Optimize Support CRUD E2E Test (#5970)
* ⚡ Fix and Optimize License E2E Test (#5971)

###

## v3.1.3

March 20th 2025

***

### 🎯 Highlights

* **React 18 Upgrade**: Major frontend framework upgrade from React 17.0.2 to React 18.3.1
* **UI Enhancements**: LynkSelect integration across multiple components
* **Improved Component Management**: Bulk edit support status across versions/parts
* **Enhanced Analytics**: Executive dashboard improvement**s**
* **BitBucket**: New webhook events now supported.

### ✨ New Features

#### User Interface Improvements

* 📊 Added Executive Dashboard card for number of SBOMs in specific lifecycle
* 🔍 Implemented search functionality to RepositoriesConnection and updated query type
* ⌨️ Added Kbar shortcut from Policy Details page and improved navigation
* 🔄 Integrated LynkSelect in multiple components:
  * Component Add Modal and related fields
  * Build version drawer
  * Vulnerability status component
  * VEX modal component
  * Policy modal dropdowns

#### Repository Management

* 🗑️ Implemented Bitbucket repository deletion service
* 🔄 Support for PullRequestMerged event with environment and version generation

#### Component Management

* ✅ Added ability to bulk edit component support status across versions/parts
* 🏷️ Added internal tag to the support status drawer
* 🔄 Refactored component relationship drawer with reusable component

### 🐛 Bug Fixes

#### UI and User Experience

* 📋 Fixed header alignment in vulnerability table
* 🎭 Fixed VEX custom field validation
* 🛑 Fixed UI crash on User Role Delete modal
* ⬛ Updated dark mode color for regex highlighter
* 📅 Fixed incorrect theme for calendar field
* 📏 Adjusted column widths in license table to improve readability
* 📊 Fixed System Log visibility issue
* ✅ Added loader to Role Delete Modal
* 📊 Fixed pagination item count in Global Vulnerability Affected Products

#### Data Management

* 📤 Fixed export functionality for searched users and user lists
* 🧩 Fixed support level with NA disappearing when sorting
* 📧 Fixed email retention issue on login
* 📊 Updated support CSV export with part information
* 🔄 Enabled filters during user export
* 📊 Updated column order for support status export
* 🔄 Added sorting for support end date and support level
* 📉 Fixed analytics to zero-out data when not available
* 🚫 Removed assessment expiration when no longer maintained
* 🛑 Removed assessment expiration from support bulk edit

#### Backend Improvements

* 🔧 Refactored Packages processor for improved PURL handling
* 🛠️ Fixed GitHub update job
* 🔄 Updated repositories job
* 🗃️ Fixed migration issues
* 📊 Fixed project vulnerability metrics
* 📑 Fixed indexes on component support override

#### E2E Tests

* 🧪 Fixed SBOM E2E tests
* 🧪 Fixed SBOM General tab Author E2E tests
* 🧪 Fixed SBOM Components E2E tests
* 🧪 Fixed SBOM Vulnerabilities E2E tests

#### Technical Debt & Maintenance

* 🧹 Removed unused components
* 🔄 Updated patch versions for dependencies
* 🔄 Updated minor versions for dependencies
* 📚 Added ESLint rule to prevent direct drawer imports
* 🔄 Refactored Configuration Modal and removed redundant code
* 📜 Updated jspdf to the latest version
* 🔄 Updated apollo-upload-client to the latest version
* 🔧 Improved SBOM Components code

## v3.1.2

March 12th 2025

***

* Minor release to fix crashing job process.

## v3.1.1

March 11th 2025

***

### 🚀 Highlights

This release brings significant improvements to component support management, enhanced SBOM capabilities, and new integrations with source code management tools. We've also made the user interface more intuitive and fixed several important bugs to ensure a smoother experience.

***

### 🎁 New Features

#### 📊 Component Support Management

* ✅ **Bulk Update Support Status** - Update multiple components at once to save time
* 📥 **CSV Export with Support Details** - Export all your component support data including parts support level
* 🗓️ **Assessment Expiration Dates** - Assessment expiration days now converted to specific dates for clarity
* 🏷️ **Improved Support Status UI** - Clearer icons, tooltips, and visual indicators

#### 🔄 Source Code Integrations

* 🧩 **Bitbucket Integration** - Full Bitbucket configuration interface with webhook support
* 🔗 **Enhanced Repository Connections** - Improved GitHub connection handling
* 🔁 **Webhook Improvements** - More reliable event handling for source code changes

#### 👥 User Management

* 📋 **User CSV Export** - Export user information to CSV for external reporting
* ⏱️ **Improved Invitation Flow** - Added loading indicators when managing user invitations
* 📄 **Enhanced User Table** - Fixed display issues in the user management interface
* 📱 **Organization User Pagination** - Better handling of large user lists with pagination

#### 📑 SBOM Enhancements

* 🔍 **Comparison Layout Improvements** - Clearer visualization when comparing SBOMs
* 🖱️ **Drag and Drop Upload** - Enhanced SBOM upload with full-screen drag and drop support
* 🏁 **Auto-Archive for Ready Status** - Automatic archiving when SBOM reaches ready state
* 🧰 **Updated SBOM Info Card** - Clearer information display on the tools page

***

### 🔧 Enhancements

#### 💫 User Interface Improvements

* 🎨 **Standardized Table Layouts** - Consistent design across product details and changelog views
* 🔍 **Refactored Filter Components** - More intuitive filtering across all tables
* 📏 **Fixed Text Cropping** - No more cut-off text in version tables
* 🏷️ **Required Field Indicators** - Clear marking of required PURL fields
* 🔢 **Better Pagination** - Hide controls when not needed and show total item counts

#### 🛡️ Vulnerability Management

* 🎯 **Direct Only Filtering** - New filter option for component and vulnerability tables
* 🔗 **Impacted Products View** - See all affected products in Global Vulnerability View
* 📊 **Dashboard Status Counts** - Fixed vulnerability severity status counts on dashboard
* 🔍 **Expanded View Improvements** - Integrated detail components for better information display

#### ⚡ Performance Optimizations

* 🚀 **Lazy Loading in Dropdowns** - Faster loading in Tools Product List
* ⚙️ **License Loading Optimization** - More efficient license processing
* 📈 **Improved Memory Management** - Better application performance and stability
* 🔌 **Enhanced Database Connections** - More reliable database operations

***

### 🐞 Bug Fixes

* 🛠️ **SBOM Status Issues** - Fixed SBOM not ready state when vulnerability scan is disabled
* 🔄 **SBOM Comparison** - Resolved runtime errors in comparison functionality
* 🔍 **Search Shortcut** - Fixed disappearing search shortcut bug
* 📝 **VEX Status History** - Fixed data display issues in vulnerability status history
* 🏷️ **Component Support Tags** - Fixed run status indicators
* ✉️ **Email Configuration** - Improved validation for email settings
* 👤 **Author Creation** - Fixed issues with creating new authors
* 🔗 **Repository Connections** - Resolved issues with Bitbucket integration

***

### 🔒 System Improvements

* 📋 **Enhanced Logging** - Better system logging capabilities
* 🔍 **Code Quality** - Added ESLint rules to restrict console logs
* ✉️ **Email Security** - Updated email validation for better security
* 📊 **Monitoring Enhancements** - Improved error handling and system monitoring

***

## v3.1.0

***

* Release Error

## v3.0.9

Feb 27th 2025

***

### 🔥 Highlights

* 🚀 Dependent Auto-Completion in CPE Editor – Improves accuracy and efficiency.
* 🛠 Major Refactoring – Multiple drawers now use LynkDrawer for a more consistent UI.
* 🔍 Enhanced Analytics & Metrics – Process execution time, Patch Velocity updates, and improved component expand view.
* 🎨 UI/UX Improvements – New severity & EPSS styling, input field theme updates, and better support for different viewports.
* 🔐 Security & Compliance – Fixes to login notification handling, email verification, and product lifecycle tracking.
* 📢 Notifications & Reports – Improvements in product notifications and report notification cleanup.

### ✨ New Features & Enhancements

* ✅ CPE Editor Auto-Completion – Dependent fields now auto-complete based on previous values. \[#5660]
* ✅ System Logs with Execution Time – Added process execution time tracking. \[#5668]
* ✅ Product Auto-Archive Feature – New settings introduced for auto-archiving inactive products. \[#5686, #2012]
* ✅ Enhanced Rule Import – Drag and drop works across the entire screen with improved stability. \[#5679]
* ✅ Kbar Navigation Enhancements – New route flags added from the Vulnerability Details page. \[#5683]
* ✅ Support Tab Updates – Now includes required information for better insights. \[#5698]

### 🛠 UI & UX Improvements

* ✅ LynkDrawer Refactor – Standardized UI for multiple drawers,.
* ✅ Analytics Page Optimization – Improved layout for different viewports. \[#5687]
* ✅ Severity & EPSS Styling Updates – Better visual cues for security issues. \[#5688]
* ✅ Scrollbar Hidden in LynkDrawer – Provides a cleaner look. \[#5674]
* ✅ Updated Component Expand View – Now includes support details. \[#5670]
* ✅ Reordered Product Settings Tags – Improves accessibility. \[#5707]
* ✅ Support Status Drawer Enhanced – Additional details added. \[#5725]
* ✅ Compliance Card Styling Fixes – Ensures consistent appearance. \[#5694]
* ✅ Updated Component Version Column – Added required spacing for better readability. \[#5696]

### 🐞 Bug Fixes

* ✅ Forgot Password Link Alignment – UI fix for better visibility. \[#5661]
* ✅ Fix PURL and CPE Preview Tag Issues – Ensures correct tag rendering. \[#5671]
* ✅ Fix UI Breaking in Component Support Modal – Prevents layout issues. \[#5672]
* ✅ Fix Security Tokens, Roles & Internal Components Alignment – Ensures proper display. \[#5723]
* ✅ Fix Patch Velocity Metrics – Now zeroed out like other metrics. \[#5708]
* ✅ Fix Support CSV Export – Resolves incorrect exports. \[#5709]
* ✅ Fix Login Notifications – Now triggers only for actual user logins. \[#2027]
* ✅ Fix Filter for Multiple Fields in Labels – Improves accuracy. \[#2015]
* ✅ Prevent Forgot Password Email Bombing – Strengthened security. \[#1996]
* ✅ Fix Disabled Products in Lifecycle Calculations – Improves lifecycle tracking. \[#2014]

###

## v3.0.8

Feb 20th 2025

***

### 🚀 Highlights

* **Performance Improvements**: Optimized various API queries, reducing redundant calls and improving dashboard performance.
* **Enhanced SBOM Actions**: Added support for SBOM actions mutation and refined SBOM upload and comparison.
* **Component Support Level**: Full Support for component level support.
* **Policy & Compliance Updates**: New filters for policy details and global policy lists.
* **GitHub Integration**: Improved GitHub client functionality and token handling.

### 🆕 New Features

* **License Status Update**: Added the ability to update `license_status` on components. (#1945, #5564)
* **Global Policy Filters**: Introduced filters to refine policy searches. (#1962, #5574)
* **SBOM Actions Mutation**: Added mutation support for SBOM actions. (#1988)
* **Support Level Download API**: Implemented an API for downloading support levels. (#1974, #5618)
* **Re-run Support Analysis**: Added a new action for rerunning support analysis. (#5642)

### 🛠️ Bug Fixes

* **SBOM Upload & Processing**:
  * Fixed end-to-end (E2E) test issues with SBOM uploads. (#5593, #5644)
  * Corrected repository lookup logic. (#1984)
  * Fixed invalid SBOM notification update count. (#1986)
* **Dashboard & Vulnerability Fixes**:
  * Resolved double vulnerability severity counting. (#1980)
  * Fixed vulnerability lookup form and styling. (#5603, #5612)
  * Optimized vulnerability query execution. (#5598, #5605)
* **UI & UX Improvements**:
  * Standardized combo-box styling. (#5650)
  * Improved component insights and support preview. (#5610, #5611)
  * Fixed various layout and styling inconsistencies. (#5612, #5614, #5633, #5655)
* **Policy & Compliance Fixes**:
  * Fixed typo in policy conditions component. (#5607)
  * Refactored policy creation modal. (#5604)
  * Updated policy result queries for efficiency. (#5599)

### 📈 Performance Improvements

* **Optimized API Calls**:
  * Reduced product stage API calls from 7 to 1. (#5588)
  * Optimized vulnerability severity API calls from 5 to 1. (#5589)
  * Streamlined environment total counts API. (#5651)
  * Improved SBOM comparison query execution. (#5649)
* **Refactoring & Cleanup**:
  * Removed unused imports, hooks, and components. (#5594, #5656, #5657)
  * Introduced a reusable `fetchNodes` utility function. (#5638)
  * Enhanced vendor root path validation with regex matching. (#5634)

###

## v3.0.7

Feb 13th 2025

***

### 🚀 Highlights

* Major refactoring and optimizations across SBOM components and compliance modules.
* Enhanced UI components with improved styling and usability.
* Introduced new policy violation page and lifecycle stage updates.
* Improved support for free-tier users with updated dashboards and feature restrictions.

### ✨ New Features

* **Reusable UI Components:** Created reusable divider, drawer, and label components for better UI consistency. (#5507, #5540, #5541)
* **Policy Violation Page:** Added a dedicated policy violation page with required details. (#5518)
* **Executive Dashboard Enhancements:** Introduced new filters for better dashboard analytics. (#5539)
* **Improved Component Notes Drawer:** Implemented the Components Notes Drawer using `LynkDrawer`. (#5554)
* **Global Variables:** Added global lists for severity levels and VEX types. (#5567, #5572)
* **New Lifecycle Stage:** Added a new product lifecycle stage for better categorization. (#5552)

### 🛠️ Bug Fixes

* Fixed crash when API returns null for license autocomplete. (#5517)
* Fixed UI crash when switching tabs after expanding policy table. (#5521)
* Fixed incorrect count of products in 'None' lifecycle stage. (#1960)
* Fixed failing SBOM build and changelog E2E tests. (#5551, #5553)
* Fixed error 500 on re-running automation. (#1956)
* Fixed organization and product E2E tests. (#5550, #5569)
* Fixed empty graphs, updated formulas, and stylistic changes. (#5581)
* Fixed regular expression logic for better accuracy. (#5528)
* Fixed incorrect parts checkbox logic in SBOM download dialog. (#5583)
* Fixed CPE and PURL editor issues. (#5584, #5585)
* Fixed PURL version check. (#5547)
* Fixed layout issues in SBOM download menu. (#5555)
* Fixed changelog table styling for dark mode. (#5542)

### 🔄 Refactoring & Improvements

* **SBOM Compare Code:** Refactored SBOM comparison logic in tools and version lists. (#5144)
* **Compliance Tab Update:** Refactored SBOM compliance tab for improved performance. (#5520)
* **Free Tier Enhancements:**
  * Hide compliance and parts checkbox in SBOM download. (#5548)
  * Hide product by label for free-tier users. (#5546)
  * Update dashboard by removing restricted metrics. (#5563)
  * Remove label select in import status for free tier. (#5565)
  * Centralized free-tier check logic. (#5577)
* **Performance Optimizations:**
  * Removed unused components, variables, and mutations. (#5509, #5510, #5578, #5576)
  * Improved default checkbox styling in tables. (#5523)
  * Updated SBOM reprocess function for better efficiency. (#5516)
  * Updated vulnerability graphs API with paginated queries. (#5586)
  * Optimized routing logic for global vulnerability access. (#5545)
  * Refactored customer check logic in `useProjectGroup`. (#5575)
  * Centralized route checks logic in a dedicated hook. (#5571)

## v3.0.6

Feb 5th 2025

***

### Highlights

Interlynk Platform v3.0.6 introduces enhanced filtering, model validation improvements, and multiple UI/UX refinements to improve overall user experience. This release also includes essential bug fixes and performance optimizations.

### New Features

* **Filter by Project Group Label IDs** in daily metrics, providing more granular insights ([#1929](https://github.com/interlynk-io/lynk-dash-app/pull/1929)).
* **Refresh Token Implementation** to enhance authentication flow ([#1796](https://github.com/interlynk-io/lynk-dash-app/pull/1796)).
* **OSV Lookup Integration** for vulnerability management ([#1917](https://github.com/interlynk-io/lynk-dash-app/pull/1917)).

### Improvements

* **Model Validation Enhancements**: Updated validation logic for organization settings and schema updates ([#1928](https://github.com/interlynk-io/lynk-dash-app/pull/1928)).
* **Health Icons in Action Panels** for improved visibility ([#5417](https://github.com/interlynk-io/lynk-dash-app/pull/5417)).
* **Executive Dashboard Enhancements**: Added business unit filtering ([#5438](https://github.com/interlynk-io/lynk-dash-app/pull/5438)).
* **Lifecycle Updating Feature** moved to SBOM Details Page ([#5444](https://github.com/interlynk-io/lynk-dash-app/pull/5444)).
* **Component Insights & Icons Refinements** ([#5412](https://github.com/interlynk-io/lynk-dash-app/pull/5412)).
* **New Graphs for Vulnerability Age & Identification Velocity** ([#5502](https://github.com/interlynk-io/lynk-dash-app/pull/5502)).

### Bug Fixes

* **Fix Resetting of All Compliance** ([#1930](https://github.com/interlynk-io/lynk-dash-app/pull/1930)).
* **Fix Retraction Issues** ([#1927](https://github.com/interlynk-io/lynk-dash-app/pull/1927)).
* **Fix Custom Vulnerability Issues** ([#1923](https://github.com/interlynk-io/lynk-dash-app/pull/1923)).
* **Resolve Login Error Handling** ([#5463](https://github.com/interlynk-io/lynk-dash-app/pull/5463)).
* **Fix User Registration Button Disable Bug** ([#5473](https://github.com/interlynk-io/lynk-dash-app/pull/5473)).
* **Remove Environment Selector from Author Modal in SBOM Detail Page** ([#5475](https://github.com/interlynk-io/lynk-dash-app/pull/5475)).
* **Fix Lifecycle Modal Bug: Remove Lynk Alert on Close** ([#5458](https://github.com/interlynk-io/lynk-dash-app/pull/5458)).
* **Fix Global Env State Link to Global Vulnerability Env Filter** ([#5454](https://github.com/interlynk-io/lynk-dash-app/pull/5454)).
* **Fix Component Relationship CRUD E2E Test** ([#5498](https://github.com/interlynk-io/lynk-dash-app/pull/5498)).
* **Fix Import Vulnerability Status Functionality E2E Test** ([#5496](https://github.com/interlynk-io/lynk-dash-app/pull/5496)).
* **Fix Parts Functionality E2E Test** ([#5495](https://github.com/interlynk-io/lynk-dash-app/pull/5495)).

## v3.0.5

January 27th 2025

***

### Highlights of New Features and Improvements

#### SBOM Lifecycle Management

Introduced a feature to seamlessly manage and update SBOM lifecycles. (#5410)

#### Executive Dashboard Enhancements

Dashboard now populates with key data to improve high-level decision-making. (#5415)

#### Severity and CVSS Metrics

Added Severity and CVSS Scores to the Vulnerability View Page for better risk assessment. (#5418)

#### Improved Dashboard UI

Updated the dashboard with new graphs and data for better insights. (#5362, #5419)

#### Streamlined Component Lookup

Enhanced the UX for faster and easier component search. (#5383)

#### Contribution Suppression

Added the ability to suppress specific contribution types. (#1922)

#### Validation and Modal Enhancements

Manufacturer and component add modals updated with required validations and new changes. (#5398, #5408)

#### Health Scoring Updates

Stylistic and functional updates made to health scoring for improved usability. (#5387, #5405)

### Bug Fixes

* Fixed alignment issues in component notes. (#5396)
* Resolved inconsistencies in component insight data. (#5390)
* Fixed issues with the Vulnerability Info View and included Known Exploited Vulnerabilities (KEV) in the expanded view. (#5407)
* Removed unnecessary component warnings. (#5404)
* Addressed multiple entries in metric aggregation reports. (#5420)

### Other Improvements

* Updated description tags with icons for better visual clarity. (#5389)
* Implemented UI improvements across the platform for a more cohesive experience. (#5409)
* Improved tools loading view for better user feedback. (#5406)
* Added an end-to-end test for organization creation and switching workflows. (#4752)

## v3.0.4

January 23rd 2025

***

### **Highlights of the Release**

The v3.0.4 release introduces significant enhancements to platform usability, performance, and compliance workflows. With additional features such as improved filtering, enriched SBOM operations, and a variety of bug fixes, this update reinforces our commitment to delivering a robust and user-friendly experience.

***

### **New Features**

* **Annotate Gem Initialization**: Enhanced annotation capabilities with the addition of the annotate gem to streamline development workflows. \[#1905]
* **Attach Existing Custom Vulnerabilities to SBOMs**: Simplified vulnerability management by allowing custom vulnerabilities to be linked directly to SBOMs. \[#1902]
* **Package Lookup Functionality**: Added the ability to perform detailed package lookups, leveraging Package URLs (PURLs) for precision. \[#1907, #1913]
* **Score Settings in Command Bar**: Easily access and adjust score settings via the command bar for a more seamless experience. \[#5369]

***

### **Enhancements**

* **Policy Rule Violations Finder**: Extended filtering options for more granular policy rule violation analysis. \[#1870]
* **Weight Control for Package Health Logic**: Enabled fine-tuned control over package health calculations to improve reporting accuracy. \[#1898, #5029]
* **Updated Plan Details View**: Improved clarity and accessibility in the plan details interface. \[#5341]
* **Refactored Components**: Significant refactoring of components, including CVSS, CPE, and PURL info cards for better maintainability and performance. \[#5342, #5365]
* **Improved SBOM Operations**:
  * Fixed SBOM creation tool tests. \[#5351]
  * Enhanced SBOM general tab functionality. \[#5375]
  * Updated SBOM end-to-end tests for increased coverage. \[#5366, #5384]
* **Compliance and Vulnerability Management**:
  * Removed compliance selector and custom vulnerability actions for free-tier users, streamlining operations. \[#5349, #5350]
  * Improved vulnerability table preview for customer view. \[#5370]

***

### **Bug Fixes**

* **Health Score Calculations**:
  * Resolved issues with health score bugs and null breakdowns. \[#1912, #1919]
  * Fixed health score fields validation. \[#5382]
* **Concurrency Control**: Controlled the concurrency of workflows and jobs to prevent resource contention. \[#1908]
* **Date Filter**: Fixed a bug with date filtering for component vulnerabilities. \[#1909]
* **Custom Vulnerability Operations**: Addressed issues with custom vulnerability creation and operation support. \[#1915, #5380]
* **General Fixes**:
  * Fixed typos, calculation errors, and stylistic changes in various areas. \[#1919, #5360]
  * Resolved modal auto-closing issues in SBOM tabs. \[#5375]
  * Fixed missing brace errors. \[#5367]
  * Corrected end-to-end test failures across SBOM and components. \[#5359, #5376, #5384]
  * Fixed color code validation issues. \[#5353]

***

### **Performance Improvements**

* **Refactoring and Cleanup**:
  * Refactored utility functions for better code reuse and readability. \[#5336, #5356, #5357]
  * Removed unused global states and redundant functions. \[#5345, #5355]
  * Cleaned up policy table and automation column components. \[#5363, #5364]
* **Loading Feedback**: Added feedback for the refresh button to enhance user experience during data updates. \[#5372]

***

### **Security Updates**

* **X-Permitted-Cross-Domain-Policies**: Implemented additional security headers to ensure stricter domain access controls. \[#5378]

## v3.0.3

January 14th 2025

***

### 📋 **Highlights**

* Introduced **Defect Density Calculation Service** to provide deeper insights into project health.
* Added **Reconcile Service** to ensure vulnerability data remains consistent across the platform.
* Enhanced **custom fields for workflow integration**, supporting more personalized workflows.

***

### ✨ **New Features**

* **Defect Density Calculation**:\
  Introduced the **DefectDensityService** to calculate defect density for projects, offering better visibility into overall project health.
* **Reconcile Service**:\
  Implemented a **reconciliation service** to prevent mismatches in vulnerability data across different sections of the platform.
* **Custom Fields for Workflow Integration**:\
  Enhanced **workflow integrations** by allowing **custom fields**, making it easier to tailor workflows to specific needs in tools like Jira.

***

### 🛠 **Improvements**

* **Annotatable Support in Changelogs**:\
  Replaced the term **annotation** with **annotatable** to improve consistency in changelogs.
* **Global Vulnerability Table Refactor**:\
  Refactored the **Global Vulnerability Table** for better performance and a cleaner interface.
* **System Logs Update**:\
  Updated **system logs** to support new scan types, improving traceability.
* **SBOM Selection Issue Fixed**:\
  Resolved various **SBOM selection issues**, ensuring a smoother experience across workflows.
* **Email Styling Enhancements**:\
  Improved the **styling of email templates** for better readability and consistency.

***

### 🐞 **Bug Fixes**

* **Compliance Bug in SBOM Score Report**:\
  Fixed an issue where compliance reports failed when the **report format** was present but not selected.
* **Vulnerability Status History Fix**:\
  Resolved an issue where **vulnerability status history** did not display **imported statuses** correctly.
* **Vendor Page Redirection**:\
  Fixed a **redirection issue** on the vendor page.
* **404 Page Setup**:\
  Implemented a **404 error page** for better user experience when navigating invalid links.
* **Component Description Preview Update**:\
  Updated **component previews** to improve readability.
* **Invalid Expressions Handling**:\
  Improved error handling to manage **invalid expressions**, preventing crashes.
* **Dashboard Redirection Issue**:\
  Fixed redirection issues when navigating through the **dashboard**.

***

### 🔧 **Other Fixes and Enhancements**

| **Issue**                         | **Description**                                          |
| --------------------------------- | -------------------------------------------------------- |
| Fixed email styling               | Improved email template readability                      |
| Compliance list preview update    | Updated compliance lists with new styling                |
| Fixed analytics filter issue      | Resolved issues with filtering analytics data            |
| Product delete modal verification | Added input verification to the **product delete modal** |
| Update policy expand view         | Enhanced **policy expand view** for better UX            |
| Fixed SBOM checks test            | Fixed **end-to-end test** issues related to SBOM checks  |
| Data license modal fix            | Resolved issues with **data license modal**              |
| Handle invalid CVSS expressions   | Fixed handling of **invalid CVSS vector expressions**    |

***

### ✅ **Quality of Life Changes**

* Updated the **default sort order** for **Global Vulnerabilities** to improve relevance.
* Fixed various navigation bugs, ensuring **sort orders are retained** across pages.
* Enhanced **Custom Vulnerability Form** with **input validation** to avoid submission errors.
* Improved the **SBOM General Tab Styling** for consistency across the platform.
* Added **delete checks** to the **Product Table** for easier record management.

***

### ⚙️ **Technical Enhancements**

* Refactored **external navigation URLs** into **reusable components** for better maintainability.
* Updated **node options** in **staging deployment** to improve performance.
* Updated **CVSS Info Modal** with **conditional previews** to improve flexibility.

## v3.0.2

**January 7th, 2025**

### 🆕 New Features & Highlights

* **Project Filtering by Name**

  Easily filter projects by their name to quickly find what you’re looking for, especially in large environments.
* **Defect Density Graph in Analytics**

  Visualize vulnerabilities across your components with the new Defect Density Graph, helping you track defect trends over time.
* **Custom Vulnerability Tab**

  Manage organization-specific vulnerabilities more effectively with the new Custom Vulnerability Tab.
* **SBOM Quality Metrics Enhancements**

  The SBOM Quality Score preview and calculation have been improved, offering more accurate insights into your SBOM health.

### 🛠️ Improvements & Fixes

* Added detailed Activity Logs for Annotations to track changes and updates.
* Resolved issues with Component Relationship Preview to display accurate relationships between components.
* Fixed SBOM Download Issue when the quality score was blank.
* Improved Manufacturer URL Navigation to ensure all links work as expected.
* Updated Email Styling for cleaner, more professional email templates in production.
* Environment Selector is now disabled after selection to prevent accidental changes.
* Multiple Analytics Page Enhancements, including updated icons, filters, and default values for a better user experience.

### 🐞 Bug Fixes

* Fixed SQL Error in the project metrics finder to ensure smoother performance.
* Resolved Compliance Score Lookup issues that always defaulted to NTIA.
* Fixed SBOM Quality Score Calculation to ensure consistency across reports.
* Corrected a Typo in Project Vulnerability Metrics for more accurate reporting.
* Fixed Graph Styling in Dark Mode to improve readability.

### 📈 Analytics & Metrics Improvements

* Added Vulnerability Status Counts to the Analytics dashboard for a clearer overview of your vulnerabilities.
* Updated the Patch Velocity Metric to improve tracking of remediation efforts.
* Enhanced SBOM Statistics for more accurate and actionable data.
* Automatically Reset Analytics Filters when changing environments to ensure fresh data views.

### ✅ Security Enhancements

* Implemented Organization Name Validation to prevent potential code injection risks.
* Fixed issues with Activity Logs to ensure accurate tracking of actions and changes.

## v3.0.1

**January 3rd, 2025**

### 🚀 New Features

* **SBOM Automation Rules Saving Across Environments**

  Automation rules can now persist across different environments, providing better flexibility in managing your SBOM processes. \[#5211, #5234]
* **Conditional Preview for Organizational Lists**

  Users can now preview organizational lists based on specific conditions, improving user experience and navigation. \[#5213]
* **Component Annotation Support**

  Added support for component-level annotations, allowing users to add custom notes and metadata for better tracking. \[#5206, #5221]
* **System Log Functionality**

  Implemented system logging to provide better visibility into platform actions and audit trails. \[#5232, #1851]
* **SBOM Vulnerability Statistics**

  Added a detailed vulnerability statistics view for each SBOM, giving users quick insights into their SBOM’s security posture. \[#5230]

### ✨ Enhancements

* **SBOM Compliance View Loading Screen**

  A loading screen has been added to the SBOM compliance view to improve user experience during data fetches. \[#5231]
* **ShareLynk Drawer Refactor**

  The ShareLynk drawer has been updated with a new form layout for a more intuitive user experience. \[#5228]
* **User Update Validation**

  Improved user update validation to handle various scenarios accurately and securely. \[#5249]
* **Email Notifications Styling**

  Fixed styling issues in email notifications to render correctly across different devices and platforms. \[#1792]
* **Global Icon Style Update**

  Updated icon styles globally for a more consistent and polished look across the platform. \[#5246]
* **Annotation Type Updates**

  Annotations now include timestamps for better tracking of updates and creation dates. \[#1848]
* **SBOM Activity Logs**

  Updated SBOM activity logs to include additional details, making it easier to track changes and activities. \[#5243]
* **UI and Analytics Improvements**

  Improved the overall UI consistency and made enhancements to the analytics page for a better user experience. \[#5220, #1847]

### 🐛 Bug Fixes

* **Fixed SBOM Download Issues in ShareLynk**

  Resolved missing code for SBOM download options, ensuring a smoother download experience. \[#5136, #5261]
* **Fixed Vulnerability Badge Alignment**

  Addressed misalignment issues with vulnerability badges for better visibility. \[#5256]
* **Fixed SBOM Checks Rescan**

  Resolved an issue causing errors when re-running SBOM checks. \[#5241, #5240]
* **Fixed Daily Metrics Collection**

  Fixed errors in the daily metrics collection job and optimized it to use upserts. \[#1845, #1853]
* **Fixed Missing Component Vulnerabilities**

  Resolved issues with missing component vulnerabilities from certain parts of the platform. \[#1838]
* **Fixed SBOM Download Authorization Issue**

  Addressed an issue where ShareLynk SBOM downloads failed due to missing authorization checks. \[#1843]
* **User Name Sanitization**

  Implemented user name sanitization to avoid potential code injection vulnerabilities. \[#5245]
* **Fixed Organization Name Update Validation**

  Ensured proper validation when updating organization names to prevent invalid entries. \[#5247]
* **Fixed Search Query Trimming**

  Resolved an issue with untrimmed search queries causing mismatches. \[#1840]
* **Fixed Vulnerability Statuses Globally**

  Standardized the vulnerability status column across the platform for consistency. \[#5242]
* **Fixed Repo Crashes**

  Addressed crashes occurring in specific repo configurations. \[#1844]

## v3.0.0

**December 23, 2024**

### 🚀 New Features

* **Hide SBOM Quality Score**\
  Added the ability to hide SBOM quality scores for enhanced flexibility in compliance workflows. \[#1715]
* **Unignore SBOM Checks**\
  Users can now “Unignore” checks, providing greater control over ignored items. \[#5160]
* **Component Search in Relationship Form**\
  Implemented a robust search functionality for components within the relationship form. \[#5175]

***

### ✨ Enhancements

* **FDA Component Support**\
  Updated support levels for FDA components, ensuring up-to-date compliance. \[#1808]
* **Default and Manual Scan Organization**\
  Moved default and manual scans to more intuitive facets for better user experience. \[#1829]
* **Optimized SBOM PDF Export**\
  Refactored and optimized SBOM PDF exports for smaller, more efficient files. \[#5170, #5178]
* **Tooltip and Label Updates**\
  Improved tooltips for Version Health Score and SBOM Quality Score for better clarity. \[#5188, #5198]
* **Improved Vulnerability Feeds**\
  Cleaned up and optimized vulnerability/exploitability feed listings. \[#5158]
* **UI Consistency**\
  Enhanced component side-drawer consistency and updated the compliance drawer for a cohesive UI. \[#5161, #5121]
* **API Call Optimization**\
  Reduced unnecessary API calls for better performance. \[#5130]
* **Updated SBOM Defaults**\
  Adjusted SBOM export defaults for user convenience. \[#5190]

***

### 🐛 Bug Fixes

* **Nil Panic Error**\
  Resolved issues causing nil panic errors for users. \[#1814]
* **SBOM Checks Filter**\
  Fixed filter reset issue in SBOM checks. \[#5159]
* **Tooltip Mismatch**\
  Fixed incorrect tooltips on Version Health Score. \[#5188]
* **Vulnerability Badge Styling**\
  Adjusted styling for vulnerability badges for better visibility. \[#5194]
* **Vulnerability Count Display**\
  Updated SBOM details to show `-` for vulnerability count when scans are pending. \[#5192]
* **Component Update**\
  Fixed component update functionality with required changes. \[#5187]
* **Relationship Updates**\
  Addressed issues in primary relationship previews and updates. \[#5173, #5195]
* **Search Query Trimming**\
  Fixed issues with untrimmed search queries causing mismatches. \[#5199]
* **PDF Export Issues**\
  Resolved missing data hashes and fixed descriptions from products in PDFs. \[#5189, #5191]
* **License Table Display**\
  Fixed SBOM license table in customer views. \[#5197]
* **Compliance List**\
  Addressed inconsistencies in the compliance list. \[#5208]

***

### ⚙️ Technical Improvements

* **Sidekiq Configurations**\
  Added configurations for Sidekiq, improving job management. \[#1830]
* **Job Scheduling Changes**\
  Updated job scheduling for improved reliability. \[#1833]
* **Removed Debug Code**\
  Cleaned up unnecessary debug code to streamline performance. \[#1824]
* **Removed New Relic**\
  Eliminated unused New Relic and Solid Errors to reduce overhead. \[#1811]

## v2.9.9

**December 17th, 2024**

### :new: New Features

* Added API to retrieve a single custom vulnerability within the current organization
* Introduced support for Level CSV download option
* Enabled SBOM export as FDA specific Excel
* Dynamic addition of custom fields to vulnerability CSV Export

### :hand\_splayed: Enhancements

* Improved validation for vulnerability ID uniqueness
* Enhanced SBOM build drawer with supplier fields
* Refined SBOM general tab
* Updated vulnerability card layout
* Implemented context-sensitive label menu
* Updated product settings tooltip
* Improved SBOM actions and components
* Refined product details and ShareLynk table components
* Added vulnerability indicator to components
* Enabled delete feature for dependency\_of relationships

### :hammer\_pick: Bug Fixes

* Fixed crash when component vulnerability is null in component VEX update API
* Resolved timeout issues in organization vulnerability queries
* Corrected severity filter functionality
* Fixed crash in daily metrics job
* Resolved issues with SBOM download options
* Corrected custom field bugs in CSV export
* Fixed vulnerability count display before scanning
* Resolved key prop and React ref warnings
* Fixed progress bar overflow issue
* Corrected inconsistencies in global and product vulnerability views
* Addressed ShareLynk SVG link preview issues
* Fixed SBOM modal and drawer inconsistencies

## v2.9.8

**December 5th, 2024**

### :star: Highlights

* Enhanced Vulnerability Management: Introduced features to identify and manage vulnerabilities, including custom vulnerability additions and updates.
* Improved User Interface: Multiple UI enhancements across SBOM components, license management, and analytics.
* PDF Export Improvements: Fixed critical PDF export issues and added dynamic custom fields for export.
* Performance Optimization: Removal of unused libraries, variables, and static media to streamline builds and improve performance.

### :new: New Features

* Custom Vulnerability Addition: Add and manage custom vulnerabilities for SBOMs (#4996).
* Label Filtering: Added label-based filtering for analytics and part selection (#5021, #5053).
* CSV Export: Enabled CSV export for the support tab (#5040).
* SBOM PDF Enhancements: Dynamic custom fields added to SBOM PDF exports (#5064).
* Vulnerability Scanning: Auto vulnerability scan triggered upon adding or updating custom vulnerabilities (#1763).
* Order-by Search Support: Added support for ordering search results (#1751).<br>

### :hand\_splayed: Enhancements

* Component Management: Updated the component tree, state, info modal, and expand views for a more streamlined experience (#4983, #4979, #5033, #5059).
* UI Updates: Improved styling for tools page, license expand views, and editors (#5062, #5060, #5037).
* Improved Validation: Enhanced error handling for invalid CPE checks and custom vulnerabilities (#4999, #5050).
* Analytics Page: Added new environment filters and updated analytics components (#5034).
* Automation Rules: Introduced a toast notification for rule generation and added “contains” to automation rules (#5012, #1762).

### :hammer\_pick: Bug Fixes

* Search Functionality: Fixed SBOM search field and duplicate SBOM transfer issues (#4997, #1773).
* License Modal: Addressed UI and error handling issues (#4990).
* PDF Export: Resolved issues in PDF export, including vulnerability and parts details (#5041, #5063).
* PURL and CPE Editors: Fixed styling, validation, and search options for better usability (#5037, #5017).
* Component Validation: Fixed issues with component supplier validation and other vulnerabilities (#5004, #5051).
* SBOM Reprocessing: Automatically reprocess SBOMs upon updates to primary (#1767).
* Code Refactoring: Updated global styles, removed unused components, and replaced tooltips for consistency (#4986, #5014, #5015).
* Library Updates: Bumped dependencies for cross-spawn, http-proxy-middleware, and rollup for security and compatibility (#4940, #4673, #4476).
* Error Handling: Improved error messages and validation for various operations (#5032, #5054).
* Build Optimization: Improved build times by removing unwanted media files and unused variables (#5025, #5036).

## v2.9.7

**November 27, 2024**

### :star: Highlights

* 🚀 Improved User Experience: Enhanced workflows in component creation, SBOM management, and vulnerability analysis.
* 🔒 Advanced Security Features: Added safeguards and improvements to ensure compliance and data integrity.
* 📄 SBOM Enhancements: Seamless SBOM transfer between environments and new export fixes.

### :new: New Features

* Custom Vulnerabilities: Add and manage vulnerabilities tailored to your specific needs.
* SBOM Management: Transfer SBOMs between environments and streamline SBOM list interactions.
* Enhanced License Handling: Custom license transformations and text display improvements.
* Component Tree Updates: Added primary paths, dependency tagging, and action enhancements.
* Accessibility Improvements: Fixed button and image accessibility issues.

### :hammer\_pick: Bug Fixes

* Fixed validation errors in component creation and updates.
* Corrected user permission issues for Viewer roles.
* Resolved analytics bugs for environment selections.
* Fixed parts navigation and dependency linking issues.

### :person\_running: Performance Improvements

* Addressed deadlock issues and optimized PURL normalization.

### :hand\_splayed: UI Enhancements

* Updated SBOM author tags with tooltips and reordered columns for better usability.
* Fixed alignment and modal display inconsistencies.
* Removed unused code and integrated consistent Chakra components.

## v2.9.6

**November 19, 2024**

### :star: Highlights

* **Enhanced Usability:** Improved support for large SBOM files, reducing UI freezing and enhancing download/edit functionality
* **Advanced Graph Support:** Added directional support for the relationship graph view, making visualization more intuitive.
* **Improved Validation:** Introduced license expression validation and refined product and vulnerability input handling.
* **Streamlined Error Management:** Fixed upload error handling and enhanced modal behaviors for better error visibility.

### :new: New Features

* **Directional Relationship Graph View:** Graph views now support directional visualization for better clarity.
* **License Expression Validator:** A new feature to validate license expressions during uploads.
* **Trace View for E2E Tests:** Trace view support added for end-to-end tests on CI, aiding debugging and performance insights.
* **Vulnerability & Component Matching:** Enhanced logic for matching vulnerabilities and components by intersecting names.
* **EPSS Score:** Null values are now allowed, ensuring flexibility in data input.
* **Status Field:** Made optional to accommodate partial inputs.
* **Vulnerability Field:** Can now be left blank if applicable.

### :hammer\_pick: Bug Fixes

* Fixed edit and download button issues for large SBOMs.
* Reduced chances of UI freezing with large files.
* Error Handling Enhancements: Improved error handling during upload and reprocess actions. • Fixed issues with reset and indication in the VEX update flow.
* Enhanced VEX import table and history drawer with custom fields.
* Relationship Graph and Table Refinements:
* Resolved issues with vulnerability link forms and table action buttons.
* Addressed bugs in relationship deletion modals.
* Updated component linking in the vulnerabilities tab. • Improved import vulnerability status UI.
* Resolved e2e test issues, including product deletion and label validation.
* Updated SBOM files and product creation validation for tests.

***

## v2.9.5

**November 14, 2024**

### :star: Highlights

* **Custom VEX Fields:** Easily manage and add customized VEX (Vulnerability Exploitability Exchange) fields for better vulnerability tracking.
* **License Notifications:** Receive notifications related to software license compliance and updates.
* **Enhanced Export Options:** Seamlessly export and import End of Support (EOS) data, along with improved SBOM PDF layouts.
* **Component Dependency Tree:** Visualize and analyze component dependencies within the platform to understand the structure and potential vulnerabilities better.
* **SBOM PDF Enhancements:** Added missing labels, data mappings, and refined layout for better readability and compliance with export needs.

### :hand\_splayed: Improvements

* **UI/UX Refinements**
  * Updated mailer font styling, component subheaders, and the integration tab name for improved navigation.
  * Enhanced search functionality for better score filtering.
  * New tooltip and styling across lists, modals, and menus for a more consistent experience.
  * Updated dashboard header and increased search bar width for quicker data access.
* **Policy and Automation**
  * New SB-HC-25 checks implemented for enhanced policy adherence.
  * Automated validation added to streamline creating and managing automation rule&#x73;**.**
* **Data Handling**
  * Filtering for unknown ecosystem entries and handling of null values to enhance data integrity.
  * Improved CSV and PDF exports, ensuring only relevant data is included.
* **Notifications:**
  * Refined notification settings, including adherence to personal settings for targeted updates.

### :hammer\_pick: Fixes

* **Component and Vulnerability Updates**
  * Resolved issues in the component update process, including null strings and prefix issues.
  * Fixed vulnerabilities and licensing data in the global vulnerability table.
  * Enhanced form validation across VEX forms and vulnerability tables to ensure data accuracy.
* **SBOM and Export Refinements**
  * Fixed issues with CSV filter and export, ensuring reliable downloads.
  * Improved logic for filtering out disabled products and maintaining format consistency.
* **UI Bug Fixes**
  * Corrected layout bugs, icon placements, and button spacing across several views.
  * Addressed vulnerabilities in navigation and vulnerability status indication.

***

## v2.9.4

**November 4, 2024**

### :new: **Features**

* SBOM Enhancements
* Added SPDX Lite export support
* Implemented PDF export functionality
* Enhanced SBOM phases management
* Added flag to indicate SBOM reprocess status
* Authentication & Security
* Added unauthenticated access support for organization requests
* Improved request workflow for public APIs
* Enhanced password security mechanisms
* User Experience
* Redesigned email templates and footer
* Updated SBOM upload request UI
* Improved organization selector interface

### :person\_running: Performance Improvements

* Optimized policy count logic
* Enhanced SBOM request flow
* Fixed component health score calculations

### :hammer\_pick: Bug Fixes

* Resolved policy matching for SPDX ID
* Fixed CPE error in component support
* Addressed SBOM level policy result metrics
* Fixed license search and validation issues
* Resolved multiple clicks on upload SBOM button

### :test\_tube: Testing & Quality

* Added comprehensive E2E tests for core functionalities
* Enhanced validation for SBOM phases
* Improved error handling and user feedback

***

## v2.9.3

**October 24, 2024**

### :star: SBOM Enhancements

* Added support for CPE 2.2
* Introduced SBOM lifecycle management
* Improved SBOM export functionality with exclude parts option
* New upload request UI for SBOM

### :unlock: Security & Automation

* Implemented automation rules for internal component checking
* Enhanced CPE finder with improved exact match and prefix search prioritization
* Added internal Slack monitoring system
* Fixed component evaluator for less\_than, more\_than, and range operations

### :hand\_splayed: **UI/UX Improvements**

* Comprehensive CSV export functionality for multiple views
* Updated organization and environment selectors
* Refined label management system
* Enhanced dashboard filters and analytics

***

## v2.9.1

**October 17, 2024**

### :new: Features & Enhancements

* **SBOM Lifecycle Support (UI Pending)**: Added functionality to manage SBOM lifecycles phases, streamlining compliance workflows. (#1634)
* **SBOMs Count Availability**: SBOMs count is now accessible through Sharelynk for easier tracking. (#1625)
* **Notification for Manual Policy Scans**: Implemented a notification system for manual policy scan results, keeping you informed. (#1611)
* **Email Template Overhaul**: Introduced a new email template as part of a unified email strategy. (#1624)
* **CSV Export for Enhanced Reporting**: Now export data from the Global Vulnerability Detail View and SBOM Components View. (#4599)
* **Loader for Policy Violation Counts**: Displays a loader instead of zero when a policy scan is in progress, providing a more accurate view. (#4530)
* **Product Permission Renaming**: Updated "Archive Product" permission to "Delete Product" for better clarity. (#1631)
* **Async Scroll for Product Breadcrumbs**: Improved user experience with a new asynchronous scrolling component. (#4576)
* **End-to-End Testing Improvements**: Expanded E2E tests to cover more features, such as internal component CRUD. (#4607)
* **Custom Mobile Warnings and Device View Updates**: Added custom warnings for mobile users and refined the device warning views. (#4591, #4610)

### :hammer\_pick: Fixes

* **Logout After Email Confirmation**: Users will be logged out upon confirming their email if they are already logged in, enhancing security. (#1626)
* **SPDX Export and Import Issues**: Resolved crashes during SPDX export and fixed duplicate component imports. (#1633)
* **Policy Scan Fixes**: Addressed an issue where policy scans would not complete when using certain parts. (#4586)
* **Ribbon Badge Count Accuracy**: Corrected the display of policy counts on ribbon badges. (#1632)
* **Automation File Naming**: Fixed export file names for automation, ensuring consistency. (#4572)
* **Modal and UI Enhancements**: Resolved issues with modals, such as the archive automation modal close button. (#4577)
* **Playwright and Test Fixes**: Updated playwright report issues and SBOM delete tests. (#4605, #4612)
* **UI Consistency**: Addressed alignment, color scheme, and height issues in various components. (#4564, #4595, #4597)

***

## v2.8.8-HotFix

**October 17, 2024**

* :small\_red\_triangle: An issue was identified, impacting the automation of supplier additions at version level. This has been fixed in this hot-fix release.

***

## v2.8.8

**October 10, 2024**

### :new: **New Features**

* **Component Insights**: Added component insights for better visibility into usage and vulnerabilities (#4496, #4552).
* **SPDX 2.3 Export**: Added export functionality for SPDX 2.3 specification (#1615).<br>
* SBOM Download: You can now download the original SBOM.
* **Slack Notifications**: Notifications for failed E2E tests now sent to Slack, with log URLs included (#4547, #4557).
* **Vulnerability Actions**: Updated vulnerability actions for improved workflow (#4561).
* **JIRA Validation Rule**: Added a validation rule for JIRA ticket creation (#4553).
* **Products Enable/Disable E2E Tests**: Added E2E tests for product enable/disable actions (#4556).

### :hand\_splayed: **Enhancements**

* **UI Updates**: Improved component and vulnerabilities layout, insights preview, and VEX status (#4523, #4552, #4527).
* **Component License Tag**: Updated license tag for better component identification (#4565).
* **SBOM Support Status**: Added visibility for SBOM-related activities (#1586).

### :hammer\_pick: **Fixes**

* **JIRA Link, Component Card, Sidebar, and Search**: Fixed issues with JIRA link, component card display, responsive sidebar, and changelog search (#4541, #4555, #4563, #1563).
* **SPDX Validation and Repo Key**: Resolved SPDX export validation and repo key issues (#1618, #1610).
* **Miscellaneous Fixes**: Addressed sign-up button, E2E label tests, and unit test failures (#4562, #4551, #4549, #4569).

### :broom: **Clean-ups & Miscellaneous**

* **Code Clean-up**: Various clean-ups to improve codebase (#4560).
* **Export and Test Updates**: Fixed export issues and updated specs test actions (#1616, #4571).

***

## v2.8.7

**October 4, 2024**

### :new: Features and Enhancements:

* Refactored the version table and product modal for better structure and performance (#4466, #4475).
* Updated the SBOM vulnerability table and optimized API calls like `GetOrgName` for faster performance (#4463, #4467).
* Several user interface improvements, including:
  * Refactor of PURL and CPE card (#4500).
  * Updated settings header and sidebar with documentation links (#4499, #4529).
  * Improved component edit drawer, modal, and search functionality (#4489, #4516).
  * Added ShareLynk validation and updated validation messages (#4494, #4513).
  * Updated column identifiers and fixed alignment issues in the user table (#4485, #4497).
* Enhanced vulnerability state handling and validation, including vulnerability filters and link validation (#4486, #4515, #4540).
* Fixed multiple UI bugs related to dark color schemes, product updates, and component state issues (#4490, #4491, #4537, #4539).
* Other minor performance improvements and refactors, including E2E tests switched to Linux and improved cron job handling (#4487, #4526).

### :hammer\_pick: **Fixes**

* Fixed vulnerability scanning failures and PURL validation issues (#1599, #4506).
* Resolved bugs like vulnerability expand view, NVD link, and missing dependencies in the version table (#4490, #4524, #4507).
* Fixed issues related to FDA compliance support level and security token initialization (#1575, #4525).
* Several fixes related to Docker and workflow configurations (#1587, #1588, #1589).
* Improved license handling, including case-insensitive search and removed VEX completed check (#1596, #1600).

***

## v2.8.6

**September 26, 2024**

### :new: Features

* **Component Library\[BETA/NOUI]**: Introduced a new component library to streamline UI elements across the platform, enhancing consistency and maintainability.
* **SBOM Support Enhancements**: Updates to the SBOM support query, expanding compatibility and improving query accuracy.
* **Global Custom Date Input**: A custom date input field was introduced for global use, standardizing date selection across multiple features.
* **Manufacturer Modal Improvements**: Added a confirmation modal for archiving manufacturers, improving user interaction with sensitive actions.

### :hammer\_pick: Fixes

* **Error Messaging**: Enhanced error messages for SVG link issues and unexpected errors during automation rule imports.
* **Component Support Updates**: Fixed issues with support updates, including renaming fields and adding new validation checks to prevent errors.
* **Vulnerability Page Fixes**: Adjustments to vulnerability displays, including showing low severity counts and fixing breadcrumb navigation.
* **Playwright Test Fixes**: Multiple fixes and optimizations for Playwright tests to ensure better CI/CD integration and reduce timeouts.

### :hand\_splayed: Enhancements

* **User Interface Updates**: Refined UI in several areas, including the general tab, component type fields, and policy violation counts.
* **Dockerfile and Workflow Optimizations**: Updates to Dockerfile and GitHub Actions workflows for better efficiency, including enabling Docker BuildKit.
* **Search Functionality**: Removed prefix search in favor of substring search for better accuracy in results.
* **Policy and Parts Modal Refactoring**: The policy modal and parts modal were refactored for improved usability and performance.

***

## v2.8.5

**September 19th, 2024**

### :new: Features

* Archive Version Preview: Enabled preview of archived versions with necessary changes (`#4319`).
* Automation Import/Export: Implemented automation import/export feature (`#4403`).
* Component Author: Added support for displaying component author information (`#1539`).
* Component PURL & CPE: Added missing PURL and CPE data for components (`#4374`).
* Docker Image Versioning: Created `Image-version.yml` to track Docker image versions (`#1543`).

### :hammer\_pick: Fixes

* Search Functionality: Resolved issue where search for check ID was not working (`#1531`).
* Expired Invitations: Fixed handling of expired invitations (`#1538`).
* Internal Component Tagging: Fixed component tagging issues (`#1503`, `#4269`).
* Supplier Check: Addressed supplier check issue in SBOM (`#4392`).
* Component Version Validation: Resolved validation issues for component versions (`#4361`, `#4398`).
* Reset Password Page: Fixed reset password link issue (`#4397`).
* Policy View Alignment: Corrected alignment of the policy view (`#4356`).
* SBOM Fixes: Fixed issues in SBOM support table, CPE validation, supplier modal, and details page in customer view (`#4372`, `#4371`, `#4408`, `#4393`).
* Invitation Handling: Resolved additional invitation handling issues (`#4395`).
* Dark Mode Styling: Fixed styling issues in dark mode and license field validation (`#4400`).
* Checks Preview: Fixed logic for previewing checks (`#4399`).

### :hand\_splayed: Enhancements

* Restart Policy: Updated Docker container restart policy to "always" (`#1534`).
* License Updates: Added updated licenses (`#1540`).
* Progress Bar Styling: Enhanced progress bar styling (`#4340`).
* Component Relation Drawer: Added expand action to the component relation drawer (`#4364`).
* General Styling Updates: Updated styling for the general tab, login/register page, and success messages (`#4367`, `#4346`, `#4390`).
* Consolidation & Workflow: Consolidated files and updated workflows accordingly (`#1544`).
* Modal Enhancements: Refined modal consistency and styling (`#4410`, `#4414`).
* Product Status Modal: Enhanced product status modal functionality (`#4421`).

***

## v2.8.4

**September 12, 2024**

### :new: **New Features**

* Added violation count functionality
* Implementation of component unsaved warning
* Update to VEX status view and global vulnerability UI
* Addition of component support tooltip
* Update to authentication UI

### :hand\_splayed: **Improvements**

* Enhanced SBOM (Software Bill of Materials) features:
  * Fixed SBOM table spacing
  * Updated SBOM general tab layout and styling
  * Added info tooltip in SBOM general tab
  * Improved SBOM data license modal
* Refined component management:
  * Updated component end-of-support field
  * Refactored component identifier fields
  * Enhanced component health score view
  * Improved component fields validation
* Enhanced product features:
  * Fixed product search issue
  * Updated product actions preview
* Upgraded policy management:
  * Updated policy stats color
  * Fixed policy count display

### :hammer\_pick: **Bug Fixes**

* Fixed SVG link issues
* Resolved EOL (End of Life) finder problems
* Addressed staging errors from demo data
* Fixed null copyright value on component creation
* Corrected valid expression showing as custom license
* Resolved components create function issues
* Fixed license update problems
* Addressed VEX status modal issues

### :hand\_splayed: **UI/UX Enhancements**

* Various styling improvements across the application
* Fixed compliance card alignment and styling
* Refined dashboard stats alignment
* Updated progress bar functionality
* Implemented dark mode color corrections

### :unlock: **Security and Performance**

* Updated security tokens with required validation
* Upgraded various dependencies for improved security and performance

### :blue\_circle: **Other Changes**

* Removed SBOM reprocess option from customer view
* Removed label option from free tier accounts
* Updated free tier limits
* Various settings and modal fixes
* Environment configuration updates for staging and production

### :small\_red\_triangle: **Known Issues**

* Product Vuln tab "set status" crashes
* In the component Edit tab, if you click save on a component, even if no changes are made, it throws a no-component error.
* Ctrl-K search has settings navigations not working correctly.

***

## 2.8.0

**September 4, 2024**

### :new: New Features

* Added SSO support (Google & Github)
* Introduced request functionality for plan upgrades.
* Enabled component-level support information and exposed it on the SBOM support page.
* Added new fields and updated views like compliance warning for disabled checks, component copyright field, connection tab renaming, and vulnerability info page redesign.
* Improved UI for the SBOM upload modal, label filter dropdown, and compliance drawer.

### :hammer\_pick: Bug Fixes

* Fixed various UI issues, including compliance tab, select styling, component drawer, vex completed filter, SBOM parts UI, policy violation drawer, organization register modal, breadcrumb fetching, product filter in global vulnerability page, component update function, import wizard, overflow issue in component drawer, and more.
* Fixed modal behaviors including Add/Edit License, Create Role, Create Token, and settings modals.
* Fixed policy stats and SBOM download modal.
* Fixed config not saving issue, errors, and orphaned dependencies.
* Ensured consistency in documentation.

### :hand\_splayed: UI Improvements

* Enhanced support delete modal, SBOM build drawer, organization table, product label filter, compliance tab design, login page (privacy policy and terms of services), compliance description, and compliance tab with new design.
* Improved component dependency view, label dropdown, label filter instructions, product page, and label size.
* Refined styling and layout consistency for various UI components.

### :bulb:Miscellaneous

* Added a flag for invalidating entries in the CPE info table.
* Updated the demo name and description.
* Refactored component vulnerability scope in the resolver.
* Updated staging environment settings and hostnames.
* Made modal fixes and other general settings changes.

## 2.7.9

**August 27, 2024**

### :new: New Features

* Labels \[GA]
* Free Tier \[Beta]
* Demo account seed data
* Compliance Tab
* Component Library alpha (No user-facing data as yet)
* AWS marketplace integration alpha

### :hammer\_pick: Bug Fixes

* Limit server log files to 100MB
* Various fixes for notifications.
* Sanitize and remove bad data from SBOMs.
* Refetch refactor in UI, for consistent performance.
* Modal consistency fixes.
* Tons for additional fixes and consistency improvements.

***

## 2.7.8

**August 15th, 2024**

### :new: New Features

* Version Archive Support - Individual versions can now be archived. Archival removes the version from all metrics, vulnerabilities & policies.
* Notification Support - We support personal & organization level notification support. Notifications are supported over Email/Slack & Teams. This is an early release; currently we support only Sbom upload/failures & Vuln report scans. More notifications will be added on an ongoing basis.
* Labels Support: Products can now be labelled for easy management.

### :hammer\_pick: Bug Fixes

* Permanent fix for Delete Role crash.
* Checks does not flag an sbom with a single component with relationship failure.
* Text alignment for SBOM Card.
* Product Listing fixes a bunch of them.
* Version Compare fixes.
* Toast bar notification consistency.

## 2.7.7

**August 1st, 2024**

### :new: New Features

* PURL & CPE vulnerabilities are merged, producing a single list of vulnerabilities by component.
* Product Progress Graph \[ Demo account only ]

### :hammer\_pick: Bug Fixes

* Compliance score fixes
  * Other identifiers now take into account either CPE or PURL
  * Comp suppliers accounting issue.
* Migration to remove old roles
* Fixed permissions wipe out
* Invalid PURL crash fix
* Updated info tooltips
* Google Analytics fixes


# Interlynk API

Upload, download, and manage SBOMs on the Interlynk platform with a GraphQL API. Every example in these docs uses curl.

The Interlynk API lets you automate everything you can do in the Interlynk dashboard: upload SBOMs, download them in CycloneDX or SPDX, edit metadata, review vulnerabilities, and apply VEX.

The API is GraphQL. There is one endpoint, and it handles both reads (queries) and writes (mutations).

```
https://api.interlynk.io/lynkapi
```

## How to read these docs

Every request in this documentation is a `curl` command you can copy, paste, and run. Set your security token as an environment variable first and the examples will work as written:

```bash
export INTERLYNK_SECURITY_TOKEN="lynk_live_xxxxxxxxxxxxxxxxxxxx"
```

If you use the platform from a CI pipeline or a script in another language, the same requests apply. GraphQL over HTTP is just a `POST` with a JSON body.

## Start here

| Page                                                  | What it covers                                            |
| ----------------------------------------------------- | --------------------------------------------------------- |
| [Authentication](/api/getting-started/authentication) | Create a security token and make an authenticated request |
| [Quickstart](/api/getting-started/quickstart)         | Your first API call, end to end                           |
| [Data Model](/api/concepts/data-model)                | Products, environments, versions, and components          |

## Common tasks

| Guide                                                            | Use it to                                                |
| ---------------------------------------------------------------- | -------------------------------------------------------- |
| [Upload an SBOM](/api/managing-sboms/upload-sbom)                | Push an SBOM file to a product                           |
| [Download an SBOM](/api/managing-sboms/download-sbom)            | Pull an SBOM in CycloneDX or SPDX                        |
| [List Products and Versions](/api/inventory/list-resources)      | Find the IDs you need for other calls                    |
| [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     | Add or change SBOM authors and suppliers                 |
| [Edit a Component](/api/inventory/edit-component)                | Change a component's license, copyright, or other fields |
| [Vulnerabilities and VEX](/api/security/vulnerabilities-and-vex) | List vulnerabilities and set VEX status                  |
| [Manage Notifications](/api/security/notifications)              | Control notification settings, preferences, and channels |
| [Manage Users and Roles](/api/user-management/user-management)   | Invite users, set roles, and configure SSO               |

## Prefer a CLI?

[`pylynk`](https://github.com/interlynk-io/pylynk) is the official command-line tool. It wraps the same API and is a good fit for CI/CD pipelines. These docs cover the raw API for everyone who wants to call it directly.


# Authentication

The Interlynk API authenticates every request with a security token sent in the `Authorization` header.

## Token types

There are two kinds of token. Pick the one that matches how you will use the API.

|                           | Personal token                       | Service token                          |
| ------------------------- | ------------------------------------ | -------------------------------------- |
| Belongs to                | A user                               | The organization                       |
| Role                      | Inherits the user's role             | An explicit role you choose            |
| Survives the user leaving | No                                   | Yes                                    |
| Prefix                    | `lynk_live_...`                      | `lynk_service_live_...`                |
| Best for                  | Manual use, scripts you run yourself | CI/CD, automation, shared integrations |

{% hint style="success" %}
**For CI/CD integrations, use a service token.** A personal token stops working when the person who created it loses access or leaves the organization, which breaks the pipeline. A service token belongs to the organization and has its own role, so it keeps running independently of any one user.
{% endhint %}

## Create a personal token

1. Log in to the [Interlynk dashboard](https://app.interlynk.io).
2. Click **Settings** in the left-hand bar.
3. Click **Personal** in the top right.
4. Click **Security Tokens**.
5. Click **+** to generate a new token.

Give the token a name and an expiration date. Pick the shortest expiration that fits your use case.

A personal token looks like this:

```
lynk_live_CgzGW2qLk5C73o7SgsKyBT3wVcm**********
```

## Create a service token

Create a service token from your organization settings in the dashboard. A service token has two properties:

* A **name**, so you can identify it later.
* A **role**, which sets exactly what the token is allowed to do.

A service token looks like this:

```
lynk_service_live_CgzGW2qLk5C73o7SgsKyBT3wVcm**********
```

Give a CI/CD service token the least-privileged role that still lets the pipeline do its job. For a pipeline that only uploads SBOMs, a role without delete or admin rights is enough.

{% hint style="warning" %}
Copy the token as soon as it is generated. You cannot retrieve it again after you close the window. Store it as a secret in your CI/CD platform, never in the repository.
{% endhint %}

## Token permissions

A personal token inherits the role of the user who created it. A token created by an admin has admin privileges. A service token uses the role you assign when you create it.

Either way, give the token the least privilege the integration needs.

## Use the token

Both token types are used the same way. Send the token as a bearer token on every request:

```
Authorization: Bearer lynk_live_xxxxxxxxxxxxxxxxxxxx
```

Store it in an environment variable so it stays out of your shell history and your scripts:

```bash
export INTERLYNK_SECURITY_TOKEN="lynk_live_xxxxxxxxxxxxxxxxxxxx"
```

## Verify it works

This request returns your organization's name. If the token is valid, you get a name back.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { id name } }"}'
```

Response:

```json
{
  "data": {
    "organization": {
      "id": "72219448-e3cf-47f4-8e54-49199fc47f52",
      "name": "Acme Corp"
    }
  }
}
```

If the token is missing or wrong, the API returns HTTP `401`:

```json
{
  "errors": [
    { "message": "Unauthorized", "extensions": { "code": "UNAUTHORIZED" } }
  ]
}
```

See [Errors](/api/reference/errors) for the full list of failure modes.


# Quickstart

This page walks through a single API call from start to finish. It assumes you have a security token. If you do not, see [Authentication](/api/getting-started/authentication).

## 1. Set your token

```bash
export INTERLYNK_SECURITY_TOKEN="lynk_live_xxxxxxxxxxxxxxxxxxxx"
```

## 2. Make a request

The API has one endpoint. You always send a `POST` with a JSON body.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { id name } }"}'
```

```json
{
  "data": {
    "organization": {
      "id": "72219448-e3cf-47f4-8e54-49199fc47f52",
      "name": "Acme Corp"
    }
  }
}
```

## Anatomy of a request

The JSON body has up to three keys:

| Key             | Required | Purpose                                                         |
| --------------- | -------- | --------------------------------------------------------------- |
| `query`         | Yes      | The GraphQL query or mutation string                            |
| `variables`     | No       | Values referenced by the query, as a JSON object                |
| `operationName` | No       | Names the operation when the query string defines more than one |

A request with variables looks like this:

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query GetSbom($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { id projectVersion } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    },
    "operationName": "GetSbom"
  }'
```

Variables keep IDs and user input out of the query string, which makes requests easier to build and safer to script.

{% hint style="info" %}
Queries read data. Mutations change data. Both go to the same endpoint as a `POST`. Uploads are the one exception: they use `multipart/form-data` instead of a JSON body. See [Upload an SBOM](/api/managing-sboms/upload-sbom).
{% endhint %}

## Next steps

* Learn how the platform is organized in the [Data Model](/api/concepts/data-model).
* [List your products and versions](/api/inventory/list-resources) to get the IDs other calls need.
* [Upload](/api/managing-sboms/upload-sbom) or [download](/api/managing-sboms/download-sbom) an SBOM.


# Data Model

Before you call the API, it helps to know how Interlynk organizes data. Four levels nest inside your organization.

```
Organization
└── Product            (a piece of software you track)
    └── Environment    (default, development, production, ...)
        └── Version    (one uploaded SBOM)
            └── Component   (a dependency inside that SBOM)
```

## The four levels

| Level           | What it is                                                                                      |
| --------------- | ----------------------------------------------------------------------------------------------- |
| **Product**     | A piece of software you track, for example `payments-service`.                                  |
| **Environment** | A stage within a product. Every product starts with `default`, `development`, and `production`. |
| **Version**     | A single SBOM uploaded to an environment. Each upload creates a new version.                    |
| **Component**   | One dependency listed inside a version's SBOM.                                                  |

When you upload an SBOM, you upload it to a product and an environment. The upload becomes a new version.

## Dashboard names vs API names

The GraphQL schema uses different names than the dashboard. They mean the same things. You will see the API names in queries and responses.

| Dashboard   | GraphQL schema |
| ----------- | -------------- |
| Product     | `projectGroup` |
| Environment | `project`      |
| Version     | `sbom`         |
| Component   | `component`    |

So a product's ID is the `id` of a `projectGroup`, an environment's ID is the `id` of a `project`, and a version's ID is the `id` of an `sbom`.

{% hint style="info" %}
Two field names trip people up. A version ID is called `sbomId` in most queries. An environment ID is called `projectId`. Keep that in mind when you read the [download](/api/managing-sboms/download-sbom) and [upload](/api/managing-sboms/upload-sbom) guides.
{% endhint %}

## Identifiers

Every object has a UUID `id`, for example `4e423fe0-d089-4025-b1e4-8fe9608138d6`. Most calls need one or more of these IDs.

You can refer to objects two ways:

* **By ID.** Pass the UUID directly. This is exact and fast.
* **By name.** Some calls accept a product name and environment name instead. Useful when you do not have IDs yet, for example in a build script.

To find IDs, see [List Products and Versions](/api/inventory/list-resources).


# Upload an SBOM

Uploading creates a new version inside a product's environment. Each upload is a new version, so you do not overwrite anything.

Uploads are the one API call that does not use a JSON body. A file upload over GraphQL uses `multipart/form-data`, following the [GraphQL multipart request spec](https://github.com/jaydenseric/graphql-multipart-request-spec). The sections below show exactly what that means for curl.

## The request

A multipart upload sends three parts:

| Part         | Contents                                                                             |
| ------------ | ------------------------------------------------------------------------------------ |
| `operations` | The GraphQL mutation and its variables, as JSON. The file variable is set to `null`. |
| `map`        | Tells the server which uploaded file fills which variable.                           |
| `0`          | The SBOM file itself. The part name (`0`) matches the key in `map`.                  |

## Upload by product name

The simplest form. Name the product and environment, and the API resolves them.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

A successful upload returns an empty `errors` list:

```json
{
  "data": {
    "sbomUpload": {
      "errors": []
    }
  }
}
```

{% hint style="info" %}
Do not set `Content-Type` yourself. When you use `-F`, curl sets `multipart/form-data` with the correct boundary automatically.
{% endhint %}

## Upload by ID

If you already have a product ID and environment ID, pass them instead of names. IDs are exact and skip the name lookup.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupId: ID, $projectId: ID) { sbomUpload(input: { doc: $doc, projectGroupId: $projectGroupId, projectId: $projectId }) { errors } }","variables":{"doc":null,"projectGroupId":"26ae44b7-2f68-4cf4-a405-d5ee0177bb11","projectId":"1fade833-0603-4139-8ca0-26592264a4c9"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

## Choosing where it goes

`sbomUpload` accepts these target inputs. Pass the product and the environment.

| Input              | Type   | Identifies                                                    |
| ------------------ | ------ | ------------------------------------------------------------- |
| `projectGroupName` | String | Product, by name                                              |
| `projectGroupId`   | ID     | Product, by ID                                                |
| `projectName`      | String | Environment, by name (`default`, `development`, `production`) |
| `projectId`        | ID     | Environment, by ID                                            |

If you omit the environment, the upload goes to `default`.

## Supported file formats

* CycloneDX, JSON and XML
* SPDX, JSON and tag-value

## After the upload

A new version is created and the platform starts processing it: vulnerability scanning, automation, and policy checks. The SBOM is not fully ready to download until processing finishes.

* [Check Processing Status](/api/managing-sboms/processing-status) shows how to tell when it is done.
* [List Products and Versions](/api/inventory/list-resources) shows the new version and its ID.

## Errors

If the upload fails, the reason is in the `errors` list:

```json
{
  "data": {
    "sbomUpload": {
      "errors": ["Project group not found"]
    }
  }
}
```

Common causes:

| Message                   | Cause                                                              |
| ------------------------- | ------------------------------------------------------------------ |
| `Project group not found` | The product name or ID does not exist, or the token cannot see it. |
| HTTP `401`                | The token is missing, expired, or wrong.                           |

See [Errors](/api/reference/errors) for more.

## Recording build provenance

When you upload from a CI/CD pipeline, you can attach provenance: the event, commit, build, and repository behind this SBOM. The platform records it with the new version, so you can trace any version back to the build that produced it.

Provenance travels as `X-` HTTP headers on the upload request. The multipart body and GraphQL mutation are unchanged. Every header is optional and independent, so send the ones you have and omit the rest.

This is what the [`pylynk`](https://github.com/interlynk-io/pylynk) CLI does for you automatically. The examples below show how to send the same headers from curl.

### Provenance headers

| Header               | Meaning                                                                              |
| -------------------- | ------------------------------------------------------------------------------------ |
| `X-CI-Provider`      | CI system: `github_actions`, `azure_devops`, `bitbucket_pipelines`, or `generic_ci`. |
| `X-Event-Type`       | What triggered the build: `push`, `pull_request`, or `release`.                      |
| `X-Release-Tag`      | Tag name, for a release or tag build.                                                |
| `X-PR-Number`        | Pull request number.                                                                 |
| `X-PR-URL`           | Pull request URL.                                                                    |
| `X-PR-Source-Branch` | Branch being merged from.                                                            |
| `X-PR-Target-Branch` | Branch being merged into.                                                            |
| `X-PR-Author`        | User who triggered the build.                                                        |
| `X-Build-URL`        | Link to the CI run.                                                                  |
| `X-Commit-SHA`       | Commit hash.                                                                         |
| `X-Repository-URL`   | Repository URL.                                                                      |

### From GitHub Actions

GitHub Actions exposes most of these as built-in variables.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "X-CI-Provider: github_actions" \
  -H "X-Event-Type: $GITHUB_EVENT_NAME" \
  -H "X-Commit-SHA: $GITHUB_SHA" \
  -H "X-PR-Author: $GITHUB_ACTOR" \
  -H "X-Build-URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \
  -H "X-Repository-URL: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

{% hint style="info" %}
A tag push has `GITHUB_REF` like `refs/tags/v1.2.3` and is a release. Add `-H "X-Release-Tag: ${GITHUB_REF#refs/tags/}"`. Pull request fields (number, URL, branches) are not in plain variables; they live in the event payload at `$GITHUB_EVENT_PATH`, which you can read with `jq`.
{% endhint %}

### From Azure DevOps

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "X-CI-Provider: azure_devops" \
  -H "X-Commit-SHA: $BUILD_SOURCEVERSION" \
  -H "X-PR-Number: $SYSTEM_PULLREQUEST_PULLREQUESTID" \
  -H "X-PR-Source-Branch: $SYSTEM_PULLREQUEST_SOURCEBRANCH" \
  -H "X-PR-Target-Branch: $SYSTEM_PULLREQUEST_TARGETBRANCH" \
  -H "X-PR-Author: $BUILD_REQUESTEDFOR" \
  -H "X-Build-URL: ${SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}${SYSTEM_TEAMPROJECT}/_build/results?buildId=$BUILD_BUILDID" \
  -H "X-Repository-URL: $BUILD_REPOSITORY_URI" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

The `SYSTEM_PULLREQUEST_*` variables are only set on pull request builds. On a plain commit, drop the `X-PR-*` headers.

### From Bitbucket Pipelines

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "X-CI-Provider: bitbucket_pipelines" \
  -H "X-Commit-SHA: $BITBUCKET_COMMIT" \
  -H "X-PR-Number: $BITBUCKET_PR_ID" \
  -H "X-PR-Source-Branch: $BITBUCKET_BRANCH" \
  -H "X-PR-Target-Branch: $BITBUCKET_PR_DESTINATION_BRANCH" \
  -H "X-Release-Tag: $BITBUCKET_TAG" \
  -H "X-Build-URL: https://bitbucket.org/$BITBUCKET_WORKSPACE/$BITBUCKET_REPO_SLUG/pipelines/results/$BITBUCKET_BUILD_NUMBER" \
  -H "X-Repository-URL: https://bitbucket.org/$BITBUCKET_WORKSPACE/$BITBUCKET_REPO_SLUG" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

`BITBUCKET_TAG` is set only on tag builds and `BITBUCKET_PR_*` only on pull request builds. Drop whichever headers are empty.

### From any other CI

On any other system, set the headers from whatever variables your CI exposes. Use `generic_ci` as the provider and fill in what you have.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "X-CI-Provider: generic_ci" \
  -H "X-Commit-SHA: $GIT_COMMIT" \
  -H "X-Build-URL: $BUILD_URL" \
  -H "X-Repository-URL: $REPO_URL" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

{% hint style="info" %}
[`pylynk`](https://github.com/interlynk-io/pylynk) detects GitHub Actions, Azure DevOps, and Bitbucket Pipelines and sets all of these headers automatically. If you already run it in your pipeline, you get provenance without any of the above.
{% endhint %}

## Retrying failed uploads

In a CI/CD pipeline, a single upload attempt is not reliable. Network blips, rate limits, and brief server errors all cause failures that succeed on a retry. Retry transient failures with exponential backoff, and fail fast on permanent ones like a bad token.

### Which failures to retry

Retrying a bad token wastes time and never succeeds. Retrying a server error often works on the next attempt.

| Failure                           | Retry? | Why                                                                     |
| --------------------------------- | ------ | ----------------------------------------------------------------------- |
| Network error or timeout          | Yes    | Transient. The next attempt usually connects.                           |
| HTTP 429 (rate limited)           | Yes    | The server is asking you to slow down. Back off and retry.              |
| HTTP 500, 502, 503, 504           | Yes    | Transient server error.                                                 |
| HTTP 401 (unauthorized)           | No     | The token is wrong or expired. Fix it.                                  |
| HTTP 400, 403, 404                | No     | The request is wrong. Retrying sends the same bad request.              |
| HTTP 200 with `sbomUpload.errors` | No     | The upload was rejected, for example an unknown product. Fix the input. |

Between retries, wait longer each time. Doubling the delay (1s, then 2s, then 4s) gives the API room to recover and avoids a tight retry loop. This is exponential backoff.

### Option 1: curl's built-in retry

curl has exponential backoff built in. The `--retry` flag retries transient failures and doubles the wait between attempts on its own.

```bash
curl --retry 5 --retry-connrefused --fail-with-body \
  https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json
```

| Flag                  | Effect                                                                   |
| --------------------- | ------------------------------------------------------------------------ |
| `--retry 5`           | Retry up to 5 times. curl waits 1s, then 2s, 4s, 8s, doubling each time. |
| `--retry-connrefused` | Also retry when the connection is refused.                               |
| `--fail-with-body`    | Exit non-zero on an HTTP error, but still print the response body.       |

{% hint style="info" %}
Do not add `--retry-delay`. Setting a fixed delay turns off curl's exponential backoff. Leave it off and the delay doubles automatically.
{% endhint %}

curl's `--retry` retries the transient cases for you: timeouts and HTTP 408, 429, 500, 502, 503, and 504. It does not retry 401 or other 4xx errors, which is what you want.

What `--retry` cannot see is a GraphQL-level rejection. If the API returns HTTP `200` with a non-empty `sbomUpload.errors` list, curl treats the request as a success. Always check that field yourself:

```bash
RESPONSE=$(curl -s --retry 5 --retry-connrefused \
  https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -F operations='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"payments-service","projectName":"default"}}' \
  -F map='{"0":["variables.doc"]}' \
  -F 0=@my-sbom.cdx.json)

if [ "$(echo "$RESPONSE" | jq -r '.data.sbomUpload.errors | length')" != "0" ]; then
  echo "Upload rejected: $(echo "$RESPONSE" | jq -c '.data.sbomUpload.errors')"
  exit 1
fi
echo "Upload succeeded."
```

This option is enough for most pipelines.

### Option 2: a retry script

When you want full control, for example to log each attempt or to treat the GraphQL `errors` field as a hard stop, use an explicit loop.

```bash
#!/usr/bin/env bash
set -euo pipefail

ENDPOINT="https://api.interlynk.io/lynkapi"
SBOM_FILE="my-sbom.cdx.json"
PRODUCT="payments-service"
ENVIRONMENT="default"
MAX_ATTEMPTS=4   # 1 initial attempt + 3 retries

OPERATIONS='{"query":"mutation uploadSbom($doc: Upload!, $projectGroupName: String, $projectName: String) { sbomUpload(input: { doc: $doc, projectGroupName: $projectGroupName, projectName: $projectName }) { errors } }","variables":{"doc":null,"projectGroupName":"'"$PRODUCT"'","projectName":"'"$ENVIRONMENT"'"}}'

attempt=1
while true; do
  body=$(mktemp)
  # %{http_code} is the HTTP status; "000" means curl could not reach the server.
  status=$(curl -s -o "$body" -w '%{http_code}' "$ENDPOINT" \
    -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
    -F operations="$OPERATIONS" \
    -F map='{"0":["variables.doc"]}' \
    -F 0=@"$SBOM_FILE" || echo "000")

  if [ "$status" = "200" ]; then
    errors=$(jq -c '.data.sbomUpload.errors' < "$body")
    rm -f "$body"
    if [ "$errors" = "[]" ]; then
      echo "Upload succeeded."
      exit 0
    fi
    # Rejected by the API. This is permanent, do not retry.
    echo "Upload rejected: $errors"
    exit 1
  fi
  rm -f "$body"

  # Permanent HTTP failures: fix the request, do not retry.
  if [ "$status" = "401" ] || \
     { [ "$status" -ge 400 ] 2>/dev/null && [ "$status" -lt 500 ] && [ "$status" != "429" ]; }; then
    echo "Upload failed with HTTP $status. Not retrying."
    exit 1
  fi

  # Transient failure: network error ("000"), 429, or 5xx.
  if [ "$attempt" -ge "$MAX_ATTEMPTS" ]; then
    echo "Upload failed after $attempt attempts. Last status: $status."
    exit 1
  fi

  delay=$(( 2 ** (attempt - 1) ))   # 1s, 2s, 4s
  echo "Attempt $attempt failed (status $status). Retrying in ${delay}s..."
  sleep "$delay"
  attempt=$(( attempt + 1 ))
done
```

This is the same strategy the [`pylynk`](https://github.com/interlynk-io/pylynk) CLI uses: three retries with a 1s, 2s, 4s backoff, no retry on authentication or client errors.

### A note on duplicate versions

Every successful `sbomUpload` creates a new version. There is no upload ID you can reuse to make a retry idempotent.

This matters in one specific case: the server accepts the upload, but the response is lost on the way back to you (a dropped connection at exactly the wrong moment). Your script sees a failure and retries, and the retry creates a second version of the same SBOM.

This is rare and usually harmless, since the versions are identical. If your pipeline cannot tolerate it, after a retry that followed an unclear failure, [list the versions](/api/inventory/list-resources) for that product and environment and remove any duplicate.

### Add jitter for fleets of pipelines

If many pipelines upload at once and all hit a rate limit together, they will all back off by the same amount and retry at the same moment, hitting the limit again. Add a small random delay (jitter) so the retries spread out:

```bash
delay=$(( 2 ** (attempt - 1) ))
jitter=$(( RANDOM % 1000 ))           # 0 to 999 milliseconds
sleep "$(printf '%d.%03d' "$delay" "$jitter")"
```


# Check Processing Status

When you upload an SBOM, the platform runs post-processing on it: automation rules, vulnerability scanning, and policy checks. A version is not fully ready to download until processing finishes.

This guide shows how to check where a version is in that pipeline.

## Quick check: vulnRunStatus

The fastest signal is `vulnRunStatus` on a version. It is part of the [product listing](/api/inventory/list-resources) response, so you often have it already.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Status($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { id projectVersion vulnRunStatus } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }'
```

```json
{
  "data": {
    "sbom": {
      "id": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "projectVersion": "3.0.2",
      "vulnRunStatus": "FINISHED"
    }
  }
}
```

`vulnRunStatus` is `FINISHED` once scanning is done. Before that it reports an in-progress state.

## Per-stage status

The `download` field reports each processing stage separately through `processingStatus`. Use this when you care about a specific stage.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Ready($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { download(sbomId: $sbomId) { ready processingStatus { automation vulnScan policyScan } } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }'
```

```json
{
  "data": {
    "sbom": {
      "download": {
        "ready": true,
        "processingStatus": {
          "automation": "COMPLETED",
          "vulnScan": "COMPLETED",
          "policyScan": "COMPLETED"
        }
      }
    }
  }
}
```

## Wait for processing before downloading

If you want one call that blocks until processing finishes, pass `requireCompleted` to `download` with the stages you need. The stages are `AUTOMATION`, `VULN_SCAN`, and `POLICY_SCAN`.

```graphql
query downloadSbom($projectId: Uuid!, $sbomId: Uuid!,
                   $requireCompleted: [SbomProcessingStageEnum!]) {
  sbom(projectId: $projectId, sbomId: $sbomId) {
    download(sbomId: $sbomId, requireCompleted: $requireCompleted) {
      ready
      content
      processingStatus { automation vulnScan policyScan }
    }
  }
}
```

If a required stage is not done, `ready` comes back `false` and `content` is empty. Poll on a short interval until `ready` is `true`:

```bash
#!/bin/bash
PROJECT_ID="1fade833-0603-4139-8ca0-26592264a4c9"
SBOM_ID="4e423fe0-d089-4025-b1e4-8fe9608138d6"

while true; do
  READY=$(curl -s https://api.interlynk.io/lynkapi \
    -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"query\":\"query(\$p:Uuid!,\$s:Uuid!,\$rc:[SbomProcessingStageEnum!]){sbom(projectId:\$p,sbomId:\$s){download(sbomId:\$s,requireCompleted:\$rc){ready}}}\",\"variables\":{\"p\":\"$PROJECT_ID\",\"s\":\"$SBOM_ID\",\"rc\":[\"VULN_SCAN\"]}}" \
    | jq -r '.data.sbom.download.ready')

  if [ "$READY" = "true" ]; then
    echo "Processing finished."
    break
  fi
  echo "Still processing, waiting 10s..."
  sleep 10
done
```

Once `ready` is `true`, [download the SBOM](/api/managing-sboms/download-sbom).


# Download an SBOM

Downloading returns one version's SBOM. You need two IDs: the environment ID (`projectId`) and the version ID (`sbomId`). Get them from [List Products and Versions](/api/inventory/list-resources).

The SBOM content comes back base64-encoded inside the JSON response. You decode it to get the file.

## The request

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query downloadSbom($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { download(sbomId: $sbomId) { ready content contentType filename } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }'
```

Response:

```json
{
  "data": {
    "sbom": {
      "download": {
        "ready": true,
        "content": "ewogICJib21Gb3JtYXQiOiAiQ3ljbG9uZURYIiwK...",
        "contentType": "application/json",
        "filename": "payments-service.cdx.json"
      }
    }
  }
}
```

| Field         | Meaning                                                        |
| ------------- | -------------------------------------------------------------- |
| `ready`       | `true` when the SBOM is processed and content is included.     |
| `content`     | The SBOM file, base64-encoded.                                 |
| `contentType` | MIME type of the decoded file, for example `application/json`. |
| `filename`    | Suggested filename. May be `null`.                             |

## Decode the content

The `content` field is base64. Pipe the response through `jq` and `base64` to write the SBOM straight to a file:

```bash
curl -s https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query downloadSbom($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { download(sbomId: $sbomId) { ready content } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }' \
  | jq -r '.data.sbom.download.content' | base64 -d > sbom.json
```

`sbom.json` now holds the CycloneDX or SPDX document.

## Download options

Pass extra variables to control format and content. Add them to `variables` and to the `download(...)` arguments.

| Variable               | Type       | Effect                                                                |
| ---------------------- | ---------- | --------------------------------------------------------------------- |
| `spec`                 | `SbomSpec` | Output format: `CycloneDX` or `SPDX`.                                 |
| `specVersion`          | String     | Spec version, for example `1.6` or `2.3`.                             |
| `includeVulns`         | Boolean    | Include known vulnerabilities in the SBOM.                            |
| `original`             | Boolean    | Return the exact file that was uploaded, with no platform processing. |
| `lite`                 | Boolean    | Return a lighter SBOM with reduced metadata.                          |
| `excludeParts`         | Boolean    | Exclude linked or nested part SBOMs.                                  |
| `includeSupportStatus` | Boolean    | Add support-status information to components.                         |

Example, download as SPDX 2.3 with vulnerabilities:

```bash
curl -s https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query downloadSbom($projectId: Uuid!, $sbomId: Uuid!, $spec: SbomSpec, $specVersion: String, $includeVulns: Boolean) { sbom(projectId: $projectId, sbomId: $sbomId) { download(sbomId: $sbomId, spec: $spec, specVersion: $specVersion, includeVulns: $includeVulns) { ready content } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "spec": "SPDX",
      "specVersion": "2.3",
      "includeVulns": true
    }
  }' \
  | jq -r '.data.sbom.download.content' | base64 -d > sbom.spdx.json
```

## When the SBOM is not ready

A version is not downloadable until the platform finishes processing it. If you download too soon, `ready` is `false` and `content` is empty.

To make the API wait for processing, pass `requireCompleted` with the stages you need. Ask `download` for `processingStatus` so you can see what is pending.

```graphql
query downloadSbom($projectId: Uuid!, $sbomId: Uuid!,
                   $requireCompleted: [SbomProcessingStageEnum!]) {
  sbom(projectId: $projectId, sbomId: $sbomId) {
    download(sbomId: $sbomId, requireCompleted: $requireCompleted) {
      ready
      content
      processingStatus { automation vulnScan policyScan }
    }
  }
}
```

Valid stages: `AUTOMATION`, `VULN_SCAN`, `POLICY_SCAN`.

If `ready` is still `false`, wait and retry. See [Check Processing Status](/api/managing-sboms/processing-status) for the full pattern.


# Edit SBOM Metadata

You can change a version's metadata through the API: who authored the SBOM, who supplies it, and the license that governs the document itself. This guide covers SBOM authors, suppliers, and the data license.

{% hint style="info" %}
**Author of the SBOM vs author of a component.** An SBOM has authors, the people or tools that produced the document. This maps to `metadata.authors` in CycloneDX. A *component* inside the SBOM also has an `author` field, but that one is read-only through the API: it is set when the SBOM is ingested and cannot be changed with a mutation. To edit component-level fields you can change, see [Edit a Component](/api/inventory/edit-component).
{% endhint %}

Every call here needs the version ID (`sbomId`). Get it from [List Products and Versions](/api/inventory/list-resources).

## Add an author

`authorCreate` adds an author to a version.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation AddAuthor($sbomId: Uuid!, $name: String!, $email: String, $phone: String) { authorCreate(input: { sbomId: $sbomId, name: $name, email: $email, phone: $phone }) { author { id name email phone } errors } }",
    "variables": {
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "name": "Jane Doe",
      "email": "jane@example.com"
    }
  }'
```

```json
{
  "data": {
    "authorCreate": {
      "author": {
        "id": "b1c2d3e4-0000-0000-0000-000000000001",
        "name": "Jane Doe",
        "email": "jane@example.com",
        "phone": null
      },
      "errors": []
    }
  }
}
```

| Input    | Type   | Required                               |
| -------- | ------ | -------------------------------------- |
| `sbomId` | Uuid   | Yes. The version to add the author to. |
| `name`   | String | Yes.                                   |
| `email`  | String | No.                                    |
| `phone`  | String | No.                                    |

Save the returned `author.id`. You need it to update or delete the author.

## List the authors on a version

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Authors($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { authors { id name email phone } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }'
```

## Update an author

`authorUpdate` changes an existing author. Pass the `authorId` and only the fields you want to change.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation UpdateAuthor($authorId: Uuid!, $sbomId: Uuid!, $email: String) { authorUpdate(input: { authorId: $authorId, sbomId: $sbomId, email: $email }) { author { id name email } errors } }",
    "variables": {
      "authorId": "b1c2d3e4-0000-0000-0000-000000000001",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "email": "jane.doe@example.com"
    }
  }'
```

## Delete an author

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation DeleteAuthor($authorId: Uuid!, $sbomId: Uuid!) { authorDelete(input: { authorId: $authorId, sbomId: $sbomId }) { errors } }",
    "variables": {
      "authorId": "b1c2d3e4-0000-0000-0000-000000000001",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }'
```

## Suppliers

A version also has suppliers. The mutations work the same way as authors:

| Mutation             | Purpose                      |
| -------------------- | ---------------------------- |
| `sbomSupplierCreate` | Add a supplier to a version. |
| `sbomSupplierUpdate` | Change an existing supplier. |
| `sbomSupplierDelete` | Remove a supplier.           |

To set a supplier on an individual component instead of the whole SBOM, see [Edit a Component](/api/inventory/edit-component).

## Set the data license

The data license is the license that governs the SBOM document itself, not the software it describes. In SPDX this is the `dataLicense` field (it defaults to `CC0-1.0`). In the dashboard it shows on the version as the **Data License**.

This is a property of the whole version, so you set it with `sbomUpdate`, not `componentUpdate`. `sbomUpdate` takes the version ID as `id` and a `licenses` object holding an SPDX expression in `licensesExp`:

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetDataLicense($id: Uuid!, $licenses: LicenseInput) { sbomUpdate(input: { id: $id, licenses: $licenses }) { sbom { id licensesExp } errors } }",
    "variables": {
      "id": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "licenses": { "licensesExp": "CC0-1.0" }
    }
  }'
```

```json
{
  "data": {
    "sbomUpdate": {
      "sbom": {
        "id": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
        "licensesExp": "CC0-1.0"
      },
      "errors": []
    }
  }
}
```

{% hint style="info" %}
**Data license vs component license.** `sbomUpdate` with `licenses` sets the license on the SBOM document (the version). The `licenses` field on `componentUpdate` sets the license on a single component inside the SBOM. They use the same `LicenseInputType` and the same `licensesExp` SPDX expression, but they apply at different levels (`LicenseInput`). See [Edit a Component](/api/inventory/edit-component).
{% endhint %}

## Errors

Mutation failures come back in the `errors` list rather than as an HTTP error:

```json
{
  "data": {
    "authorCreate": {
      "author": null,
      "errors": ["Sbom not found"]
    }
  }
}
```

`Sbom not found` means the `sbomId` is wrong or the token cannot access it. See [Errors](/api/reference/errors).


# List Products and Versions

Most API calls need IDs: a product ID, an environment ID, or a version ID. This guide shows how to find them.

## List your products

This returns every product, its environments, and the versions in each environment.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query ListProducts($first: Int) { organization { projectGroups(first: $first, enabled: true, orderBy: { field: PROJECT_GROUPS_UPDATED_AT, direction: DESC }) { totalCount nodes { id name projects { nodes { id name sboms { id projectVersion vulnRunStatus primaryComponent { name version } } } } } } } }",
    "variables": { "first": 25 }
  }'
```

Response:

```json
{
  "data": {
    "organization": {
      "projectGroups": {
        "totalCount": 3,
        "nodes": [
          {
            "id": "26ae44b7-2f68-4cf4-a405-d5ee0177bb11",
            "name": "payments-service",
            "projects": {
              "nodes": [
                {
                  "id": "1fade833-0603-4139-8ca0-26592264a4c9",
                  "name": "default",
                  "sboms": [
                    {
                      "id": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
                      "projectVersion": "3.0.2",
                      "vulnRunStatus": "FINISHED",
                      "primaryComponent": { "name": "payments-service", "version": "3.0.2" }
                    }
                  ]
                },
                { "id": "d845527f-f794-4120-97e3-ee350ee6638f", "name": "development", "sboms": [] },
                { "id": "0554ca34-ae9c-48f4-bc94-d14269214a43", "name": "production", "sboms": [] }
              ]
            }
          }
        ]
      }
    }
  }
}
```

Read the IDs from the response:

* **Product ID** is `projectGroups.nodes[].id`.
* **Environment ID** is `projects.nodes[].id`.
* **Version ID** is `sboms[].id`. This is the `sbomId` other calls ask for.

## Find one product by name

If you know the product name, search for it instead of listing everything.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query FindProduct($name: String!) { organization { projectGroups(search: $name, enabled: true, first: 10) { nodes { id name projects { nodes { id name sboms { id projectVersion } } } } } } }",
    "variables": { "name": "payments-service" }
  }'
```

`search` matches partially, so confirm the `name` in the response is the exact product you want.

## Pagination

List queries return 25 items by default. They use cursor-based pagination. Request `totalCount` and `pageInfo` to page through larger result sets:

```graphql
query ListProducts($first: Int, $after: String) {
  organization {
    projectGroups(first: $first, after: $after, enabled: true,
                  orderBy: { field: PROJECT_GROUPS_UPDATED_AT, direction: DESC }) {
      totalCount
      pageInfo { endCursor hasNextPage }
      nodes { id name }
    }
  }
}
```

* Pass `first` and `after` to move forward. `first` is the page size, `after` is the `endCursor` from the previous page.
* Pass `last` and `before` to move backward.
* When `hasNextPage` is `false`, you have reached the end.

See [Conventions](/api/reference/conventions) for more on pagination, ordering, and search.

## Next steps

With the IDs in hand, you can [upload](/api/managing-sboms/upload-sbom), [download](/api/managing-sboms/download-sbom), or [edit](/api/managing-sboms/edit-sbom-metadata) an SBOM.


# Group Products with Parts

A version can include other versions as **parts**. Use this to model an assembly: a top-level product made up of components you track separately, each with its own SBOM.

{% hint style="info" %}
**Parts link versions, not whole products.** A part relationship connects one version (`sbom`) to another version. You attach a specific version of the child product to a specific version of the parent. When the child ships a new version, attach that new version as a part. The link does not move to the latest version on its own.
{% endhint %}

Every call here needs version IDs (`sbomId`). Get them from [List Products and Versions](/api/inventory/list-resources). You need two: the parent version and the version you want to add as a part.

## Add a part

`sbomPartCreate` attaches one version to another. `parentSbomId` is the version that will contain the part. `partSbomId` is the version being added.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation AddPart($parent: Uuid!, $part: Uuid!) { sbomPartCreate(input: { parentSbomId: $parent, partSbomId: $part }) { sbomPart { id } errors } }",
    "variables": {
      "parent": "b5c023fe-1def-4204-8d5f-f6d277c6fe2f",
      "part": "e55baffc-5b30-4071-acc2-9792a4a682bc"
    }
  }'
```

```json
{
  "data": {
    "sbomPartCreate": {
      "sbomPart": { "id": "cbf8c489-d752-46a9-b4ca-a548351f23c5" },
      "errors": null
    }
  }
}
```

| Input          | Type | Required                                     |
| -------------- | ---- | -------------------------------------------- |
| `parentSbomId` | Uuid | Yes. The version that will contain the part. |
| `partSbomId`   | Uuid | Yes. The version to add as a part.           |

Save the returned `sbomPart.id`. You need it to remove the part later. It is the ID of the link, not the ID of either version.

## List the parts on a version

Query the parent version's `sbomParts`. Each entry has the link `id` and the `part`, which is the attached version.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Parts($id: Uuid!) { sbom(sbomId: $id) { id sbomParts { id part { id projectVersion primaryComponent { name version } } } } }",
    "variables": { "id": "b5c023fe-1def-4204-8d5f-f6d277c6fe2f" }
  }'
```

```json
{
  "data": {
    "sbom": {
      "id": "b5c023fe-1def-4204-8d5f-f6d277c6fe2f",
      "sbomParts": [
        {
          "id": "cbf8c489-d752-46a9-b4ca-a548351f23c5",
          "part": {
            "id": "e55baffc-5b30-4071-acc2-9792a4a682bc",
            "projectVersion": "1.0",
            "primaryComponent": { "name": "alphatron", "version": "1.0" }
          }
        }
      ]
    }
  }
}
```

`sbomParts` lists the direct parts only. For the full nested tree, when a part has parts of its own, request `deepParts` instead.

## Remove a part

`sbomPartDelete` takes the `id` of the part link, the `sbomPart.id` returned by `sbomPartCreate` or listed under `sbomParts`. It is not a version ID.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation RemovePart($id: Uuid!) { sbomPartDelete(input: { id: $id }) { sbomPart { id } errors } }",
    "variables": { "id": "cbf8c489-d752-46a9-b4ca-a548351f23c5" }
  }'
```

Removing a part deletes the link, not the version. The version you detached still exists on its own product.

## Notes

* A version cannot contain the same part twice. Adding a part that is already attached returns an error.
* Both IDs must be versions your token can access, in the same organization.


# Edit a Component

`componentUpdate` changes the fields of a single component inside an SBOM. Use it to correct a license, add a copyright line, fix a `purl`, and more.

You need two IDs: the component ID and the version ID (`sbomId`).

## Find the component ID

List the components in a version and read the `id` of the one you want.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Components($sbomId: Uuid!) { sbom(projectId: \"1fade833-0603-4139-8ca0-26592264a4c9\", sbomId: $sbomId) { components(sbomId: $sbomId, first: 25) { totalCount nodes { id name version purl copyright licensesExp } } } }",
    "variables": { "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6" }
  }'
```

```json
{
  "data": {
    "sbom": {
      "components": {
        "totalCount": 88,
        "nodes": [
          {
            "id": "10ad56c1-2b33-49c0-9822-cfcb54be40f4",
            "name": "jackson-core",
            "version": "2.15.2",
            "purl": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.2?type=jar",
            "copyright": null,
            "licensesExp": "Apache-2.0"
          }
        ]
      }
    }
  }
}
```

`components` is a paginated connection. To search by name, add a `search` argument, or page through with `first` and `after`. See [Conventions](/api/reference/conventions).

## Update the component

Pass the component `id`, the `sbomId`, and only the fields you want to change. Omitted fields are left untouched.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation EditComponent($id: Uuid!, $sbomId: Uuid!, $copyright: String) { componentUpdate(input: { id: $id, sbomId: $sbomId, copyright: $copyright }) { component { id name copyright } errors } }",
    "variables": {
      "id": "10ad56c1-2b33-49c0-9822-cfcb54be40f4",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "copyright": "Copyright (c) FasterXML, LLC"
    }
  }'
```

```json
{
  "data": {
    "componentUpdate": {
      "component": {
        "id": "10ad56c1-2b33-49c0-9822-cfcb54be40f4",
        "name": "jackson-core",
        "copyright": "Copyright (c) FasterXML, LLC"
      },
      "errors": []
    }
  }
}
```

## Editable fields

`componentUpdate` accepts these inputs. `id` and `sbomId` are required, the rest are optional.

| Input          | Type                | Description                                       |
| -------------- | ------------------- | ------------------------------------------------- |
| `id`           | Uuid                | The component ID. Required.                       |
| `sbomId`       | Uuid                | The version the component belongs to. Required.   |
| `name`         | String              | Component name.                                   |
| `version`      | String              | Component version.                                |
| `purl`         | String              | Package URL.                                      |
| `cpes`         | \[String]           | CPE identifiers.                                  |
| `licenses`     | LicenseInput        | License expression. See below.                    |
| `copyright`    | String              | Copyright statement.                              |
| `notice`       | String              | License notice text.                              |
| `description`  | String              | Free-text description.                            |
| `group`        | String              | Group or namespace, for example a Maven group ID. |
| `scope`        | String              | Component scope.                                  |
| `kind`         | String              | Component kind.                                   |
| `internal`     | Boolean             | Mark the component as internal.                   |
| `primary`      | Boolean             | Mark the component as the primary component.      |
| `checksums`    | \[ChecksumInput]    | Hashes. Each is `{ alg, content }`.               |
| `externalUrls` | \[ExternalUrlInput] | External links. Each is `{ name, url }`.          |

### Setting a license

`licenses` takes a `LicenseInput` object with a single field, `licensesExp`, an SPDX license expression:

```json
"variables": {
  "id": "10ad56c1-2b33-49c0-9822-cfcb54be40f4",
  "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
  "licenses": { "licensesExp": "Apache-2.0 OR MIT" }
}
```

with the mutation:

```graphql
mutation EditComponent($id: Uuid!, $sbomId: Uuid!, $licenses: LicenseInput) {
  componentUpdate(input: { id: $id, sbomId: $sbomId, licenses: $licenses }) {
    component { id name licensesExp }
    errors
  }
}
```

{% hint style="info" %}
This sets the license on a single component. To set the license of the SBOM document itself (the **Data License**, SPDX `dataLicense`), use `sbomUpdate` instead. See [Set the data license](/api/managing-sboms/edit-sbom-metadata#set-the-data-license).
{% endhint %}

{% hint style="info" %}
A component has a read-only `author` field that `componentUpdate` does not accept. To record authorship, set it at the SBOM level with `authorCreate`. See [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata). To set a component's supplier, use `compSupplierCreate`.
{% endhint %}

## Set a component supplier

`componentUpdate` does not change the supplier. Use `compSupplierCreate`:

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation AddSupplier($componentId: Uuid!, $name: String!, $url: String, $contactName: String, $contactEmail: String) { compSupplierCreate(input: { componentId: $componentId, name: $name, url: $url, contactName: $contactName, contactEmail: $contactEmail }) { errors } }",
    "variables": {
      "componentId": "10ad56c1-2b33-49c0-9822-cfcb54be40f4",
      "name": "FasterXML, LLC",
      "url": "https://fasterxml.com"
    }
  }'
```

## Errors

A failed update returns the reason in `errors`:

```json
{
  "data": {
    "componentUpdate": {
      "component": null,
      "errors": ["Component not found"]
    }
  }
}
```

| Message                 | Cause                                                                |
| ----------------------- | -------------------------------------------------------------------- |
| `Component not found`   | The component `id` is wrong, or it does not belong to that `sbomId`. |
| `No arguments provided` | You sent only `id` and `sbomId` with no fields to change.            |
| `Project not enabled`   | The product the component belongs to is disabled.                    |


# Vulnerabilities and VEX

After an SBOM is processed, the platform attaches known vulnerabilities to its components. You can list them through the API and record a VEX assessment for each one.

You need the environment ID (`projectId`) and version ID (`sbomId`). Get them from [List Products and Versions](/api/inventory/list-resources).

## List vulnerabilities

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Vulns($projectId: Uuid!, $sbomId: Uuid!, $first: Int, $after: String) { sbom(projectId: $projectId, sbomId: $sbomId) { vulns(sbomId: $sbomId, first: $first, after: $after) { totalCount pageInfo { hasNextPage endCursor } nodes { id vuln { vulnId source sev cvssScore } component { name version } vexStatus { id name } } } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "first": 25
    }
  }'
```

```json
{
  "data": {
    "sbom": {
      "vulns": {
        "totalCount": 14,
        "pageInfo": { "hasNextPage": false, "endCursor": "MjU" },
        "nodes": [
          {
            "id": "5c11d0e2-0d27-484d-b04f-8df991082652",
            "vuln": {
              "vulnId": "GHSA-72hv-8253-57qq",
              "source": "GITHUB",
              "sev": "medium",
              "cvssScore": 6.9
            },
            "component": { "name": "jackson-core", "version": "2.15.2" },
            "vexStatus": null
          }
        ]
      }
    }
  }
}
```

The `id` on each node is the **component vulnerability ID**. It identifies one vulnerability on one component. You need it to set VEX.

`vulns` is paginated. When `pageInfo.hasNextPage` is `true`, request the next page with `after` set to `endCursor`. See [Conventions](/api/reference/conventions).

## Read more about a vulnerability

Two different IDs come back from the list above, and they point at different objects.

* The `id` on each node is the **component vulnerability ID**. It identifies one vulnerability on one component in this version. VEX attaches to it, and it carries the instance-level data: effective CVSS, fix versions, VEX state.
* The `vuln` block is the **global vulnerability record**, shared by every version that has this vulnerability. Its `id` (also exposed on the node as `vulnId`) is what the top-level `vuln` query takes.

So you can read more two ways: expand fields on the node you already have, or look the global record up by its ID.

### Expand the node

Add fields to the same `vulns` query. No second call is needed.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Node($projectId: Uuid!, $sbomId: Uuid!) { sbom(projectId: $projectId, sbomId: $sbomId) { vulns(sbomId: $sbomId, first: 1) { nodes { id effectiveCvssScore effectiveCvssSeverity fixedVersions retracted createdAt vexStatus { name } component { name version purl } vuln { vulnId sev } } } } }",
    "variables": {
      "projectId": "1fade833-0603-4139-8ca0-26592264a4c9",
      "sbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6"
    }
  }'
```

```json
{
  "data": {
    "sbom": {
      "vulns": {
        "nodes": [
          {
            "id": "1a2735d0-ac84-4dfc-9bd0-ecd78106091a",
            "effectiveCvssScore": 7.5,
            "effectiveCvssSeverity": "high",
            "fixedVersions": ["1.7.0"],
            "retracted": false,
            "createdAt": "2026-01-30T00:08:27Z",
            "vexStatus": null,
            "component": { "name": "jose2go", "version": "v1.5.0", "purl": "pkg:golang/github.com/dvsekhvalnov/jose2go@v1.5.0" },
            "vuln": { "vulnId": "GO-2025-4123", "sev": "high" }
          }
        ]
      }
    }
  }
}
```

Node fields you can read, by group:

| Group              | Fields                                                                                                                             |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| Identity           | `id`, `vulnId`, `componentId`, `sbomId`, `createdAt`, `updatedAt`                                                                  |
| Component          | `component { name version purl ... }`                                                                                              |
| Effective CVSS     | `effectiveCvssScore`, `effectiveCvssSeverity`, `effectiveCvssVector`, `hasCustomCvss`, `cvssAdjustedScore`, `cvssAdjustedSeverity` |
| CVSS customization | `cvssTemporalVector`, `cvssEnvironmentalVector`, `cvssTemporalMetrics`, `cvssEnvironmentalMetrics`                                 |
| VEX                | `vexStatus { name }`, `vexJustification`, `cdxResponse`, `note`, `impact`, `detail`, `actionStmt`, `fixedIn`, `vexStatusUpdatedAt` |
| Remediation        | `fixedVersions`, `lastAffectedVersions`, `resolutionDate`, `patchVelocity`                                                         |
| State              | `retracted`, `retractedAt`, `isComplete`, `isPart`, `isFirstDegreePart`                                                            |
| Links              | `externalUrls`, `currentExternalUrls`, `externalIssueTrackerLinks`, `componentVulnCustomFields`, `componentVulnLogs`               |

### Look up the global record

Pass the global vulnerability ID (the node's `vulnId`, or `vuln.id`) to the top-level `vuln` query. Use this for cross-version rollups without going through a single SBOM.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query Vuln($id: Uuid!) { vuln(id: $id) { vulnId displayId source sev cvssScore cvssVector desc publishedAt lastModifiedAt componentCount sbomVersionsCount projectGroupsCount vulnInfo { cveId cwes kev epssScore epssPercentile advisories } } }",
    "variables": { "id": "6a89a3c0-c1d0-47ad-b120-7d8390f2d0e8" }
  }'
```

```json
{
  "data": {
    "vuln": {
      "vulnId": "GO-2025-4123",
      "displayId": "CVE-2025-63811",
      "source": "osv",
      "sev": "high",
      "cvssScore": 7.5,
      "cvssVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "desc": "Denial-of-Service (DoS) via crafted JWE token high compression ratio in jose2go",
      "publishedAt": "2025-11-18T15:44:15Z",
      "lastModifiedAt": "2026-02-04T04:04:38Z",
      "componentCount": 2,
      "sbomVersionsCount": 2,
      "projectGroupsCount": 1,
      "vulnInfo": { "cveId": "GO-2025-4123", "cwes": [], "kev": false, "epssScore": 0.00029, "epssPercentile": 0.08849, "advisories": ["..."] }
    }
  }
}
```

The `vuln` record fields are `vulnId`, `displayId`, `nvdAliasId`, `source`, `sev`, `cvssScore`, `cvssVector`, `desc`, `publishedAt`, `lastModifiedAt`, `componentCount`, `sbomVersionsCount`, `projectGroupsCount`, and `sbomVersions`. The nested `vulnInfo` adds threat intel: `cveId`, `cwes`, `kev`, `epssScore`, `epssScores`, `epssPercentile`, and `advisories`.

{% hint style="info" %}
One naming gotcha. On a node, `vulnId` is the UUID of the global record, the value the `vuln` query wants. On the `vuln` record itself, `vulnId` is the human advisory string such as `GO-2025-4123`, and `id` is the UUID.
{% endhint %}

## Get the VEX status options

VEX statuses are referenced by ID. Fetch the list of valid statuses first:

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { vexStatuses { id name } }"}'
```

```json
{
  "data": {
    "vexStatuses": [
      { "id": "28c61387-c85f-4f9b-b434-4b2d887b8915", "name": "In Triage" },
      { "id": "10cf7c16-b8fb-4731-8622-d874cd2680bc", "name": "Not Affected" },
      { "id": "303b6a94-995f-484d-8ae7-3df89dd4352b", "name": "Affected" },
      { "id": "7fbb2b21-c031-4578-b6e7-9bb78612b6f6", "name": "Fixed" }
    ]
  }
}
```

Fetch these IDs from your own organization. They are stable within an organization, so you can look them up once and reuse them.

Two more lookup queries return the other VEX option lists:

* `vexJustifications { id name }` for justification IDs.
* `cdxResponses { id name }` for response IDs.

## Set a VEX status

`componentVexUpdate` records a VEX assessment on one component vulnerability. Pass the component vulnerability `id` as `componentVulnId`, the version as `currentSbomId`, and the status ID.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetVex($componentVulnId: Uuid!, $currentSbomId: Uuid!, $vexStatusId: Uuid, $note: String) { componentVexUpdate(input: { componentVulnId: $componentVulnId, currentSbomId: $currentSbomId, vexStatusId: $vexStatusId, note: $note }) { componentVuln { id vexStatus { name } note } errors } }",
    "variables": {
      "componentVulnId": "5c11d0e2-0d27-484d-b04f-8df991082652",
      "currentSbomId": "4e423fe0-d089-4025-b1e4-8fe9608138d6",
      "vexStatusId": "10cf7c16-b8fb-4731-8622-d874cd2680bc",
      "note": "Vulnerable code path is not reachable in our usage."
    }
  }'
```

```json
{
  "data": {
    "componentVexUpdate": {
      "componentVuln": {
        "id": "5c11d0e2-0d27-484d-b04f-8df991082652",
        "vexStatus": { "name": "Not Affected" },
        "note": "Vulnerable code path is not reachable in our usage."
      },
      "errors": []
    }
  }
}
```

### componentVexUpdate inputs

| Input                | Type    | Description                                               |
| -------------------- | ------- | --------------------------------------------------------- |
| `componentVulnId`    | Uuid    | The component vulnerability ID. Required.                 |
| `currentSbomId`      | Uuid    | The version the vulnerability belongs to. Required.       |
| `vexStatusId`        | Uuid    | A status ID from `vexStatuses`.                           |
| `vexJustificationId` | Uuid    | A justification ID from `vexJustifications`.              |
| `cdxResponseId`      | Uuid    | A response ID from `cdxResponses`.                        |
| `note`               | String  | Free-text note.                                           |
| `impact`             | String  | Impact statement.                                         |
| `detail`             | String  | Detail statement.                                         |
| `action`             | String  | Action statement.                                         |
| `fixedIn`            | String  | Version the issue is fixed in.                            |
| `propagateVex`       | Boolean | Apply the same VEX to matching components in other SBOMs. |

To update many vulnerabilities at once, use `componentVexBulkUpdate`, which takes a list of `componentVulnIds` and the same VEX fields.

## Errors

Failures return in the `errors` list:

```json
{
  "data": {
    "componentVexUpdate": {
      "componentVuln": null,
      "errors": ["Component vuln not found"]
    }
  }
}
```

See [Errors](/api/reference/errors).


# Manage Notifications

Interlynk sends notifications when things happen to your SBOMs: a version uploads, a scan finds new vulnerabilities, a policy fails, a license changes. The API gives you three independent controls over those notifications.

| Control         | Scope                 | What it sets                                               |
| --------------- | --------------------- | ---------------------------------------------------------- |
| **Settings**    | Organization or user  | Which message types fire, and at what severity level.      |
| **Preferences** | User, per environment | Which categories you subscribe to for a given environment. |
| **Channels**    | User                  | Where notifications go: email, Slack, Teams.               |

Settings are the only control with an organization-wide scope. Preferences and channels always belong to the calling user. Read each one before you change it, since most calls overwrite rather than merge.

## Notification settings

A setting decides whether a message type is enabled and at what level. Levels are `ALERT`, `WARN`, or `INFO`. Settings exist at two scopes: the organization default, and a per-user override. The `org` flag on the update mutation picks which one you write.

### Read the organization settings

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { notificationSettings { messageType title enabled level hasOverride } } }"}'
```

```json
{
  "data": {
    "organization": {
      "notificationSettings": [
        { "messageType": "SBOM_UPLOAD_SUCCESS", "title": "Version Upload Success", "enabled": true, "level": "INFO", "hasOverride": false },
        { "messageType": "SBOM_UPLOAD_FAILED", "title": "Version Upload Failed", "enabled": true, "level": "ALERT", "hasOverride": true }
      ]
    }
  }
}
```

`hasOverride` is `true` when the organization has changed the message type from its system default. The full list of message types is in the [reference table](#message-types) below.

To read your own user-level overrides instead, query `organizationUser`:

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organizationUser { notificationSettings { messageType title enabled level } } }"}'
```

### Update settings

`bulkUpdateNotificationSettings` writes one or more settings in a single call. Set `org` to `true` for the organization default, or `false` for your own user-level override. Each entry needs a `messageType` and at least one of `enabled` or `level`.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetSettings($settingsData: [NotificationSettingInput!]!) { bulkUpdateNotificationSettings(input: { org: true, settingsData: $settingsData }) { success totalProcessed successfulCount failedCount errors } }",
    "variables": {
      "settingsData": [
        { "messageType": "SBOM_UPLOAD_FAILED", "enabled": true, "level": "ALERT" },
        { "messageType": "SBOM_UPLOAD_SUCCESS", "enabled": false }
      ]
    }
  }'
```

```json
{
  "data": {
    "bulkUpdateNotificationSettings": {
      "success": true,
      "totalProcessed": 2,
      "successfulCount": 2,
      "failedCount": 0,
      "errors": []
    }
  }
}
```

The whole batch is transactional. If any entry fails, for example an unknown `messageType`, nothing is written and the reason comes back in `errors`.

{% hint style="info" %}
Writing organization settings (`org: true`) requires the **Edit Notification Settings** permission, which Admin and Owner roles have. A Viewer can read organization settings but not change them, and gets `You are not authorized to perform this action on NotificationSetting`. Any user can write their own settings with `org: false`.
{% endhint %}

#### Message types <a href="#message-types" id="message-types"></a>

| `messageType`              | Title                                   | Default level |
| -------------------------- | --------------------------------------- | ------------- |
| `SBOM_UPLOAD_SUCCESS`      | Version Upload Success                  | INFO          |
| `SBOM_UPLOAD_FAILED`       | Version Upload Failed                   | ALERT         |
| `SBOM_VULN_SCAN_REPORT`    | Version Vulnerability Summary Report    | ALERT         |
| `NEW_VULNS_REPORT`         | Version Vulnerability Scan Report       | ALERT         |
| `VULN_DIFF_REPORT`         | Version Vulnerability Comparison Report | WARN          |
| `SBOM_POLICY_SCAN_REPORT`  | Version Policy Scan Report              | WARN          |
| `LICENSE_CREATION_SUCCESS` | Organization License Create Success     | INFO          |
| `LICENSE_CREATION_FAILED`  | Organization License Create Failed      | ALERT         |
| `LICENSE_UPDATE_SUCCESS`   | Organization License Update Success     | INFO          |
| `LICENSE_UPDATE_FAILED`    | Organization License Update Failed      | ALERT         |
| `LICENSE_SUMMARY`          | Version License Summary                 | INFO          |
| `SBOM_LICENSE_UPDATE`      | Version License Update                  | INFO          |
| `COMPONENT_LICENSE_UPDATE` | Version Component License Update        | INFO          |

Read the live list from your own organization with the settings query above. New message types are added over time.

## Notification preferences

Preferences are user-scoped and set per environment. Each environment subscribes to a set of categories. The valid categories are `none`, `all`, `vulnerabilities`, `licenses`, `policies`, and `uploads`. Use `none` to unsubscribe and `all` to subscribe to everything.

### Read your preferences for one environment

Pass the environment ID as `envId`. Get environment IDs from [List Products and Versions](/api/inventory/list-resources).

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { notificationPreferences(envId: \"fa803351-ec53-44cf-aec5-88d99372e59f\") }"}'
```

```json
{ "data": { "notificationPreferences": ["vulnerabilities", "policies"] } }
```

To see every product and environment at once, query `organizationUser`. The preferences are grouped by product:

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organizationUser { notificationPreferences(first: 25) { nodes { productName projects { projectId projectName subscribedCategories } } } } }"}'
```

### Update one environment

`notificationPreferenceUpdate` replaces the categories for a single environment. The list you send is the full set of categories after the call, so include every category you want to keep.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetPref($envId: Uuid!, $prefs: [NotificationPreferenceArguments!]!) { notificationPreferenceUpdate(input: { envId: $envId, notificationPreferences: $prefs }) { currentNotificationPreference { id } } }",
    "variables": {
      "envId": "fa803351-ec53-44cf-aec5-88d99372e59f",
      "prefs": ["vulnerabilities", "policies"]
    }
  }'
```

### Update many environments at once

`bulkUpdateNotificationPreferences` takes a list, one entry per environment. Each entry pairs a `projectId` (the environment ID) with its `enabledCategories`.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetPrefs($preferencesData: [NotificationPreferenceInput!]!) { bulkUpdateNotificationPreferences(input: { preferencesData: $preferencesData }) { success successfulCount failedCount errors } }",
    "variables": {
      "preferencesData": [
        { "projectId": "fa803351-ec53-44cf-aec5-88d99372e59f", "enabledCategories": ["uploads"] },
        { "projectId": "44e4c17c-c04b-4994-a845-4840c45c72a4", "enabledCategories": ["all"] }
      ]
    }
  }'
```

## Delivery channels

Channels decide where your notifications go. They are user-scoped. Email, Slack, and Teams are simple on or off toggles. Slack and Teams also need a webhook URL, which you set separately.

### Read your channels

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { notificationChannels { email slack teams } notificationConfigs { slackWebhookUrl teamsWebhookUrl } }"}'
```

```json
{
  "data": {
    "notificationChannels": { "email": true, "slack": false, "teams": false },
    "notificationConfigs": { "slackWebhookUrl": null, "teamsWebhookUrl": null }
  }
}
```

### Turn channels on or off

`notificationChannelUpdate` sets all three toggles at once.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetChannels($channels: NotificationChannelInput!) { notificationChannelUpdate(input: { notificationChannels: $channels }) { success } }",
    "variables": { "channels": { "email": true, "slack": false, "teams": false } }
  }'
```

### Set a webhook URL

`notificationConfigUpdate` sets one webhook per call. Send either `slackWebhookUrl` or `teamsWebhookUrl`, not both in the same call.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetWebhook($configs: NotificationConfigInput!) { notificationConfigUpdate(input: { notificationConfigs: $configs }) { success } }",
    "variables": { "configs": { "slackWebhookUrl": "https://hooks.slack.com/services/T000/B000/XXXX" } }
  }'
```

After setting the webhook, turn the matching channel on with `notificationChannelUpdate`.

## Errors

The bulk mutations report per-entry failures in their `errors` list and keep the operation transactional, so a single bad entry rolls back the whole batch:

```json
{
  "data": {
    "bulkUpdateNotificationSettings": {
      "success": false,
      "successfulCount": 0,
      "failedCount": 1,
      "errors": ["Unknown notification type: SBOM_UPLOADED"]
    }
  }
}
```

| Message                                                                | Cause                                                                             |
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `Unknown notification type: ...`                                       | The `messageType` is not a valid type. See the [reference table](#message-types). |
| `At least one of enabled or level must be specified`                   | A settings entry had only a `messageType`.                                        |
| `You are not authorized to perform this action on NotificationSetting` | You sent `org: true` without the Edit Notification Settings permission.           |

See [Errors](/api/reference/errors) for the general error model.


# Manage Users and Roles

Interlynk controls access with role-based access control (RBAC). Every user in an organization holds one role, and a role is a named set of permissions. The API lets you invite users, change the role a user holds, remove users, and define custom roles.

{% hint style="success" %}
**Prefer SSO for managing access.** If your identity provider supports SAML (Okta, Microsoft Entra ID, Google Workspace, and others), connect it once and users are provisioned automatically on first login with a default role. You stop maintaining the member list by hand, access follows your directory, and deprovisioning happens where it should. See [Single sign-on](#single-sign-on) below. Use the invite flow for people outside your IdP or for early setup.
{% endhint %}

## How access works

| Concept        | What it is                                                      |
| -------------- | --------------------------------------------------------------- |
| **Role**       | A named set of permissions, scoped to one organization.         |
| **Permission** | A single capability, for example `invite_users` or `view_sbom`. |
| **Member**     | A user attached to an organization with exactly one role.       |

Three system roles exist in every organization: **Admin** (all permissions), **Operator**, and **Viewer** (read-only). Enterprise organizations can also define custom roles. The actions below each require a permission, so the token you use must belong to a user whose role grants it.

| Action                  | Mutation                 | Permission required                     |
| ----------------------- | ------------------------ | --------------------------------------- |
| Add a user              | `organizationUserInvite` | `invite_users`                          |
| Change a user's role    | `organizationUserUpdate` | `edit_user_role`                        |
| Remove a user           | `organizationUserRemove` | `delete_user`                           |
| Create or change a role | `organizationRole*`      | `edit_user_role`, `update_organization` |
| Configure SSO           | `samlConfig*`            | `edit_connections`                      |

A token without the permission gets `You are not authorized to perform this action on User`. The Admin role holds every permission.

## Find role and user IDs

The user-management mutations take a `userId` and an `organizationRoleId`. Read both from the `organization` query.

### List roles

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { organizationRoles { id name isAdmin isSystem } } }"}'
```

```json
{
  "data": {
    "organization": {
      "organizationRoles": [
        { "id": "29470b2d-...", "name": "Admin", "isAdmin": true, "isSystem": true },
        { "id": "1d6d5eff-...", "name": "Operator", "isAdmin": false, "isSystem": true },
        { "id": "784f2a4f-...", "name": "Viewer", "isAdmin": false, "isSystem": true }
      ]
    }
  }
}
```

### List members

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { users(first: 25) { nodes { id name email invitationStatus role { name } } } } }"}'
```

`invitationStatus` is `invited` for a pending invitation, `accepted` once the user joins, `declined`, or `pending_registration`.

## Add a user

`organizationUserInvite` invites a user by email and assigns a role. Pass the `organizationRoleId` from the roles list. The user gets an email and shows as `invited` until they accept.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation Invite($email: String!, $roleId: Uuid!) { organizationUserInvite(input: { email: $email, organizationRoleId: $roleId }) { user { id email invitationStatus role { name } } errors } }",
    "variables": {
      "email": "newhire@example.com",
      "roleId": "784f2a4f-1e1b-4d4d-815b-033b1b6165ec"
    }
  }'
```

```json
{
  "data": {
    "organizationUserInvite": {
      "user": { "id": "db3bb458-...", "email": "newhire@example.com", "invitationStatus": "invited", "role": { "name": "Viewer" } },
      "errors": []
    }
  }
}
```

{% hint style="warning" %}
A non-admin inviter can only invite to **its own role**. An Admin can invite to any role. Inviting to a different role without admin rights returns `User does not have permission to invite to this role to this organization`. The `organizationRoleId` is optional; omit it to invite with no role assigned yet.
{% endhint %}

## Change a user's access level

`organizationUserUpdate` changes the role a user holds. Pass the `userId` and the target `organizationRoleId`.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetRole($userId: Uuid!, $roleId: Uuid!) { organizationUserUpdate(input: { userId: $userId, organizationRoleId: $roleId }) { user { id email role { name } } errors } }",
    "variables": {
      "userId": "db3bb458-78a1-4a07-8d82-b7e091c55e58",
      "roleId": "1d6d5eff-999f-4d8b-8584-9bd0b4ce592c"
    }
  }'
```

```json
{
  "data": {
    "organizationUserUpdate": {
      "user": { "id": "db3bb458-...", "email": "newhire@example.com", "role": { "name": "Operator" } },
      "errors": []
    }
  }
}
```

## Remove a user

`organizationUserRemove` detaches a user from the organization. Pass the `userId`. This removes the membership; it does not delete the person's Interlynk account.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation Remove($userId: Uuid!) { organizationUserRemove(input: { userId: $userId }) { user { id email } errors } }",
    "variables": { "userId": "db3bb458-78a1-4a07-8d82-b7e091c55e58" }
  }'
```

To leave an organization yourself, use `organizationUserLeave` with an `organizationId` instead.

## Custom roles

{% hint style="info" %}
Custom roles are an Enterprise feature. On other tiers the role mutations return a tier error, and you work with the built-in Admin, Operator, and Viewer roles.
{% endhint %}

### Create a role

`organizationRoleCreate` takes a name and the full list of permission keys. See the [permission reference](#permission-reference) for valid keys.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation NewRole($name: String!, $perms: [String!]!) { organizationRoleCreate(input: { name: $name, permissions: $perms }) { organizationRole { id name permissions } errors } }",
    "variables": {
      "name": "QA Reviewer",
      "perms": ["view_organization", "view_product_group", "view_sbom"]
    }
  }'
```

### Update a role

`organizationRoleUpdate` takes permission deltas, not a full list. Each entry is a `permissionKey` and a `value`: `true` adds the permission, `false` removes it. Permissions you do not mention stay as they are.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation EditRole($id: Uuid!, $perms: [SetPermissionInput!]) { organizationRoleUpdate(input: { organizationRoleId: $id, permissions: $perms }) { organizationRole { name permissions } errors } }",
    "variables": {
      "id": "9cba58cb-5e93-4dec-ae57-7fbc04ab3a32",
      "perms": [
        { "permissionKey": "edit_vulnerabilities", "value": true },
        { "permissionKey": "view_sbom", "value": false }
      ]
    }
  }'
```

### Assign a role to many users

`organizationRoleBulkApply` moves a list of users onto one role in a single call.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation Bulk($id: Uuid!, $userIds: [Uuid!]!) { organizationRoleBulkApply(input: { organizationRoleId: $id, userIds: $userIds }) { organizationRole { name users { email } } errors } }",
    "variables": {
      "id": "9cba58cb-5e93-4dec-ae57-7fbc04ab3a32",
      "userIds": ["3bdc339e-afe1-435f-bebf-2d8c9d4416cb"]
    }
  }'
```

### Delete a role

`organizationRoleDelete` removes a custom role. Move any users off it first.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation DelRole($id: Uuid!) { organizationRoleDelete(input: { id: $id }) { organizationRole { id name } errors } }",
    "variables": { "id": "9cba58cb-5e93-4dec-ae57-7fbc04ab3a32" }
  }'
```

## Single sign-on

SSO is the preferred way to run access at any scale past a handful of people. Connect your SAML identity provider once and new users are provisioned on first login with a default role, so you do not invite them one at a time. Deactivating a user in your IdP cuts their access.

{% hint style="info" %}
SSO is an Enterprise feature configured with the `samlConfig` mutations. Reading the config needs `view_connections`; creating or updating it needs `edit_connections`; deleting it needs `delete_connections`.
{% endhint %}

### Read the current SSO config

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { samlConfig { id enabled issuer idpSsoServiceUrl tenant metadataUrl defaultUserRole { id name } } } }"}'
```

`samlConfig` is `null` until you create one.

### Create the SSO config

`samlConfigCreate` reads your identity provider's metadata URL and extracts the SSO service URL and signing certificate for you. The `defaultUserRoleId` sets the role every new SSO user receives on first login. Pick a least-privileged role such as Viewer.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation SetupSso($role: Uuid!) { samlConfigCreate(input: { metadataUrl: \"https://idp.example.com/app/metadata\", assertionConsumerServiceUrl: \"https://api.interlynk.io/auth/saml/callback?tenant=acme\", tenant: \"acme\", issuer: \"https://api.interlynk.io\", defaultUserRoleId: $role }) { samlConfig { id enabled tenant idpSsoServiceUrl defaultUserRole { name } } errors } }",
    "variables": { "role": "784f2a4f-1e1b-4d4d-815b-033b1b6165ec" }
  }'
```

The arguments:

| Argument                      | Description                                                             |
| ----------------------------- | ----------------------------------------------------------------------- |
| `metadataUrl`                 | Your IdP's SAML metadata URL. Must be reachable; the server fetches it. |
| `assertionConsumerServiceUrl` | The ACS URL the IdP posts responses to.                                 |
| `tenant`                      | A short identifier for your organization, used in the callback URL.     |
| `issuer`                      | The service provider entity ID.                                         |
| `defaultUserRoleId`           | Role assigned to new SSO users.                                         |
| `attributeStatements`         | Optional custom attribute mappings.                                     |

If the metadata URL cannot be fetched or parsed, the mutation returns the parse errors and writes nothing.

### Update or disable SSO

`samlConfigUpdate` changes the config. `defaultUserRoleId` is required on update; the other fields are optional. Set `enabled: false` to switch SSO off without deleting the configuration.

```bash
curl https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation UpdateSso($role: Uuid!) { samlConfigUpdate(input: { enabled: false, defaultUserRoleId: $role }) { samlConfig { enabled defaultUserRole { name } } errors } }",
    "variables": { "role": "1d6d5eff-999f-4d8b-8584-9bd0b4ce592c" }
  }'
```

To remove SSO entirely, call `samlConfigDelete` with the config `id`.

## Permission reference <a href="#permission-reference" id="permission-reference"></a>

Common permission keys, by category. Read the live set for a role from the `organizationRoles { permissions }` query.

| Category        | Keys                                                                                         |
| --------------- | -------------------------------------------------------------------------------------------- |
| User Management | `view_users`, `invite_users`, `edit_user_role`, `delete_user`                                |
| Organization    | `view_organization`, `update_organization`                                                   |
| Product         | `view_product_group`, `create_product_group`, `update_product_group`, `delete_product_group` |
| SBOM            | `view_sbom`, `update_sbom`, `edit_sbom_components`, `edit_vulnerabilities`, `delete_sbom`    |
| Connections     | `view_connections`, `edit_connections`, `delete_connections`                                 |

## Errors

| Message                                                                     | Cause                                                               |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `You are not authorized to perform this action on User`                     | The token's role lacks the permission for this action.              |
| `User does not have permission to invite to this role to this organization` | A non-admin tried to invite to a role other than its own.           |
| `You are not authorized to perform this action on SamlConfig`               | The token lacks `edit_connections` (or `view_connections` to read). |
| `Metadata url could not be parsed: ...`                                     | The SSO `metadataUrl` was unreachable or not valid SAML metadata.   |

See [Errors](/api/reference/errors) for the general error model.


# Conventions

This page covers the rules that apply across the whole API: the endpoint, request shape, pagination, ordering, and search.

## Endpoint

One endpoint serves every query and mutation:

```
https://api.interlynk.io/lynkapi
```

Always use `POST`. Authenticate with a bearer token. See [Authentication](/api/getting-started/authentication).

## Request shape

For queries and mutations, send a JSON body with `Content-Type: application/json`:

```json
{
  "query": "query { organization { name } }",
  "variables": {},
  "operationName": null
}
```

| Key             | Required | Purpose                                                     |
| --------------- | -------- | ----------------------------------------------------------- |
| `query`         | Yes      | The GraphQL operation string.                               |
| `variables`     | No       | Values referenced by the operation.                         |
| `operationName` | No       | Required only when `query` defines more than one operation. |

File uploads are the exception. They use `multipart/form-data`. See [Upload an SBOM](/api/managing-sboms/upload-sbom).

## Identifiers

Objects are identified by UUID. Two scalar types appear in the schema:

* `Uuid` is used for most arguments, for example `projectId` and `sbomId`.
* `ID` is used by some inputs, for example `projectGroupId` on upload.

Pass the same UUID string for either. The distinction is a schema detail.

## Pagination

List fields use cursor-based pagination. They return 25 items by default.

Request `totalCount` and `pageInfo` alongside `nodes`:

```graphql
projectGroups(first: 25, after: "MjU") {
  totalCount
  pageInfo { startCursor endCursor hasNextPage hasPreviousPage }
  nodes { id name }
}
```

| Arguments         | Direction                                               |
| ----------------- | ------------------------------------------------------- |
| `first` + `after` | Forward. `first` is the page size, `after` is a cursor. |
| `last` + `before` | Backward.                                               |

To page forward: request a page, read `pageInfo.endCursor`, pass it as `after` on the next request, and stop when `hasNextPage` is `false`.

`totalCount` is the size of the whole result set, not the current page.

## Ordering

Many list fields accept an `orderBy` argument with a `field` and a `direction`:

```graphql
projectGroups(orderBy: { field: PROJECT_GROUPS_UPDATED_AT, direction: DESC }) {
  nodes { id name }
}
```

`direction` is `ASC` or `DESC`. The valid `field` values depend on the list being queried.

## Search

Many list fields accept a `search` argument. It matches partially and is case-insensitive. The fields it searches depend on the list. For example, `projectGroups(search: "payments")` matches product names.

Because search is partial, always confirm the `name` in the response is the exact object you wanted.

## Introspection

The production endpoint does **not** support GraphQL introspection. Use this documentation as the schema reference. See [Operations](/api/reference/operations) for the list of supported queries and mutations.


# Errors

The API reports failures in three ways. Which one you get depends on where the request failed.

## Authentication errors

A missing, expired, or invalid token returns HTTP `401` with an error body:

```json
{
  "errors": [
    { "message": "Unauthorized", "extensions": { "code": "UNAUTHORIZED" } }
  ]
}
```

Fix: check that the `Authorization` header is present and the token is current. See [Authentication](/api/getting-started/authentication).

## GraphQL errors

If the request is authenticated but the query itself is wrong, for example a misspelled field or a missing required argument, the API returns HTTP `200` with a top-level `errors` array and no `data`:

```json
{
  "errors": [
    {
      "message": "Field 'notAField' doesn't exist on type 'Organization'",
      "locations": [{ "line": 1, "column": 20 }],
      "path": ["query", "organization", "notAField"],
      "extensions": {
        "code": "undefinedField",
        "typeName": "Organization",
        "fieldName": "notAField"
      }
    }
  ]
}
```

{% hint style="warning" %}
A `200` status does not mean the request succeeded. Always check for a top-level `errors` key before you read `data`.
{% endhint %}

These errors are usually a bug in the request. Fix the query and resend.

## Mutation errors

Mutations handle expected failures differently. Instead of a top-level error, the failure is returned inside the mutation's own `errors` field, and `data` is present:

```json
{
  "data": {
    "authorCreate": {
      "author": null,
      "errors": ["Sbom not found"]
    }
  }
}
```

Every mutation in these docs has an `errors` field. Always request it and always check it. An empty list means success.

This design also protects against enumeration. A record that does not exist and a record you are not allowed to see both return the same message, for example `Sbom not found`.

## Common messages

| Message                   | Where             | Cause                                                                     |
| ------------------------- | ----------------- | ------------------------------------------------------------------------- |
| `Unauthorized`            | HTTP 401          | Token missing, expired, or invalid.                                       |
| `Sbom not found`          | Mutation `errors` | The `sbomId` is wrong, or the token cannot access it.                     |
| `Component not found`     | Mutation `errors` | The component `id` is wrong, or it does not belong to the given `sbomId`. |
| `Project group not found` | Mutation `errors` | The product name or ID does not exist, or is not visible to the token.    |
| `No arguments provided`   | Mutation `errors` | An update mutation was sent with no fields to change.                     |
| `Project not enabled`     | Mutation `errors` | The product is disabled. Re-enable it in the dashboard.                   |

## Checking errors in a script

With `jq`, check the top-level `errors` key before using `data`:

```bash
RESPONSE=$(curl -s https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { organization { name } }"}')

if echo "$RESPONSE" | jq -e '.errors' > /dev/null; then
  echo "Request failed:"
  echo "$RESPONSE" | jq '.errors'
  exit 1
fi

echo "$RESPONSE" | jq '.data'
```


# Operations

A reference list of the queries and mutations these docs cover. The API schema is larger than this. These are the operations relevant to uploading, downloading, and managing SBOMs.

The production endpoint does not support introspection, so use this page as the operation reference.

## Queries

| Query                                | Returns                                                                      | Guide                                                            |
| ------------------------------------ | ---------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `organization`                       | Your organization, its products, environments, and versions.                 | [List Products and Versions](/api/inventory/list-resources)      |
| `sbom(projectId, sbomId)`            | A single version: metadata, authors, suppliers, components, download, vulns. | [Download](/api/managing-sboms/download-sbom)                    |
| `vexStatuses`                        | Valid VEX status IDs and names.                                              | [Vulnerabilities and VEX](/api/security/vulnerabilities-and-vex) |
| `vexJustifications`                  | Valid VEX justification IDs and names.                                       | [Vulnerabilities and VEX](/api/security/vulnerabilities-and-vex) |
| `cdxResponses`                       | Valid VEX response IDs and names.                                            | [Vulnerabilities and VEX](/api/security/vulnerabilities-and-vex) |
| `organization { organizationRoles }` | Roles in the organization and their permissions.                             | [Manage Users and Roles](/api/user-management/user-management)   |
| `organization { users }`             | Members, their roles, and invitation status.                                 | [Manage Users and Roles](/api/user-management/user-management)   |
| `organization { samlConfig }`        | The organization's SSO (SAML) configuration.                                 | [Manage Users and Roles](/api/user-management/user-management)   |

### Key fields on `sbom`

The `sbom` query resolves a version. Useful fields on it:

| Field                                      | Description                                                                                   |
| ------------------------------------------ | --------------------------------------------------------------------------------------------- |
| `id`                                       | The version ID (`sbomId`).                                                                    |
| `projectVersion`                           | The version string, for example `3.0.2`.                                                      |
| `vulnRunStatus`                            | Vulnerability scan status. `FINISHED` when done.                                              |
| `primaryComponent { name version }`        | The component the SBOM describes.                                                             |
| `sbomParts { id part { ... } }`            | The versions attached as direct parts. See [Group Products with Parts](/api/inventory/parts). |
| `deepParts { ... }`                        | The full nested tree of parts.                                                                |
| `authors { id name email phone }`          | SBOM authors.                                                                                 |
| `suppliers { ... }`                        | SBOM suppliers.                                                                               |
| `components(sbomId, first, after, search)` | Paginated components in the SBOM.                                                             |
| `vulns(sbomId, first, after)`              | Paginated vulnerabilities.                                                                    |
| `download(sbomId, ...)`                    | The SBOM file. See [Download](/api/managing-sboms/download-sbom).                             |

The `sbom` query also accepts `projectName`, `projectGroupName`, and `versionName` as an alternative to `projectId` and `sbomId`.

## Mutations

| Mutation                    | Purpose                                           | Guide                                                            |
| --------------------------- | ------------------------------------------------- | ---------------------------------------------------------------- |
| `sbomUpload`                | Upload an SBOM file as a new version.             | [Upload an SBOM](/api/managing-sboms/upload-sbom)                |
| `authorCreate`              | Add an author to a version.                       | [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     |
| `authorUpdate`              | Change an existing author.                        | [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     |
| `authorDelete`              | Remove an author.                                 | [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     |
| `sbomSupplierCreate`        | Add a supplier to a version.                      | [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     |
| `sbomSupplierUpdate`        | Change an existing supplier.                      | [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     |
| `sbomSupplierDelete`        | Remove a supplier.                                | [Edit SBOM Metadata](/api/managing-sboms/edit-sbom-metadata)     |
| `sbomPartCreate`            | Attach a version to another version as a part.    | [Group Products with Parts](/api/inventory/parts)                |
| `sbomPartDelete`            | Remove a part from a version.                     | [Group Products with Parts](/api/inventory/parts)                |
| `componentUpdate`           | Change a component's fields.                      | [Edit a Component](/api/inventory/edit-component)                |
| `compSupplierCreate`        | Add a supplier to a component.                    | [Edit a Component](/api/inventory/edit-component)                |
| `componentVexUpdate`        | Set VEX on one component vulnerability.           | [Vulnerabilities and VEX](/api/security/vulnerabilities-and-vex) |
| `componentVexBulkUpdate`    | Set VEX on many vulnerabilities at once.          | [Vulnerabilities and VEX](/api/security/vulnerabilities-and-vex) |
| `organizationUserInvite`    | Invite a user and assign a role.                  | [Manage Users and Roles](/api/user-management/user-management)   |
| `organizationUserUpdate`    | Change the role a user holds.                     | [Manage Users and Roles](/api/user-management/user-management)   |
| `organizationUserRemove`    | Remove a user from the organization.              | [Manage Users and Roles](/api/user-management/user-management)   |
| `organizationRoleCreate`    | Create a custom role (Enterprise).                | [Manage Users and Roles](/api/user-management/user-management)   |
| `organizationRoleUpdate`    | Change a role's permissions (Enterprise).         | [Manage Users and Roles](/api/user-management/user-management)   |
| `organizationRoleBulkApply` | Assign a role to many users at once (Enterprise). | [Manage Users and Roles](/api/user-management/user-management)   |
| `organizationRoleDelete`    | Delete a custom role (Enterprise).                | [Manage Users and Roles](/api/user-management/user-management)   |
| `samlConfigCreate`          | Set up SSO from IdP metadata (Enterprise).        | [Manage Users and Roles](/api/user-management/user-management)   |
| `samlConfigUpdate`          | Change or disable SSO (Enterprise).               | [Manage Users and Roles](/api/user-management/user-management)   |
| `samlConfigDelete`          | Remove the SSO configuration (Enterprise).        | [Manage Users and Roles](/api/user-management/user-management)   |

## Mutation response pattern

Every mutation returns an `errors` list. An empty list means success. Most also return the object they changed. Always request `errors` and check it. See [Errors](/api/reference/errors).

```graphql
mutation {
  authorCreate(input: { sbomId: "...", name: "..." }) {
    author { id name }
    errors
  }
}
```

## Looking for the rest of the schema?

These docs cover SBOM lifecycle operations. The platform exposes more, for example policies, automation rules, and integrations. If you need an operation that is not listed here, contact <hello@interlynk.io>.


