From e0a8998454748b7c3b623d4f2259454ba4d9d669 Mon Sep 17 00:00:00 2001 From: nscuro Date: Mon, 18 May 2026 17:17:04 +0200 Subject: [PATCH] Extend portfolio access control docs * Explicitly calls out that permissions and project access are orthogonal concepts. * Provides example pattern that demonstrates how per-project permissions can be emulated. * Documents how ACL is inherited, may be bypassed, and behaves WRT project creation. Signed-off-by: nscuro --- docs/concepts/access-control.md | 159 +++++++++++++++--- .../guides/administration/configuring-ldap.md | 8 + .../guides/administration/configuring-oidc.md | 11 +- docs/includes/abbreviations.md | 1 + 4 files changed, 151 insertions(+), 28 deletions(-) diff --git a/docs/concepts/access-control.md b/docs/concepts/access-control.md index 785f23b..c5f213e 100644 --- a/docs/concepts/access-control.md +++ b/docs/concepts/access-control.md @@ -2,8 +2,12 @@ Dependency-Track uses a role-based access control model built around **permissions**, **teams**, and **users**. Permissions can be assigned to teams or directly to users. -A user's effective permissions are the union of their direct permissions and the -permissions of every team they belong to. + +!!! note "Effective permissions" + + A user's effective permissions are the **union** of their direct permissions + and the permissions of every team they belong to. Permissions are never + intersected or downgraded by team membership. ## Users @@ -18,23 +22,6 @@ Three types of users exist: All user types share the same permission model. The authentication mechanism determines how the system verifies a user's identity, not what they can access. -### LDAP authentication flow - -With LDAP, Dependency-Track authenticates users by performing a service-account -bind to locate the user's directory entry, then attempting a bind with the user's -own credentials to verify their password. On success, the system grants access. -With user provisioning turned on, Dependency-Track creates the account -automatically on first login. - -### OIDC authentication flow - -With OIDC, the frontend redirects the user to the identity provider's authorization -endpoint. After the user authenticates, the IdP returns an ID token to the frontend, -which forwards it to the API server for validation. The API server verifies the token -against the IdP's discovery endpoint and extracts the username from the configured -claim. With user provisioning turned on, Dependency-Track creates accounts on -first login. - ## Teams A team is a named collection of users and API keys. Teams hold permissions, which makes @@ -52,20 +39,138 @@ API keys belong to a team and carry the same permissions as that team. They auth automated access (CI/CD pipelines, integrations) without associating requests with a specific human user. +Deleting a team also deletes its API keys and any project access assignments +made through it. Projects and user accounts are unaffected, but users lose the +permissions they had inherited from the deleted team. + ## Portfolio access control -By default, all teams with `VIEW_PORTFOLIO` can see every project. Access Control Lists -(ACLs) restrict portfolio visibility so that a team can only see the projects explicitly -assigned to it. +By default, every principal with `VIEW_PORTFOLIO` can see every project. +Portfolio Access Control (PAC) restricts that visibility so a team can only act +on the projects explicitly assigned to it. The per-project list of assigned +teams is the project's Access Control List (ACL). + +With PAC enabled, ACL membership gates every operation on a project: viewing, +BOM upload, editing, deletion, and vulnerability triage. The portfolio +permissions (`VIEW_PORTFOLIO`, `PORTFOLIO_MANAGEMENT_UPDATE`, and so on) become +*necessary but not sufficient*: a principal must hold the relevant permission +**and** belong to a team on the project's ACL. + +Enable PAC in **Administration > Access Management > Portfolio Access Control**. -Enable ACLs in **Administration > Access Management > Portfolio Access Control**. -Once active, every project must be explicitly assigned to at least one team for it to -be visible to non-administrator users. +!!! warning "Enabling PAC affects existing projects" -ACLs are most useful in multi-tenant scenarios where different teams should not see -each other's projects. For single-team or open environments, ACLs add management + Existing projects keep their data but start with no team assignments. Until + an administrator (or a principal with `PORTFOLIO_ACCESS_CONTROL_BYPASS`) + assigns at least one team to each project, those projects become invisible + to all non-administrator users. Plan the assignment rollout before enabling + PAC on a production instance. + +PAC is most useful in multi-tenant scenarios where different teams should not see +each other's projects. For single-team or open environments, PAC adds management overhead without security benefit. +### How PAC interacts with permissions + +Permissions and ACLs are orthogonal: + +* **Permissions** define *what a principal can do*, such as uploading BOMs, + editing projects, or triaging vulnerabilities. They are global to the + principal. The model has no per-project permissions. +* **ACLs** define *which projects a principal can do it on*. They gate both reads + and writes, but do not change which capabilities the principal holds. + +To act on a project, a principal needs both the relevant permission *and* ACL +access to that project. A user with `PORTFOLIO_MANAGEMENT_UPDATE` can edit every +project they have ACL access to, and none of the ones they don't. Removing a +team from a project's ACL revokes that team's access to the project but leaves +the team's permissions unchanged elsewhere. + +### Pattern: separating permission teams from access teams + +Because permissions and ACLs compose independently, a useful pattern is to +split teams by role: + +* **Permission teams** carry capabilities (`VIEW_PORTFOLIO`, + `VULNERABILITY_ANALYSIS`, and so on) but are not assigned to any project. +* **Access teams** hold no permissions but are assigned to a subset of + projects. + +A user joins one team of each kind. Their effective rights are the union of +all their teams' permissions, scoped to the union of all their teams' ACL +grants. This emulates per-project permissions without the model having to +support them directly. + +For an organization with a *Front Office* and a *Back Office* portfolio: + +```mermaid +flowchart LR + Alice(["Alice
Developer, Front Office"]) + Bob(["Bob
Developer, Back Office"]) + Carol(["Carol
Auditor, Front + Back Office"]) + + subgraph Permission teams + Devs["Developers
VIEW_PORTFOLIO
VIEW_VULNERABILITY"] + Auditors["Auditors
VIEW_PORTFOLIO
VIEW_VULNERABILITY
VULNERABILITY_ANALYSIS"] + end + + subgraph Access teams + FO["Front Office
(no permissions)"] + BO["Back Office
(no permissions)"] + end + + FP[("Front Office
projects")] + BP[("Back Office
projects")] + + Alice --> Devs + Alice --> FO + Bob --> Devs + Bob --> BO + Carol --> Auditors + Carol --> FO + Carol --> BO + + FO -. ACL .-> FP + BO -. ACL .-> BP +``` + +Resulting effective access: + +| User | Can view | Can triage vulnerabilities on | +|:------|:--------------------------------------|:------------------------------| +| Alice | Front Office projects | none | +| Bob | Back Office projects | none | +| Carol | Front Office and Back Office projects | both portfolios | + +Adding a new domain becomes a single new access team and its ACL assignments. +Granting an existing user analyst rights on that domain is a team membership +change, not a per-project edit. + +### Inheritance through the project hierarchy + +ACL grants are inherited down the project hierarchy. Granting a team access to a +parent project grants access to every descendant, current and future. Assigning +teams at the top of a project tree is usually preferable to assigning them on +every leaf. + +### Bypassing PAC + +The `PORTFOLIO_ACCESS_CONTROL_BYPASS` permission exempts a principal from PAC +entirely: they see every project as if PAC were disabled. Reserve it for +administrators and trusted automation that legitimately needs to operate across +the full portfolio. + +### Project creation under PAC + +When an API key creates a project (for example, via BOM upload with +`PROJECT_CREATION_UPLOAD`), the API key's team is added to the new project's +ACL automatically. + +When a user creates a project, they must designate an owning team from those +they belong to. The chosen team is added to the new project's ACL. A project +created with no team assignment is invisible to everyone except administrators +and holders of `PORTFOLIO_ACCESS_CONTROL_BYPASS` until one is assigned. + ## Further reading * [Permissions reference](../reference/permissions.md) for the full permissions table diff --git a/docs/guides/administration/configuring-ldap.md b/docs/guides/administration/configuring-ldap.md index 0082ec2..0d1cedf 100644 --- a/docs/guides/administration/configuring-ldap.md +++ b/docs/guides/administration/configuring-ldap.md @@ -4,6 +4,14 @@ Dependency-Track can authenticate users against an LDAP directory such as Micros Active Directory, ApacheDS, or any other LDAP-compatible server. Once enabled, users log in with their directory credentials rather than a locally managed password. +## Authentication flow + +Dependency-Track authenticates LDAP users by first performing a service-account +bind to locate the user's directory entry, then attempting a bind with the +user's own credentials to verify their password. On success, the system grants +access. With user provisioning enabled, Dependency-Track creates the account +automatically on first login. + ## Prerequisites - A service account in the LDAP directory with read access to users and groups. diff --git a/docs/guides/administration/configuring-oidc.md b/docs/guides/administration/configuring-oidc.md index 4a63326..8c265d5 100644 --- a/docs/guides/administration/configuring-oidc.md +++ b/docs/guides/administration/configuring-oidc.md @@ -6,9 +6,18 @@ Dependency-Track supports SSO via [OpenID Connect](https://openid.net/specs/open !!! note "Frontend configuration required" OIDC requires configuration on both the **API server** and the **frontend**. - The API server validates tokens; the frontend initiates the OIDC flow. + The API server validates tokens, while the frontend initiates the OIDC flow. Configure both with the same issuer and client ID. +## Authentication flow + +The frontend redirects the user to the identity provider's authorization +endpoint. After the user authenticates, the IdP returns an ID token to the +frontend, which forwards it to the API server for validation. The API server +verifies the token against the IdP's discovery endpoint and extracts the +username from the configured claim. With user provisioning enabled, +Dependency-Track creates the account automatically on first login. + ## Prerequisites - An OIDC-compatible identity provider with a configured client (app). diff --git a/docs/includes/abbreviations.md b/docs/includes/abbreviations.md index e499267..2552578 100644 --- a/docs/includes/abbreviations.md +++ b/docs/includes/abbreviations.md @@ -12,6 +12,7 @@ *[NVD]: National Vulnerability Database *[OIDC]: OpenID Connect *[OSV]: Open Source Vulnerabilities +*[PAC]: Portfolio Access Control *[PURL]: Package URL, a standardized format for identifying software packages *[SBOM]: Software Bill of Materials *[SLO]: Service Level Objectives