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

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