|
| 1 | +# About projects |
| 2 | + |
| 3 | +A **project** is the unit of tracking in Dependency-Track. Everything else, from components |
| 4 | +to findings to policy violations to metrics, hangs off projects. The **portfolio** is the |
| 5 | +set of all projects in an instance, and how you model it shapes what reports, alerts, and |
| 6 | +aggregations are useful later. |
| 7 | + |
| 8 | +This page explains what a project is, how projects relate to each other, and the deliberate |
| 9 | +limits of the model. |
| 10 | + |
| 11 | +## What a project is |
| 12 | + |
| 13 | +Each project has: |
| 14 | + |
| 15 | +- A name and an optional version that together identify it. |
| 16 | +- A classifier naming the kind of thing the project represents (an app, a library, a |
| 17 | + container image, a firmware image, and so on, matching CycloneDX). See the |
| 18 | + [classifier list](../reference/projects.md#classifiers). |
| 19 | +- Optional ecosystem identifiers: a Package URL, a CPE, or a SWID tag. |
| 20 | +- Descriptive metadata such as a group, a description, authors, a supplier, a manufacturer, |
| 21 | + and external references. |
| 22 | +- Tags (categorical labels) and project properties (typed key-value metadata). |
| 23 | +- An optional parent, forming a hierarchy. |
| 24 | +- An access list controlling which teams can see it. |
| 25 | +- Lifecycle state: an active flag, the timestamp of the last BOM import, the timestamp of |
| 26 | + the last vulnerability analysis, and the current risk score. |
| 27 | + |
| 28 | +<!-- TODO(screenshot): docs/assets/images/concepts/projects/project-detail-header.png - Project detail header for a regular project at /projects/{uuid}/overview. Show: the version dropdown (closed), the "LATEST VERSION" badge, tag chips, description, and the severity pie charts to anchor the "what defines a project" discussion. --> |
| 29 | + |
| 30 | +## What Dependency-Track does *not* assume |
| 31 | + |
| 32 | +A few modelling decisions are deliberately left to the user. Knowing them up front avoids |
| 33 | +arguments later: |
| 34 | + |
| 35 | +- **Dependency-Track does not prescribe what a project is.** A project can map to a single |
| 36 | + library, a deployable service, an environment of a service, or an entire product line. |
| 37 | + Pick the granularity that matches how you triage and report. |
| 38 | +- **Versions are opaque strings.** Dependency-Track does not parse, compare, or sort them. |
| 39 | + Semver-like ordering is not assumed. The "latest version" pointer is a manually maintained |
| 40 | + flag (see [Versions](#versions)), not a computed one. |
| 41 | +- **Projects cannot depend on projects.** Component-level dependencies live inside a BOM. The |
| 42 | + only relationship Dependency-Track tracks between projects is the parent-child hierarchy |
| 43 | + below, and that hierarchy is organizational, not a dependency graph. If service A consumes |
| 44 | + service B, that fact is not expressible as a project relation. |
| 45 | +- **A name and version together identify a project globally.** That pair is unique across |
| 46 | + the entire instance, independent of where the project sits in the hierarchy. The same |
| 47 | + name and version cannot exist under two different parents. |
| 48 | + |
| 49 | +## Active and inactive projects |
| 50 | + |
| 51 | +A project is **active** by default. Marking it inactive records the time and changes its |
| 52 | +behavior: |
| 53 | + |
| 54 | +- It disappears from active portfolio views unless the viewer opts in to show inactive |
| 55 | + projects. |
| 56 | +- It cannot serve as a parent. |
| 57 | +- It becomes eligible for retention-driven deletion (see [Retention](#retention)). Active |
| 58 | + projects never are. |
| 59 | + |
| 60 | +A project with active children cannot become inactive. Mark the children first, or accept |
| 61 | +that the parent stays around for as long as something underneath stays live. |
| 62 | + |
| 63 | +## Hierarchies |
| 64 | + |
| 65 | +A project can have one parent and any number of children. Hierarchies are organizational: |
| 66 | +they let you group by product, environment, team, or any other axis that fits how you work. |
| 67 | + |
| 68 | +Two things flow through the hierarchy: |
| 69 | + |
| 70 | +- **Access control.** A team that can see a parent can also see the parent's descendants. |
| 71 | + See [Access control](#access-control) below. |
| 72 | +- **Aggregated metrics on collection projects.** A [collection project](#collection-projects) reads |
| 73 | + metrics from its children to produce its own. Regular parents do not. The risk score on a |
| 74 | + regular parent reflects only that parent's own components, not its children. |
| 75 | + |
| 76 | +Constraints worth remembering: |
| 77 | + |
| 78 | +- A project cannot be its own ancestor. Dependency-Track rejects cycles. |
| 79 | +- The hierarchy does not affect identity. A name and version pair remains globally unique, |
| 80 | + so the same combination cannot appear under two different parents. |
| 81 | + |
| 82 | +(Inactive projects cannot serve as a parent either. See [Active and inactive projects](#active-and-inactive-projects).) |
| 83 | + |
| 84 | +<!-- TODO(screenshot): docs/assets/images/concepts/projects/projects-tree-view.png - Projects landing at /projects with "Show flat view" toggled OFF, the tree expanded one level, and at least one collection-project parent visible. Show: the portfolio as a hierarchy and the calculator icon that distinguishes a collection project from a regular parent. --> |
| 85 | + |
| 86 | +## Collection projects |
| 87 | + |
| 88 | +A **collection project** is a parent whose only role is to combine metrics from its |
| 89 | +children. It holds no components or services of its own. Instead, it surfaces the metrics |
| 90 | +of its children using one of three modes: |
| 91 | + |
| 92 | +| Mode | Behavior | |
| 93 | +|:---------------------------|:--------------------------------------------------------------------| |
| 94 | +| Roll up every direct child | Combines metrics from every direct child. | |
| 95 | +| Roll up by tag | Combines metrics from direct children carrying a chosen tag. | |
| 96 | +| Roll up the latest version | Combines metrics from direct children marked as the latest version. | |
| 97 | + |
| 98 | +Collection projects are useful for product or portfolio aggregations that span versions, |
| 99 | +services, or environments without forcing every child to share a tag scheme. They differ |
| 100 | +from regular parents in three important ways: |
| 101 | + |
| 102 | +- They have no classifier. The classifier field disappears once a project becomes a |
| 103 | + collection project. |
| 104 | +- They cannot have components, services, or a dependency graph. The detail page hides those |
| 105 | + tabs and shows a *Collection Projects* tab listing children instead. |
| 106 | +- They do not accept BOM uploads. |
| 107 | + |
| 108 | +For when to reach for which mode and how to set them up, see |
| 109 | +[Organizing projects into hierarchies](../guides/user/organizing-projects.md). |
| 110 | + |
| 111 | +<!-- TODO(screenshot): docs/assets/images/concepts/projects/collection-project-header.png - Project detail header for a collection project, hovering the calculator icon so the tooltip showing the configured logic is visible. Show: how a collection project surfaces in the UI and that the regular Components / Services / Dependency Graph tabs are absent (Collection Projects tab is present instead). --> |
| 112 | + |
| 113 | +## Versions |
| 114 | + |
| 115 | +Two or more projects can share a name. Together they represent the version history of one |
| 116 | +logical thing. A *latest version* flag marks one of them as current. At most one version |
| 117 | +per name carries the flag. |
| 118 | + |
| 119 | +The latest-version flag drives: |
| 120 | + |
| 121 | +- The latest-version collection mode. |
| 122 | +- The badge URLs that resolve a project by name without specifying a version. |
| 123 | +- The *LATEST VERSION* badge in the project header. |
| 124 | + |
| 125 | +Because Dependency-Track does not parse version strings, nothing here is automatic. You |
| 126 | +set the flag manually when promoting a release. Cloning a project produces a new sibling |
| 127 | +with chosen inclusions (components, services, tags, properties, audit history, access list, |
| 128 | +policy violations) and is the typical path for starting a new version. See |
| 129 | +[Managing project versions](../guides/user/managing-project-versions.md). |
| 130 | + |
| 131 | +## Tags and properties |
| 132 | + |
| 133 | +A project carries two kinds of metadata. A **tag** is a categorical label that many |
| 134 | +projects can share. Policies, alerts, the tag-filtered collection mode, and the project |
| 135 | +list filter all read tags. For the wider model see [About tags](tags.md). A **project |
| 136 | +property** is a typed key-value pair (group, name, value, type, optional description) |
| 137 | +scoped to one project. The policy engine, alerting, and collection logic do not consult |
| 138 | +properties. Use a tag for a label that may apply to many projects, and a property for |
| 139 | +per-project structured data you want to read back later. |
| 140 | + |
| 141 | +## Retention |
| 142 | + |
| 143 | +By default, inactive projects stick around indefinitely. When the operator turns on |
| 144 | +retention, a scheduled maintenance task deletes inactive projects according to one of two |
| 145 | +policies: |
| 146 | + |
| 147 | +- **By age**: delete inactive projects older than a configured cutoff. |
| 148 | +- **By version count**: keep the most recent N inactive versions per name, and delete the |
| 149 | + rest. |
| 150 | + |
| 151 | +Active projects are never touched. See |
| 152 | +[Configuring project retention](../guides/administration/configuring-project-retention.md). |
| 153 | + |
| 154 | +## Access control |
| 155 | + |
| 156 | +Each project has an access list. A team can see a project when: |
| 157 | + |
| 158 | +- The team appears on that project's access list, **or** on the access list of the |
| 159 | + project's ancestors. Granting a team access to a parent also grants access to every |
| 160 | + descendant. |
| 161 | +- The team holds the `PORTFOLIO_ACCESS_CONTROL_BYPASS` permission, which overrides the |
| 162 | + access list entirely. |
| 163 | + |
| 164 | +Use this when designing a hierarchy: shared access concerns sit at parents, and the |
| 165 | +children inherit them automatically. To revoke inherited access, remove the team from |
| 166 | +the ancestor that granted it. A descendant cannot opt out on its own. |
| 167 | + |
| 168 | +For the wider model (users, teams, and which permissions gate which actions), see |
| 169 | +[About access control](access-control.md) and the |
| 170 | +[Permissions reference](../reference/permissions.md). |
0 commit comments