Skip to content

Commit e40780c

Browse files
committed
add locations docs
1 parent 517b52b commit e40780c

5 files changed

Lines changed: 356 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
title: "Locations Overview"
3+
description: "What Locations are and why they replace Endpoints"
4+
audience: pro
5+
weight: 1
6+
---
7+
8+
**Locations** are a new asset-modelling tool in DefectDojo Pro. They replace the legacy **Endpoints** model and absorb the previous **Components** (library) data, giving DefectDojo a single, polymorphic way to describe *where* a Finding lives — whether that's a URL, a software dependency from an **SBOM**, or, in the future, a **cloud resource ID**, **container image**, or **code repository**.
9+
10+
Locations are currently in **Beta** and will need to be enabled on your instance. To enable Locations on your instance, contact [support@defectdojo.com](mailto:support@defectdojo.com).
11+
12+
## Why Replace Endpoints?
13+
14+
The original Endpoints model was built around URLs and IP addresses — it carried web-app fields like `protocol`, `host`, `port`, `path`, and a fixed status table that was tightly coupled to Findings. Three problems followed:
15+
16+
1. **Limited fidelity.** Endpoints could not cleanly describe non-URL assets such as third-party libraries, container images, or cloud resources, even though scanners increasingly produce findings about those things.
17+
2. **Performance ceiling.** Per-Finding Endpoint_Status rows and the URL-shaped schema did not scale well at large customer volumes.
18+
3. **Components were second-class.** Software libraries lived only as denormalised fields on a Finding, so a library could not exist independently of a vulnerability — making true SBOM management impossible.
19+
20+
Locations fix all three by introducing a **base `Location` object** with a typed payload, plus dedicated **subtypes** for each asset shape. The MVP ships two subtypes:
21+
22+
- **URL Locations** — functional equivalent of the old Endpoints, with the same protocol/host/port/path/query/fragment fields.
23+
- **Dependency Locations** — software libraries identified by [Package URL (pURL)](https://github.com/package-url/purl-spec), used to model SBOM contents.
24+
25+
Future Location types under consideration include cloud provider resource IDs (AWS ARN, Azure Resource ID, GCP Full Resource Name), container images (registry/repository:tag and SHA256 fingerprints), and code repositories.
26+
27+
## Key Concepts
28+
29+
### Locations and Subtypes
30+
31+
A **Location** is the shared parent. It carries:
32+
33+
- A `Location Type` (e.g. `"url"`, `"dependency"`)
34+
- A canonical `Location Value` string used for display, search, and de-duplication
35+
- `Tags` and inherited tags from the parent Asset
36+
- Metadata (custom key/value pairs)
37+
38+
A **subtype** (URL or Dependency) holds the structured fields specific to that kind of location. URLs and Dependencies always live alongside a parent Location object; the subtype's `Location Value` is generated from its structured fields.
39+
40+
### References
41+
42+
Locations are not directly attached to Products or Findings. Instead, two **Reference** objects link them:
43+
44+
- **Asset References** — relationships the Location has to Assets (e.g. `libFoo` is *owned by* Asset 6, *used by* Asset 9). Each reference carries a status (`Active` or `Mitigated`) and an optional **relationship** ("Used By" or "Owned By").
45+
- **Finding References** — relationships the Location has to Findings. Each reference carries a richer status (`Active`, `Mitigated`, `False Positive`, `Risk Accepted`, `Out of Scope`) plus the auditor and audit time.
46+
47+
This separation is what allows a library to exist on a Product *without* needing a Finding — a missing capability in the old Components model.
48+
49+
### Auto-Association at Import Time
50+
51+
When a parser produces a Finding that references a URL or library, the importer:
52+
53+
1. Looks up an existing Location matching the URL or pURL; if none exists, it creates one.
54+
2. Creates a Finding Reference linking the Finding to the Location with status `Active`.
55+
3. Creates (or reuses) an Asset Reference so the Location also lives on the parent Asset.
56+
57+
Existing parsers have been updated to emit Location data when the feature flag is on, and to fall back to the legacy Endpoint model when it is off. No reconfiguration is needed when Locations are enabled — the next import will route through the Locations pipeline automatically.
58+
59+
## What's in the MVP
60+
61+
| Capability | Status |
62+
| --- | --- |
63+
| Foundational `Location`, `URL`, `Dependency` models | Shipped |
64+
| REST API for Locations and References | Shipped (read-only `Location`, full CRUD on References) |
65+
| Endpoint API read-compatibility shim | Shipped |
66+
| Endpoint → URL one-way migration command | Shipped |
67+
| Parser updates (URLs and dependencies) | Shipped for the major parsers |
68+
| SBOM upload (CycloneDX, SPDX v2/v3) | Shipped via `/api/v2/sbom-import/` |
69+
| Pro UI for Locations, URLs, Dependencies | Shipped (Beta) |
70+
| pURL search/filter | Shipped |
71+
| License tracking on dependencies | Partial (`license_expression` field) |
72+
| SWID Tag SBOM format | Not in MVP |
73+
74+
## Where to Go Next
75+
76+
- **Enable the feature** — contact [support@defectdojo.com](mailto:support@defectdojo.com) to turn Locations on for your instance.
77+
- **Migrate from Endpoints** — see [Migrating from Endpoints](../pro__migrating_from_endpoints) for what the migration preserves, and how the legacy Endpoint API behaves afterward.
78+
- **Day-to-day URL workflows** — see [Working with URLs](../pro__working_with_urls).
79+
- **SBOMs and dependencies** — see [Working with SBOMs](../pro__working_with_sboms).
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
title: "Migrating from Endpoints"
3+
description: "What happens when you migrate existing Endpoint data to Locations"
4+
audience: pro
5+
weight: 3
6+
---
7+
8+
When you enable Locations on an existing DefectDojo Pro instance, the data already stored as Endpoints needs to be carried forward into the new Locations model. This page describes migration, what it preserves, and how the legacy Endpoint API behaves once the migration has run.
9+
10+
Note that migration is **one-way**. There is no automated rollback path that re-creates Endpoints from Locations.
11+
12+
## What the Migration Does
13+
14+
For every existing Endpoint, migration will:
15+
16+
1. **Creates a URL Location** (or re-uses an existing one) using the Endpoint's `protocol`, `userinfo`, `host`, `port`, `path`, `query`, and `fragment` fields. The new URL is automatically attached to a parent `Location` object.
17+
2. **Carries over tags.** Every tag on the Endpoint is added to the Location's tag set.
18+
3. **Carries over metadata.** Each `DojoMeta` row attached to the Endpoint is re-pointed at the new Location.
19+
4. **Creates a `LocationProductReference`** so the URL appears under the correct Asset (Product).
20+
5. **Creates a `LocationFindingReference` for every `Endpoint_Status`**:
21+
22+
| Endpoint_Status flag | Resulting Location status |
23+
| --- | --- |
24+
| `risk_accepted=True` | **Risk Accepted** |
25+
| `false_positive=True` | **False Positive** |
26+
| `out_of_scope=True` | **Out of Scope** |
27+
| `mitigated=True` | **Mitigated** |
28+
| (none of the above) | **Active** |
29+
30+
The mapping is order-sensitive: the *first* matching flag wins. This intentionally collapses the old multi-flag combinations down to the single canonical status that Locations use.
31+
32+
33+
## What the Migration Does Not Do
34+
35+
- It does **not** create Dependency Locations. SBOM and library data has never existed as Endpoints, so there is nothing for the migration to convert. To populate Dependencies, upload SBOMs (see [Working with SBOMs](../pro__working_with_sboms)) or re-run scans with parsers that emit dependency data.
36+
- It does **not** delete the original Endpoint or Endpoint_Status rows. They remain in the database to back the read-only legacy API. They are not used by the new UI or by imports after the feature is enabled.
37+
38+
## Endpoint API After Migration
39+
40+
Once Locations is enabled, the legacy Endpoint API enters a **read-compatibility** mode designed to keep existing automations working without code changes — but only for read traffic.
41+
42+
### What still works
43+
44+
- `GET /api/v2/endpoints/` — Returns rows that *look like* Endpoints but are actually projected from Location Product Reference rows joined to URL Locations. The familiar fields (`protocol`, `host`, `port`, `path`, `query`, `fragment`, `tags`, `product`, `active_finding_count`) are all present.
45+
- `GET /api/v2/endpoints/{id}/` — Single-Endpoint retrieval works the same way. The `id` is the original Endpoint ID and is preserved through the migration via the Asset Reference mapping.
46+
- `GET /api/v2/endpoint_status/` and `GET /api/v2/endpoint_status/{id}/` — Returns rows projected from `LocationFindingReference`. The legacy `mitigated`, `false_positive`, `out_of_scope`, and `risk_accepted` boolean fields are reconstructed.
47+
- Filtering by `protocol`, `host`, `port`, `path`, `query`, `fragment`, `product`, and `tag(s)` continues to work.
48+
- The `generate_report` action on individual Endpoints continues to work.
49+
50+
### What returns 403
51+
52+
- `POST`, `PUT`, `PATCH`, and `DELETE` on `/api/v2/endpoints/` and `/api/v2/endpoint_status/` all return `HTTP 403` with the body:
53+
54+
> Writes to this endpoint are deprecated when V3_FEATURE_LOCATIONS is enabled
55+
56+
Clients that write Endpoint data must move to the new Reference endpoints (`POST /api/v2/location_findings/`, `POST /api/v2/location_products/`) and to the URL endpoint (`POST /api/v2/urls/`).
57+
58+
### Behavioural Differences to Watch For
59+
60+
A few things behave differently from the original Endpoint API:
61+
62+
- **Single status instead of flags.** Locations have one status at a time. If your code relied on a Finding being *both* `mitigated=True` *and* `false_positive=True` simultaneously on an Endpoint_Status, that is no longer representable — the migration picks the highest-priority flag (the order shown in the table above).
63+
- **`endpoint` field on Endpoint_Status.** The legacy `endpoint` field is reconstructed by looking up the matching Asset Reference. In rare cases where a Finding's Asset no longer matches its Location's Asset references, this field may be null.
64+
- **Pagination and ordering.** Available ordering fields on the read-compat shim are `host`, `product`, `id`, and `active_finding_count`. If your client orders by another field, switch to one of these or move to the new Locations endpoints.
65+
66+
## Tags and Metadata
67+
68+
Tags applied to Endpoints become tags on the Location object (not on the URL subtype). Tag-based filters in the legacy API continue to match.
69+
70+
Endpoint metadata is re-pointed at the Location during migration. Existing automations that read metadata via `/api/v2/endpoint_meta/` should continue to work; new metadata should be written through the Location endpoints.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
title: "Working with SBOMs"
3+
description: "Manage software dependencies and SBOMs as Locations"
4+
audience: pro
5+
weight: 5
6+
---
7+
8+
DefectDojo Pro models software libraries as **Dependency Locations**. A Dependency is a Location subtype identified by a [Package URL (pURL)](https://github.com/package-url/purl-spec) and intended to represent a single library or package — `org.apache.logging.log4j:log4j-core@2.17.0`, `pypi/django@5.0.2`, `npm/react@18.2.0`, and so on.
9+
10+
Dependencies replace the previous **Components** model, which was attached only to Findings. With Locations, libraries can exist independently of any vulnerability — you can upload an SBOM to an Asset and then let Findings auto-attach to the dependencies they reference as scans come in.
11+
12+
## What a Dependency Holds
13+
14+
Every Dependency is uniquely identified by a pURL, decomposed into atomic fields you can search and filter on:
15+
16+
| Field | Meaning | Example |
17+
| --- | --- | --- |
18+
| `purl_type` | Library ecosystem | `npm`, `pypi`, `maven`, `cargo`, `nuget`, `gem` |
19+
| `namespace` | Vendor or organisation | `org.apache.logging` |
20+
| `name` | Library name | `log4j-core` |
21+
| `version` | Specific version | `2.17.0` |
22+
| `qualifiers` *(optional)* | Implementation details | `arch=amd64` |
23+
| `subpath` *(optional)* | Path within an archive or monorepo | `src/lib/foo` |
24+
| `artifact_hashes` *(optional)* | Fingerprints | SHA256 sums |
25+
| `license_expression` *(optional)* | SPDX license expression | `Apache-2.0`, `MIT` |
26+
| `file_path` *(optional)* | Where the library was found in the project | `package-lock.json` |
27+
28+
This atomic decomposition is what makes pURL-based search useful: you can ask *"all `pypi` packages in the `django` namespace at version 4.x"* and DefectDojo can answer that without parsing a free-text string.
29+
30+
## Owned-By vs Used-By
31+
32+
When a Dependency is associated with an Asset, the Asset Reference carries an optional **relationship** describing *how* the library belongs to the Asset:
33+
34+
- **`owned_by`***"this library is owned by this Asset"*. Use this for first-party libraries an Asset publishes or maintains.
35+
- **`used_by`***"this library is used by this Asset"*. Use this for third-party dependencies an Asset consumes.
36+
37+
The same library can be `owned_by` one Asset and `used_by` several others, which is exactly the relationship you need to answer *"who consumes the package my team publishes?"* during vulnerability triage.
38+
39+
## Uploading an SBOM
40+
41+
To populate Dependencies in bulk, upload an SBOM file against a Product. The endpoint is:
42+
43+
```
44+
POST /api/v2/sbom-import/
45+
```
46+
47+
| Field | Description |
48+
| --- | --- |
49+
| `product` | The target Product (Asset) ID |
50+
| `file` | The SBOM file |
51+
| `scan_type` | The SBOM format — see supported formats below |
52+
| `replace` *(optional)* | If `true`, stale Product associations not backed by an existing Finding reference are removed. Default: `false` (cumulative) |
53+
54+
The importer parses the file, extracts `Dependency` records, deduplicates them against existing Locations (creating new ones as needed), and creates Asset References linking each Dependency to the Product. The Pro UI exposes the same upload flow — see the **Upload SBOM** action on a Product's Locations tab.
55+
56+
### Supported Formats
57+
58+
The MVP ships parsers for the two dominant SBOM formats:
59+
60+
- **CycloneDX** — JSON and XML
61+
- **SPDX** — JSON (v2 and v3), XML, and tag-value
62+
63+
SWID Tag format is not yet supported.
64+
65+
### Replace vs Append
66+
67+
By default, repeated uploads are **additive**: dependencies that already exist on the Asset are kept, new ones are added, and nothing is removed. This matches the typical workflow of incremental SBOM updates.
68+
69+
Set `replace=true` to prune. When replace mode is on, after a successful import the importer removes Product associations that were not present in the new SBOM **and** are not currently referenced by an active Finding. References tied to active Findings are preserved even in replace mode, so you do not lose vulnerability context just because a new SBOM omits a package.
70+
71+
## Findings That Reference Libraries
72+
73+
When a parser ingests a vulnerability tied to a library — for example, an SCA tool reporting `CVE-2021-44228` against `log4j-core@2.14.1` — the importer:
74+
75+
1. Looks up an existing Dependency Location by pURL, or creates a new one.
76+
2. Creates a `LocationFindingReference` linking the Finding to the Dependency with status **Active**.
77+
3. Creates a `LocationProductReference` so the Dependency also appears on the parent Product, if it isn't already.
78+
79+
Because Findings and SBOM uploads share the same underlying Dependency objects, a Finding ingested *before* an SBOM upload will be retroactively visible in the SBOM view, and vice versa.
80+
81+
## REST API
82+
83+
| Task | Endpoint |
84+
| --- | --- |
85+
| Upload an SBOM | `POST /api/v2/sbom-import/` |
86+
| List Dependencies | `GET /api/v2/dependencies/` |
87+
| Create a Dependency manually | `POST /api/v2/dependencies/` |
88+
| List Dependency Locations | `GET /api/v2/location/?location_type=dependency` |
89+
| Link a Dependency to a Finding | `POST /api/v2/location_findings/` |
90+
| Link a Dependency to a Product (with `owned_by` / `used_by`) | `POST /api/v2/location_products/` |
91+
92+
Filters on `/api/v2/dependencies/` include the pURL component fields, tags, and ordering on `name`, `version`, and active-finding count.
93+
94+
## In the Pro UI
95+
96+
When Locations is enabled, the navigation exposes:
97+
98+
- **Locations / Dependencies** — Global list of every Dependency across the instance, with pURL filters.
99+
- **Locations on a Product/Asset** — Per-Asset view that shows both URLs and Dependencies, with the **Upload SBOM** action surfaced on the Dependencies tab.
100+
- **New Dependency** — Form to create a single library by entering its pURL components manually.
101+
- **Findings detail** — A Finding that touches a library shows its Dependency Locations alongside any URL Locations, so you can see *"this CVE affects `log4j-core@2.14.1` on Asset 6 and Asset 9"* in one place.
102+
103+
## What's Not in the MVP
104+
105+
- **SWID Tag SBOM format** — Not parsed. CycloneDX or SPDX is required.
106+
- **License risk scoring** — The `license_expression` field is captured when present in the SBOM, but DefectDojo does not yet flag findings on license incompatibility. License-based reporting is on the roadmap as a follow-up to the Locations MVP.
107+
- **Container image and cloud resource Locations** — Future Location subtypes. For now, libraries discovered inside a container image are recorded as Dependencies; the container image itself is not yet a first-class Location.

0 commit comments

Comments
 (0)