summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/administration/high_availability/database.md2
-rw-r--r--doc/api/api_resources.md6
-rw-r--r--doc/api/project_vulnerabilities.md215
-rw-r--r--doc/api/vulnerabilities.md223
-rw-r--r--doc/api/vulnerability_exports.md138
-rw-r--r--doc/api/vulnerability_issue_links.md217
-rw-r--r--doc/development/packages.md2
-rw-r--r--doc/user/admin_area/settings/usage_statistics.md6
-rw-r--r--doc/user/application_security/offline_deployments/index.md1
-rw-r--r--doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_v12_10.pngbin0 -> 26548 bytes
-rw-r--r--doc/user/application_security/vulnerabilities/index.md69
-rw-r--r--doc/user/compliance/license_compliance/index.md19
-rw-r--r--doc/user/permissions.md22
13 files changed, 907 insertions, 13 deletions
diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md
index 9cb95559412..01af971d664 100644
--- a/doc/administration/high_availability/database.md
+++ b/doc/administration/high_availability/database.md
@@ -199,7 +199,7 @@ Few notes on the service itself:
- Passwords will be stored in the following locations:
- `/etc/gitlab/gitlab.rb`: hashed
- `/var/opt/gitlab/pgbouncer/pg_auth`: hashed
- - `/var/opt/gitlab/gitlab-consul/.pgpass`: plaintext
+ - `/var/opt/gitlab/consul/.pgpass`: plaintext
##### PostgreSQL information
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 34d2c40d1f9..aebbc95750d 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -71,8 +71,10 @@ The following API resources are available in the project context:
| [Services](services.md) | `/projects/:id/services` |
| [Tags](tags.md) | `/projects/:id/repository/tags` |
| [Visual Review discussions](visual_review_discussions.md) **(STARTER**) | `/projects/:id/merge_requests/:merge_request_id/visual_review_discussions` |
-| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE)** | `/projects/:id/vulnerabilities` |
-| [Vulnerability Findings](vulnerability_findings.md) **(ULTIMATE)** | `/projects/:id/vulnerability_findings` |
+| [Vulnerabilities](vulnerabilities.md) **(ULTIMATE)** | `/vulnerabilities/:id` |
+| [Vulnerability exports](vulnerability_exports.md) **(ULTIMATE)** | `/projects/:id/vulnerability_exports` |
+| [Project vulnerabilities](project_vulnerabilities.md) **(ULTIMATE)** | `/projects/:id/vulnerabilities` |
+| [Vulnerability findings](vulnerability_findings.md) **(ULTIMATE)** | `/projects/:id/vulnerability_findings` |
| [Wikis](wikis.md) | `/projects/:id/wikis` |
## Group resources
diff --git a/doc/api/project_vulnerabilities.md b/doc/api/project_vulnerabilities.md
new file mode 100644
index 00000000000..84bbc789b0c
--- /dev/null
+++ b/doc/api/project_vulnerabilities.md
@@ -0,0 +1,215 @@
+# Project Vulnerabilities API **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
+
+CAUTION: **Caution:**
+This API is currently in development and is protected by a **disabled**
+[feature flag](../development/feature_flags/index.md).
+On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
+(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
+To test if the Vulnerabilities API was successfully enabled, run the following command:
+`Feature.enabled?(:first_class_vulnerabilities)`.
+
+CAUTION: **Caution:**
+This API is in an alpha stage and considered unstable.
+The response payload may be subject to change or breakage
+across GitLab releases.
+
+Every API call to vulnerabilities must be [authenticated](README.md#authentication).
+
+Vulnerability permissions inherit permissions from their project. If a project is
+private, and a user isn't a member of the project to which the vulnerability
+belongs, requests to that project will return a `404 Not Found` status code.
+
+## Vulnerabilities pagination
+
+API results are paginated, and `GET` requests return 20 results at a time by default.
+
+Read more on [pagination](README.md#pagination).
+
+## List project vulnerabilities
+
+List all of a project's vulnerabilities.
+
+If an authenticated user does not have permission to
+[use the Project Security Dashboard](../user/permissions.md#project-members-permissions),
+`GET` requests for vulnerabilities of this project will result in a `403` status code.
+
+```plaintext
+GET /projects/:id/vulnerabilities
+```
+
+| Attribute | Type | Required | Description |
+| ------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user. |
+
+```bash
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/4/vulnerabilities
+```
+
+Example response:
+
+```json
+[
+ {
+ "author_id": 1,
+ "confidence": "medium",
+ "created_at": "2020-04-07T14:01:04.655Z",
+ "description": null,
+ "dismissed_at": null,
+ "dismissed_by_id": null,
+ "due_date": null,
+ "finding": {
+ "confidence": "medium",
+ "created_at": "2020-04-07T14:01:04.630Z",
+ "id": 103,
+ "location_fingerprint": "228998b5db51d86d3b091939e2f5873ada0a14a1",
+ "metadata_version": "2.0",
+ "name": "Regular Expression Denial of Service in debug",
+ "primary_identifier_id": 135,
+ "project_fingerprint": "05e7cc9978ca495cf739a9f707ed34811e41c615",
+ "project_id": 24,
+ "raw_metadata": "{\"category\":\"dependency_scanning\",\"name\":\"Regular Expression Denial of Service\",\"message\":\"Regular Expression Denial of Service in debug\",\"description\":\"The debug module is vulnerable to regular expression denial of service when untrusted user input is passed into the `o` formatter. It takes around 50k characters to block for 2 seconds making this a low severity issue.\",\"cve\":\"yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a\",\"severity\":\"Unknown\",\"solution\":\"Upgrade to latest versions.\",\"scanner\":{\"id\":\"gemnasium\",\"name\":\"Gemnasium\"},\"location\":{\"file\":\"yarn.lock\",\"dependency\":{\"package\":{\"name\":\"debug\"},\"version\":\"1.0.5\"}},\"identifiers\":[{\"type\":\"gemnasium\",\"name\":\"Gemnasium-37283ed4-0380-40d7-ada7-2d994afcc62a\",\"value\":\"37283ed4-0380-40d7-ada7-2d994afcc62a\",\"url\":\"https://deps.sec.gitlab.com/packages/npm/debug/versions/1.0.5/advisories\"}],\"links\":[{\"url\":\"https://nodesecurity.io/advisories/534\"},{\"url\":\"https://github.com/visionmedia/debug/issues/501\"},{\"url\":\"https://github.com/visionmedia/debug/pull/504\"}],\"remediations\":[null]}",
+ "report_type": "dependency_scanning",
+ "scanner_id": 63,
+ "severity": "low",
+ "updated_at": "2020-04-07T14:01:04.664Z",
+ "uuid": "f1d528ae-d0cc-47f6-a72f-936cec846ae7",
+ "vulnerability_id": 103
+ },
+ "id": 103,
+ "last_edited_at": null,
+ "last_edited_by_id": null,
+ "project": {
+ "created_at": "2020-04-07T13:54:25.634Z",
+ "description": "",
+ "id": 24,
+ "name": "security-reports",
+ "name_with_namespace": "gitlab-org / security-reports",
+ "path": "security-reports",
+ "path_with_namespace": "gitlab-org/security-reports"
+ },
+ "project_default_branch": "master",
+ "report_type": "dependency_scanning",
+ "resolved_at": null,
+ "resolved_by_id": null,
+ "resolved_on_default_branch": false,
+ "severity": "low",
+ "start_date": null,
+ "state": "detected",
+ "title": "Regular Expression Denial of Service in debug",
+ "updated_at": "2020-04-07T14:01:04.655Z",
+ "updated_by_id": null
+ }
+]
+```
+
+## New vulnerability
+
+Creates a new vulnerability.
+
+If an authenticated user does not have a permission to
+[create a new vulnerability](../user/permissions.md#project-members-permissions),
+this request will result in a `403` status code.
+
+```plaintext
+POST /projects/:id/vulnerabilities?finding_id=<your_finding_id>
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ----------------- | ---------- | -----------------------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) which the authenticated user is a member of |
+| `finding_id` | integer or string | yes | The ID of a Vulnerability Finding from which the new Vulnerability will be created |
+
+The other attributes of a newly created Vulnerability are populated from
+its source Vulnerability Finding, or with these default values:
+
+| Attribute | Value |
+|--------------|-------------------------------------------------------|
+| `author` | The authenticated user |
+| `title` | The `name` attribute of a Vulnerability Finding |
+| `state` | `opened` |
+| `severity` | The `severity` attribute of a Vulnerability Finding |
+| `confidence` | The `confidence` attribute of a Vulnerability Finding |
+
+```shell
+curl --header POST "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/vulnerabilities?finding_id=1
+```
+
+Example response:
+
+```json
+{
+ "author_id": 1,
+ "confidence": "medium",
+ "created_at": "2020-04-07T14:01:04.655Z",
+ "description": null,
+ "dismissed_at": null,
+ "dismissed_by_id": null,
+ "due_date": null,
+ "finding": {
+ "confidence": "medium",
+ "created_at": "2020-04-07T14:01:04.630Z",
+ "id": 103,
+ "location_fingerprint": "228998b5db51d86d3b091939e2f5873ada0a14a1",
+ "metadata_version": "2.0",
+ "name": "Regular Expression Denial of Service in debug",
+ "primary_identifier_id": 135,
+ "project_fingerprint": "05e7cc9978ca495cf739a9f707ed34811e41c615",
+ "project_id": 24,
+ "raw_metadata": "{\"category\":\"dependency_scanning\",\"name\":\"Regular Expression Denial of Service\",\"message\":\"Regular Expression Denial of Service in debug\",\"description\":\"The debug module is vulnerable to regular expression denial of service when untrusted user input is passed into the `o` formatter. It takes around 50k characters to block for 2 seconds making this a low severity issue.\",\"cve\":\"yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a\",\"severity\":\"Unknown\",\"solution\":\"Upgrade to latest versions.\",\"scanner\":{\"id\":\"gemnasium\",\"name\":\"Gemnasium\"},\"location\":{\"file\":\"yarn.lock\",\"dependency\":{\"package\":{\"name\":\"debug\"},\"version\":\"1.0.5\"}},\"identifiers\":[{\"type\":\"gemnasium\",\"name\":\"Gemnasium-37283ed4-0380-40d7-ada7-2d994afcc62a\",\"value\":\"37283ed4-0380-40d7-ada7-2d994afcc62a\",\"url\":\"https://deps.sec.gitlab.com/packages/npm/debug/versions/1.0.5/advisories\"}],\"links\":[{\"url\":\"https://nodesecurity.io/advisories/534\"},{\"url\":\"https://github.com/visionmedia/debug/issues/501\"},{\"url\":\"https://github.com/visionmedia/debug/pull/504\"}],\"remediations\":[null]}",
+ "report_type": "dependency_scanning",
+ "scanner_id": 63,
+ "severity": "low",
+ "updated_at": "2020-04-07T14:01:04.664Z",
+ "uuid": "f1d528ae-d0cc-47f6-a72f-936cec846ae7",
+ "vulnerability_id": 103
+ },
+ "id": 103,
+ "last_edited_at": null,
+ "last_edited_by_id": null,
+ "project": {
+ "created_at": "2020-04-07T13:54:25.634Z",
+ "description": "",
+ "id": 24,
+ "name": "security-reports",
+ "name_with_namespace": "gitlab-org / security-reports",
+ "path": "security-reports",
+ "path_with_namespace": "gitlab-org/security-reports"
+ },
+ "project_default_branch": "master",
+ "report_type": "dependency_scanning",
+ "resolved_at": null,
+ "resolved_by_id": null,
+ "resolved_on_default_branch": false,
+ "severity": "low",
+ "start_date": null,
+ "state": "detected",
+ "title": "Regular Expression Denial of Service in debug",
+ "updated_at": "2020-04-07T14:01:04.655Z",
+ "updated_by_id": null
+}
+```
+
+### Errors
+
+This error occurs when a Finding chosen to create a Vulnerability from is not found, or
+is already associated with a different Vulnerability:
+
+```plaintext
+A Vulnerability Finding is not found or already attached to a different Vulnerability
+```
+
+Status code: `400`
+
+Example response:
+
+```json
+{
+ "message": {
+ "base": [
+ "finding is not found or is already attached to a vulnerability"
+ ]
+ }
+}
+```
diff --git a/doc/api/vulnerabilities.md b/doc/api/vulnerabilities.md
index 21b3a6f4c96..ff1a6a7ebcd 100644
--- a/doc/api/vulnerabilities.md
+++ b/doc/api/vulnerabilities.md
@@ -1,3 +1,224 @@
# Vulnerabilities API **(ULTIMATE)**
-This document was moved to [another location](vulnerability_findings.md).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
+
+NOTE: **Note:**
+The former Vulnerabilities API was renamed to Vulnerability Findings API
+and its documentation was moved to [a different location](vulnerability_findings.md).
+This document now describes the new Vulnerabilities API that provides access to
+[Standalone Vulnerabilities](https://gitlab.com/groups/gitlab-org/-/epics/634).
+
+CAUTION: **Caution:**
+This API is currently in development and is protected by a **disabled**
+[feature flag](../development/feature_flags/index.md).
+On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
+(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
+To test if the Vulnerabilities API was successfully enabled, run the following command:
+`Feature.enabled?(:first_class_vulnerabilities)`.
+
+CAUTION: **Caution:**
+This API is in an alpha stage and considered unstable.
+The response payload may be subject to change or breakage
+across GitLab releases.
+
+Every API call to vulnerabilities must be [authenticated](README.md#authentication).
+
+Vulnerability permissions inherit permissions from their project. If a project is
+private, and a user isn't a member of the project to which the vulnerability
+belongs, requests to that project will return a `404 Not Found` status code.
+
+## Single vulnerability
+
+Gets a single vulnerability
+
+```plaintext
+GET /vulnerabilities/:id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer or string | yes | The ID of a Vulnerability to get |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/vulnerabilities/1
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "title": "Predictable pseudorandom number generator",
+ "description": null,
+ "state": "opened",
+ "severity": "medium",
+ "confidence": "medium",
+ "report_type": "sast",
+ "project": {
+ "id": 32,
+ "name": "security-reports",
+ "full_path": "/gitlab-examples/security/security-reports",
+ "full_name": "gitlab-examples / security / security-reports"
+ },
+ "author_id": 1,
+ "updated_by_id": null,
+ "last_edited_by_id": null,
+ "closed_by_id": null,
+ "start_date": null,
+ "due_date": null,
+ "created_at": "2019-10-13T15:08:40.219Z",
+ "updated_at": "2019-10-13T15:09:40.382Z",
+ "last_edited_at": null,
+ "closed_at": null
+}
+```
+
+## Confirm vulnerability
+
+Confirms a given vulnerability. Returns status code `304` if the vulnerability is already confirmed.
+
+If an authenticated user does not have permission to
+[confirm vulnerabilities](../user/permissions.md#project-members-permissions),
+this request will result in a `403` status code.
+
+```plaintext
+POST /vulnerabilities/:id/confirm
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer or string | yes | The ID of a vulnerability to confirm |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/vulnerabilities/5/confirm"
+```
+
+Example response:
+
+```json
+{
+ "id": 2,
+ "title": "Predictable pseudorandom number generator",
+ "description": null,
+ "state": "confirmed",
+ "severity": "medium",
+ "confidence": "medium",
+ "report_type": "sast",
+ "project": {
+ "id": 32,
+ "name": "security-reports",
+ "full_path": "/gitlab-examples/security/security-reports",
+ "full_name": "gitlab-examples / security / security-reports"
+ },
+ "author_id": 1,
+ "updated_by_id": null,
+ "last_edited_by_id": null,
+ "closed_by_id": null,
+ "start_date": null,
+ "due_date": null,
+ "created_at": "2019-10-13T15:08:40.219Z",
+ "updated_at": "2019-10-13T15:09:40.382Z",
+ "last_edited_at": null,
+ "closed_at": null
+}
+```
+
+## Resolve vulnerability
+
+Resolves a given vulnerability. Returns status code `304` if the vulnerability is already resolved.
+
+If an authenticated user does not have permission to
+[resolve vulnerabilities](../user/permissions.md#project-members-permissions),
+this request will result in a `403` status code.
+
+```plaintext
+POST /vulnerabilities/:id/resolve
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer or string | yes | The ID of a Vulnerability to resolve |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/vulnerabilities/5/resolve"
+```
+
+Example response:
+
+```json
+{
+ "id": 2,
+ "title": "Predictable pseudorandom number generator",
+ "description": null,
+ "state": "resolved",
+ "severity": "medium",
+ "confidence": "medium",
+ "report_type": "sast",
+ "project": {
+ "id": 32,
+ "name": "security-reports",
+ "full_path": "/gitlab-examples/security/security-reports",
+ "full_name": "gitlab-examples / security / security-reports"
+ },
+ "author_id": 1,
+ "updated_by_id": null,
+ "last_edited_by_id": null,
+ "closed_by_id": null,
+ "start_date": null,
+ "due_date": null,
+ "created_at": "2019-10-13T15:08:40.219Z",
+ "updated_at": "2019-10-13T15:09:40.382Z",
+ "last_edited_at": null,
+ "closed_at": null
+}
+```
+
+## Dismiss vulnerability
+
+Dismisses a given vulnerability. Returns status code `304` if the vulnerability is already dismissed.
+
+If an authenticated user does not have permission to
+[dismiss vulnerabilities](../user/permissions.md#project-members-permissions),
+this request will result in a `403` status code.
+
+```plaintext
+POST /vulnerabilities/:id/dismiss
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer or string | yes | The ID of a vulnerability to dismiss |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/vulnerabilities/5/dismiss"
+```
+
+Example response:
+
+```json
+{
+ "id": 2,
+ "title": "Predictable pseudorandom number generator",
+ "description": null,
+ "state": "closed",
+ "severity": "medium",
+ "confidence": "medium",
+ "report_type": "sast",
+ "project": {
+ "id": 32,
+ "name": "security-reports",
+ "full_path": "/gitlab-examples/security/security-reports",
+ "full_name": "gitlab-examples / security / security-reports"
+ },
+ "author_id": 1,
+ "updated_by_id": null,
+ "last_edited_by_id": null,
+ "closed_by_id": null,
+ "start_date": null,
+ "due_date": null,
+ "created_at": "2019-10-13T15:08:40.219Z",
+ "updated_at": "2019-10-13T15:09:40.382Z",
+ "last_edited_at": null,
+ "closed_at": null
+}
+```
diff --git a/doc/api/vulnerability_exports.md b/doc/api/vulnerability_exports.md
new file mode 100644
index 00000000000..f2666783087
--- /dev/null
+++ b/doc/api/vulnerability_exports.md
@@ -0,0 +1,138 @@
+# Project Vulnerabilities API **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/197494) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
+
+CAUTION: **Caution:**
+This API is currently in development and is protected by a **disabled**
+[feature flag](../development/feature_flags/index.md).
+On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
+(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
+To test if the Vulnerability Exports API was successfully enabled, run the following command:
+`Feature.enabled?(:first_class_vulnerabilities)`.
+
+CAUTION: **Caution:**
+This API is in an alpha stage and considered unstable.
+The response payload may be subject to change or breakage
+across GitLab releases.
+
+Every API call to vulnerability exports must be [authenticated](README.md#authentication).
+
+Vulnerability export permissions inherit permissions from their project. If a project is
+private and a user isn't a member of the project to which the vulnerability
+belongs, requests to that project return a `404 Not Found` status code.
+Vulnerability exports can be only accessed by the export's author.
+
+## Create vulnerability export
+
+Creates a new vulnerability export.
+
+If an authenticated user doesn't have permission to
+[create a new vulnerability](../user/permissions.md#project-members-permissions),
+this request results in a `403` status code.
+
+```plaintext
+POST /projects/:id/vulnerability_exports
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | ----------------- | ---------- | -----------------------------------------------------------------------------------------------------------------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path](README.md#namespaced-path-encoding) of the project which the authenticated user is a member of |
+
+```shell
+curl --header POST "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/vulnerability_exports
+```
+
+The created vulnerability export will be automatically deleted after 1 hour.
+
+Example response:
+
+```json
+{
+ "id": 2,
+ "created_at": "2020-03-30T09:35:38.746Z",
+ "project_id": 1,
+ "format": "csv",
+ "status": "created",
+ "started_at": null,
+ "finished_at": null,
+ "_links": {
+ "self": "https://gitlab.example.com/api/v4/projects/1/vulnerability_exports/2",
+ "download": "https://gitlab.example.com/api/v4/projects/1/vulnerability_exports/2/download"
+ }
+}
+```
+
+## Get single vulnerability export
+
+Gets a single vulnerability export.
+
+```plaintext
+POST /projects/:id/vulnerability_exports/:vulnerability_export_id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer or string | yes | The vulnerability's ID |
+| `vulnerability_export_id` | integer or string | yes | The vulnerability export's ID |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/vulnerability_exports/2
+```
+
+If the vulnerability export isn't finished, the response is `202 Accepted`.
+
+Example response:
+
+```json
+{
+ "id": 2,
+ "created_at": "2020-03-30T09:35:38.746Z",
+ "project_id": 1,
+ "format": "csv",
+ "status": "finished",
+ "started_at": "2020-03-30T09:36:54.469Z",
+ "finished_at": "2020-03-30T09:36:55.008Z",
+ "_links": {
+ "self": "https://gitlab.example.com/api/v4/projects/1/vulnerability_exports/2",
+ "download": "https://gitlab.example.com/api/v4/projects/1/vulnerability_exports/2/download"
+ }
+}
+```
+
+## Download vulnerability export
+
+Downloads a single vulnerability export.
+
+```plaintext
+POST /projects/:id/vulnerability_exports/:vulnerability_export_id/download
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer or string | yes | The vulnerability's ID |
+| `vulnerability_export_id` | integer or string | yes | The vulnerability export's ID |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/vulnerability_exports/2/download
+```
+
+The response will be `404 Not Found` if the vulnerability export is not finished yet or was not found.
+
+Example response:
+
+```csv
+Scanner Type,Scanner Name,Status,Vulnerability,Details,Additional Info,Severity,CVE
+container_scanning,Clair,confirmed,CVE-2017-16997 in glibc,,CVE-2017-16997 in glibc,critical,CVE-2017-16997
+container_scanning,Clair,detected,CVE-2017-18269 in glibc,,CVE-2017-18269 in glibc,critical,CVE-2017-18269
+container_scanning,Clair,detected,CVE-2018-1000001 in glibc,,CVE-2018-1000001 in glibc,high,CVE-2018-1000001
+container_scanning,Clair,detected,CVE-2016-10228 in glibc,,CVE-2016-10228 in glibc,medium,CVE-2016-10228
+container_scanning,Clair,confirmed,CVE-2010-4052 in glibc,,CVE-2010-4052 in glibc,low,CVE-2010-4052
+container_scanning,Clair,detected,CVE-2018-18520 in elfutils,,CVE-2018-18520 in elfutils,low,CVE-2018-18520
+container_scanning,Clair,detected,CVE-2018-16869 in nettle,,CVE-2018-16869 in nettle,unknown,CVE-2018-16869
+dependency_scanning,Gemnasium,detected,Regular Expression Denial of Service in debug,,Regular Expression Denial of Service in debug,unknown,yarn.lock:debug:gemnasium:37283ed4-0380-40d7-ada7-2d994afcc62a
+dependency_scanning,Gemnasium,detected,Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js,,Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js,unknown,yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98
+sast,Find Security Bugs,detected,Predictable pseudorandom number generator,,Predictable pseudorandom number generator,medium,818bf5dacb291e15d9e6dc3c5ac32178:PREDICTABLE_RANDOM:src/main/java/com/gitlab/security_products/tests/App.java:47
+sast,Find Security Bugs,detected,Cipher with no integrity,,Cipher with no integrity,medium,e6449b89335daf53c0db4c0219bc1634:CIPHER_INTEGRITY:src/main/java/com/gitlab/security_products/tests/App.java:29
+sast,Find Security Bugs,detected,Predictable pseudorandom number generator,,Predictable pseudorandom number generator,medium,e8ff1d01f74cd372f78da8f5247d3e73:PREDICTABLE_RANDOM:src/main/java/com/gitlab/security_products/tests/App.java:41
+sast,Find Security Bugs,confirmed,ECB mode is insecure 2,,ECB mode is insecure,medium,ea0f905fc76f2739d5f10a1fd1e37a10:ECB_MODE:src/main/java/com/gitlab/security_products/tests/App.java:29
+```
diff --git a/doc/api/vulnerability_issue_links.md b/doc/api/vulnerability_issue_links.md
new file mode 100644
index 00000000000..05213e788c4
--- /dev/null
+++ b/doc/api/vulnerability_issue_links.md
@@ -0,0 +1,217 @@
+# Vulnerability Issue links API **(ULTIMATE)**
+
+CAUTION: **Caution:**
+This API is in an alpha stage and considered unstable.
+The response payload may be subject to change or breakage
+across GitLab releases.
+
+## List related issues
+
+Get a list of related issues of a given issue, sorted by the relationship creation datetime (ascending).
+Issues will be filtered according to the user authorizations.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/links
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `issue_iid` | integer | yes | The internal ID of a project's issue |
+
+```json
+[
+ {
+ "id" : 84,
+ "iid" : 14,
+ "issue_link_id": 1
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/14",
+ "confidential": false,
+ "weight": null,
+ }
+]
+```
+
+## Create an issue link
+
+Creates a two-way relation between two issues. User must be allowed to update both issues in order to succeed.
+
+```plaintext
+POST /projects/:id/issues/:issue_iid/links
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `issue_iid` | integer | yes | The internal ID of a project's issue |
+| `target_project_id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) of a target project |
+| `target_issue_iid` | integer or string | yes | The internal ID of a target project's issue |
+
+```json
+{
+ "source_issue" : {
+ "id" : 83,
+ "iid" : 11,
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/11",
+ "confidential": false,
+ "weight": null,
+ },
+ "target_issue" : {
+ "id" : 84,
+ "iid" : 14,
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/14",
+ "confidential": false,
+ "weight": null,
+ }
+}
+```
+
+## Delete an issue link
+
+Deletes an issue link, removing the two-way relationship.
+
+```plaintext
+DELETE /projects/:id/issues/:issue_iid/links/:issue_link_id
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `issue_iid` | integer | yes | The internal ID of a project's issue |
+| `issue_link_id` | integer or string | yes | The ID of an issue relationship |
+
+```json
+{
+ "source_issue" : {
+ "id" : 83,
+ "iid" : 11,
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/11",
+ "confidential": false,
+ "weight": null,
+ },
+ "target_issue" : {
+ "id" : 84,
+ "iid" : 14,
+ "project_id" : 4,
+ "created_at" : "2016-01-07T12:44:33.959Z",
+ "title" : "Issues with auth",
+ "state" : "opened",
+ "assignees" : [],
+ "assignee" : null,
+ "labels" : [
+ "bug"
+ ],
+ "author" : {
+ "name" : "Alexandra Bashirian",
+ "avatar_url" : null,
+ "state" : "active",
+ "web_url" : "https://gitlab.example.com/eileen.lowe",
+ "id" : 18,
+ "username" : "eileen.lowe"
+ },
+ "description" : null,
+ "updated_at" : "2016-01-07T12:44:33.959Z",
+ "milestone" : null,
+ "subscribed" : true,
+ "user_notes_count": 0,
+ "due_date": null,
+ "web_url": "http://example.com/example/example/issues/14",
+ "confidential": false,
+ "weight": null,
+ }
+}
+```
diff --git a/doc/development/packages.md b/doc/development/packages.md
index 0880e053901..66b50ce12c8 100644
--- a/doc/development/packages.md
+++ b/doc/development/packages.md
@@ -63,6 +63,8 @@ The current state of existing package registries availability is:
| Maven | Yes | Yes | Yes |
| Conan | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/11679) | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/11679) | Yes |
| NPM | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/36853) | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/issues/36853) |
+| NuGet | Yes | No - [open issue](https://gitlab.com/gitlab-org/gitlab/-/issues/36423) | No |
+| PyPI | Yes | No | No |
NOTE: **Note:** NPM is currently a hybrid of the instance level and group level.
It is using the top-level group or namespace as the defining portion of the name
diff --git a/doc/user/admin_area/settings/usage_statistics.md b/doc/user/admin_area/settings/usage_statistics.md
index cbfdf2d188c..f28bab6ad86 100644
--- a/doc/user/admin_area/settings/usage_statistics.md
+++ b/doc/user/admin_area/settings/usage_statistics.md
@@ -197,9 +197,11 @@ but commented out to help encourage others to add to it in the future. -->
|clusters_enabled|counts||
|project_clusters_enabled|counts||
|group_clusters_enabled|counts||
+|instance_clusters_enabled|counts||
|clusters_disabled|counts||
|project_clusters_disabled|counts||
|group_clusters_disabled|counts||
+|instance_clusters_disabled|counts||
|clusters_platforms_eks|counts||
|clusters_platforms_gke|counts||
|clusters_platforms_user|counts||
@@ -211,6 +213,7 @@ but commented out to help encourage others to add to it in the future. -->
|clusters_applications_runner|counts||
|clusters_applications_knative|counts||
|clusters_applications_elastic_stack|counts||
+|clusters_management_project|counts||
|in_review_folder|counts||
|grafana_integrated_projects|counts||
|groups|counts||
@@ -382,11 +385,14 @@ but commented out to help encourage others to add to it in the future. -->
|clusters_applications_helm|usage_activity_by_stage|configure|
|clusters_applications_ingress|usage_activity_by_stage|configure|
|clusters_applications_knative|usage_activity_by_stage|configure|
+|clusters_management_project|usage_activity_by_stage|configure|
|clusters_disabled|usage_activity_by_stage|configure|
|clusters_enabled|usage_activity_by_stage|configure|
|clusters_platforms_gke|usage_activity_by_stage|configure|
|clusters_platforms_eks|usage_activity_by_stage|configure|
|clusters_platforms_user|usage_activity_by_stage|configure|
+|instance_clusters_disabled|usage_activity_by_stage|configure|
+|instance_clusters_enabled|usage_activity_by_stage|configure|
|group_clusters_disabled|usage_activity_by_stage|configure|
|group_clusters_enabled|usage_activity_by_stage|configure|
|project_clusters_disabled|usage_activity_by_stage|configure|
diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md
index db309357530..5a5f149a3bf 100644
--- a/doc/user/application_security/offline_deployments/index.md
+++ b/doc/user/application_security/offline_deployments/index.md
@@ -78,3 +78,4 @@ above. You can find more information at each of the pages below:
- [Container scanning offline directions](../container_scanning/index.md#running-container-scanning-in-an-offline-environment)
- [SAST offline directions](../sast/index.md#gitlab-sast-in-an-offline-environment)
- [DAST offline directions](../dast/index.md#running-dast-in-an-offline-environment)
+- [License Compliance offline directions](../../compliance/license_compliance/index.md#running-license-compliance-in-an-offline-environment)
diff --git a/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_v12_10.png b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_v12_10.png
new file mode 100644
index 00000000000..0fdb8d1e201
--- /dev/null
+++ b/doc/user/application_security/vulnerabilities/img/standalone_vulnerability_page_v12_10.png
Binary files differ
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
new file mode 100644
index 00000000000..5cb4f16e0d8
--- /dev/null
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -0,0 +1,69 @@
+---
+type: reference, howto
+---
+
+# Standalone Vulnerability pages
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13561) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
+
+CAUTION: **Warning:**
+This feature is currently [Alpha](https://about.gitlab.com/handbook/product/#alpha-beta-ga).
+You can begin using it, but it may receive important changes in the future.
+
+Each security vulnerability in the [Vulnerability List](../dependency_list/index.md) has its own standalone
+page.
+
+![Standalone vulnerability page](img/standalone_vulnerability_page_v12_10.png)
+
+On the standalone vulnerability page, you can interact with the vulnerability in
+several different ways:
+
+- [Change the Vulnerability Status](#changing-vulnerability-status) - You can change the
+ status of a vulnerability to **Detected**, **Confirmed**, **Dismissed**, or **Resolved**.
+- [Create issue](#creating-an-issue-for-a-vulnerability) - Create a new issue with the
+ title and description prepopulated with information from the vulnerability report.
+ By default, such issues are [confidential](../../project/issues/confidential_issues.md).
+- [Solution](#automatic-remediation-solutions-for-vulnerabilities) - For some vulnerabilities,
+ a solution is provided for how to fix the vulnerability.
+
+## Changing vulnerability status
+
+You can switch the status of a vulnerability using the **Status** dropdown to one of
+the following values:
+
+| State | Description |
+|-----------|-------------------------------------------------------------------|
+| Detected | The default state for a newly discovered vulnerability |
+| Confirmed | A user has seen this vulnerability and confirmed it to be real |
+| Dismissed | A user has seen this vulnerability and dismissed it |
+| Resolved | The vulnerability has been fixed and is no longer in the codebase |
+
+## Creating an issue for a vulnerability
+
+You can create an issue for a vulnerability by selecting the **Create issue** button.
+
+This creates a [confidential issue](../../project/issues/confidential_issues.md) in the
+project the vulnerability came from, and prepopulates it with useful information from
+the vulnerability report. After the issue is created, GitLab redirects you to the
+issue page so you can edit, assign, or comment on the issue.
+
+## Automatic remediation solutions for vulnerabilities
+
+You can fix some vulnerabilities by applying the solution that GitLab automatically
+generates for you. GitLab supports the following scanners:
+
+- [Dependency Scanning](../dependency_scanning/index.md): Automatic Patch creation
+ is only available for Node.js projects managed with `yarn`.
+- [Container Scanning](../container_scanning/index.md).
+
+### Manually applying a suggested patch
+
+To apply a patch automatically generated by GitLab to fix a vulnerability:
+
+1. Open the issue created in [Create issue](#creating-an-issue-for-a-vulnerability).
+1. In the **Issue description**, scroll to **Solution** and download the linked patch file.
+1. Ensure your local project has the same commit checked out that was used to generate the patch.
+1. Run `git apply remediation.patch` to apply the patch.
+1. Verify and commit the changes to your branch.
+
+![Apply patch for dependency scanning](../img/vulnerability_solution.png)
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index 485e9d8213d..9fcc9acf5ea 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -198,6 +198,22 @@ you can use the `MAVEN_CLI_OPTS` environment variable.
Read more on [how to use private Maven repos](../../application_security/index.md#using-private-maven-repos).
+You can also use `MAVEN_CLI_OPTS` to connect to a trusted Maven repository that uses a self-signed
+or internally trusted certificate. For example:
+
+```yaml
+include:
+ - template: License-Scanning.gitlab-ci.yml
+
+license_scanning:
+ variables:
+ MAVEN_CLI_OPTS: -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true -Dmaven.wagon.http.ssl.insecure=true
+```
+
+Alternatively, you can use a Java key store to verify the TLS connection. For instructions on how to
+generate a key store file, see the
+[Maven Guide to Remote repository access through authenticated HTTPS](http://maven.apache.org/guides/mini/guide-repository-ssl.html).
+
### Selecting the version of Python
> - [Introduced](https://gitlab.com/gitlab-org/security-products/license-management/-/merge_requests/36) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
@@ -305,6 +321,9 @@ process:
1. Ensure the package registry is reachable from within the GitLab environment and that the package
manager is configured to use your preferred package registry.
+Additional [configuration](#using-private-maven-repos) may be needed for connecting to private Maven
+repositories.
+
## Project policies for License Compliance
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5940) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.4.
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 76a33559666..fabe6fd40c9 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -57,7 +57,7 @@ The following table depicts the various user permission levels in a project.
| View Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View License list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View licenses in Dependency list **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
| View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
| View GitLab Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control-core) | ✓ | ✓ | ✓ | ✓ | ✓ |
@@ -84,15 +84,15 @@ The following table depicts the various user permission levels in a project.
| See a list of merge requests | | ✓ | ✓ | ✓ | ✓ |
| View project statistics | | ✓ | ✓ | ✓ | ✓ |
| View Error Tracking list | | ✓ | ✓ | ✓ | ✓ |
-| Create/edit/delete [Releases](project/releases/index.md)| | | ✓ | ✓ | ✓ |
+| Create new merge request | | ✓ | ✓ | ✓ | ✓ |
| Pull from [Conan repository](packages/conan_repository/index.md), [Maven repository](packages/maven_repository/index.md), or [NPM registry](packages/npm_registry/index.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
| Publish to [Conan repository](packages/conan_repository/index.md), [Maven repository](packages/maven_repository/index.md), or [NPM registry](packages/npm_registry/index.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
+| Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
+| Create/edit/delete [Releases](project/releases/index.md)| | | ✓ | ✓ | ✓ |
| Create new branches | | | ✓ | ✓ | ✓ |
| Push to non-protected branches | | | ✓ | ✓ | ✓ |
| Force push to non-protected branches | | | ✓ | ✓ | ✓ |
| Remove non-protected branches | | | ✓ | ✓ | ✓ |
-| Create new merge request | | ✓ | ✓ | ✓ | ✓ |
| Assign merge requests | | | ✓ | ✓ | ✓ |
| Label merge requests | | | ✓ | ✓ | ✓ |
| Lock merge request threads | | | ✓ | ✓ | ✓ |
@@ -107,8 +107,12 @@ The following table depicts the various user permission levels in a project.
| Remove a container registry image | | | ✓ | ✓ | ✓ |
| Create/edit/delete project milestones | | | ✓ | ✓ | ✓ |
| Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| View vulnerabilities in Dependency list **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| Create issue from vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| View vulnerability findings in Dependency list **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| Dismiss vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| Resolve vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| Dismiss vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
| Apply code change suggestions | | | ✓ | ✓ | ✓ |
| Create and edit wiki pages | | | ✓ | ✓ | ✓ |
@@ -217,21 +221,21 @@ group.
| View group epic **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
| Create/edit group epic **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
| Manage group labels | | ✓ | ✓ | ✓ | ✓ |
+| See a container registry | | ✓ | ✓ | ✓ | ✓ |
| Create project in group | | | ✓ (3) | ✓ (3) | ✓ (3) |
| Create/edit/delete group milestones | | | ✓ | ✓ | ✓ |
-| See a container registry | | ✓ | ✓ | ✓ | ✓ |
| Enable/disable a dependency proxy **(PREMIUM)** | | | ✓ | ✓ | ✓ |
| Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
+| View/manage group-level Kubernetes cluster | | | | ✓ | ✓ |
| Create subgroup | | | | ✓ (1) | ✓ |
+| Edit epic comments (posted by any user) **(ULTIMATE)** | | | | ✓ (2) | ✓ (2) |
| Edit group | | | | | ✓ |
| Manage group level CI/CD variables | | | | | ✓ |
| Manage group members | | | | | ✓ |
| Remove group | | | | | ✓ |
| Delete group epic **(ULTIMATE)** | | | | | ✓ |
-| Edit epic comments (posted by any user) **(ULTIMATE)** | | | | ✓ (2) | ✓ (2) |
| View group Audit Events | | | | | ✓ |
| Disable notification emails | | | | | ✓ |
-| View/manage group-level Kubernetes cluster | | | | ✓ | ✓ |
1. Groups can be set to [allow either Owners or Owners and
Maintainers to create subgroups](group/subgroups/index.md#creating-a-subgroup)