Add latest changes from gitlab-org/gitlab@master
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: ci_jwt_include_environment
|
||||||
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53431
|
||||||
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321206
|
||||||
|
milestone: '13.9'
|
||||||
|
type: development
|
||||||
|
group: group::configure
|
||||||
|
default_enabled: false
|
|
@ -477,9 +477,10 @@ application server, or a Gitaly node.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# Name of storage hash must match storage name in git_data_dirs on GitLab
|
# Name of storage hash must match storage name in git_data_dirs on GitLab
|
||||||
# server ('praefect') and in git_data_dirs on Gitaly nodes ('gitaly-1')
|
# server ('default') and in git_data_dirs on Gitaly nodes ('gitaly-1')
|
||||||
praefect['virtual_storages'] = {
|
praefect['virtual_storages'] = {
|
||||||
'default' => {
|
'default' => {
|
||||||
|
'nodes' => {
|
||||||
'gitaly-1' => {
|
'gitaly-1' => {
|
||||||
'address' => 'tcp://GITALY_HOST_1:8075',
|
'address' => 'tcp://GITALY_HOST_1:8075',
|
||||||
'token' => 'PRAEFECT_INTERNAL_TOKEN',
|
'token' => 'PRAEFECT_INTERNAL_TOKEN',
|
||||||
|
@ -494,8 +495,13 @@ application server, or a Gitaly node.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
In [GitLab 13.8 and earlier](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4988),
|
||||||
|
Gitaly nodes were configured directly under the virtual storage, and not under the `nodes` key.
|
||||||
|
|
||||||
1. [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2013) in GitLab 13.1 and later, enable [distribution of reads](#distributed-reads).
|
1. [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2013) in GitLab 13.1 and later, enable [distribution of reads](#distributed-reads).
|
||||||
|
|
||||||
1. Save the changes to `/etc/gitlab/gitlab.rb` and [reconfigure
|
1. Save the changes to `/etc/gitlab/gitlab.rb` and [reconfigure
|
||||||
|
@ -686,7 +692,7 @@ because we rely on Praefect to route operations correctly.
|
||||||
Particular attention should be shown to:
|
Particular attention should be shown to:
|
||||||
|
|
||||||
- The `gitaly['auth_token']` configured in this section must match the `token`
|
- The `gitaly['auth_token']` configured in this section must match the `token`
|
||||||
value under `praefect['virtual_storages']` on the Praefect node. This was set
|
value under `praefect['virtual_storages']['nodes']` on the Praefect node. This was set
|
||||||
in the [previous section](#praefect). This document uses the placeholder
|
in the [previous section](#praefect). This document uses the placeholder
|
||||||
`PRAEFECT_INTERNAL_TOKEN` throughout.
|
`PRAEFECT_INTERNAL_TOKEN` throughout.
|
||||||
- The storage names in `git_data_dirs` configured in this section must match the
|
- The storage names in `git_data_dirs` configured in this section must match the
|
||||||
|
@ -1140,11 +1146,7 @@ You can configure:
|
||||||
praefect['virtual_storages'] = {
|
praefect['virtual_storages'] = {
|
||||||
'default' => {
|
'default' => {
|
||||||
'default_replication_factor' => 1,
|
'default_replication_factor' => 1,
|
||||||
# nodes...
|
# ...
|
||||||
'gitaly-1' => {
|
|
||||||
'address' => 'tcp://GITALY_HOST_1:8075',
|
|
||||||
'token' => 'PRAEFECT_INTERNAL_TOKEN',
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
Before Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 2.6 KiB |
|
@ -12,7 +12,7 @@ Each vulnerability report contains vulnerabilities from the scans of the most re
|
||||||
The vulnerability reports display the total number of vulnerabilities by severity (for example,
|
The vulnerability reports display the total number of vulnerabilities by severity (for example,
|
||||||
Critical, High, Medium, Low, Info, Unknown). Below this, a table shows each vulnerability's detected date, status, severity, description, identifier, the scanner where it was detected, and activity (including related issues or available solutions). By default, the vulnerability report is filtered to display all detected and confirmed vulnerabilities.
|
Critical, High, Medium, Low, Info, Unknown). Below this, a table shows each vulnerability's detected date, status, severity, description, identifier, the scanner where it was detected, and activity (including related issues or available solutions). By default, the vulnerability report is filtered to display all detected and confirmed vulnerabilities.
|
||||||
|
|
||||||
![Vulnerability Report](img/group_vulnerability_report_v13_7.png)
|
![Vulnerability Report](img/group_vulnerability_report_v13_9.png)
|
||||||
|
|
||||||
You can filter which vulnerabilities display by:
|
You can filter which vulnerabilities display by:
|
||||||
|
|
||||||
|
@ -22,6 +22,17 @@ You can filter which vulnerabilities display by:
|
||||||
| Severity | Critical, High, Medium, Low, Info, Unknown |
|
| Severity | Critical, High, Medium, Low, Info, Unknown |
|
||||||
| Scanner | [Available Scanners](../index.md#security-scanning-tools) |
|
| Scanner | [Available Scanners](../index.md#security-scanning-tools) |
|
||||||
| Project | Projects configured in the Security Center settings, or all projects in the group for the group level report. This filter is not displayed on the project level vulnerability report |
|
| Project | Projects configured in the Security Center settings, or all projects in the group for the group level report. This filter is not displayed on the project level vulnerability report |
|
||||||
|
| Activity | Vulnerabilities with issues and vulnerabilities that are no longer detected in the default branch |
|
||||||
|
|
||||||
|
The Activity filter behaves differently from the other Vulnerability Report filters. The other filter options all OR together to show results from any vulnerability matching one of the filter criteria. With the Activity filter, the selected values form mutually exclusive sets to allow for precisely locating the desired vulnerability records. Additionally, not all options can be selected in combination. Selection behavior when using the Activity filter:
|
||||||
|
|
||||||
|
| Activity Selection | Results Displayed |
|
||||||
|
| --- | --- |
|
||||||
|
| All | Vulnerabilities with any Activity status (same as ignoring this filter). Selecting this will deselect any other Activity filter options. |
|
||||||
|
| No activity | Only vulnerabilities without either an associated Issue or that are no longer detected. Selecting this will deselect any other Activity filter options. |
|
||||||
|
| With issues | Only vulnerabilities with one or more associated issues. Does not include vulnerabilities that also are no longer detected. |
|
||||||
|
| No longer detected | Only vulnerabilities that are no longer detected in the latest pipeline scan of the `default` branch. Does not include vulnerabilities with one or more associated issues. |
|
||||||
|
| With issues and No longer detected | Only vulnerabilities that have one or more associated issues and also are no longer detected in the latest pipeline scan of the `default` branch. |
|
||||||
|
|
||||||
Clicking any vulnerability in the table takes you to its
|
Clicking any vulnerability in the table takes you to its
|
||||||
[vulnerability details](../vulnerabilities) page to see more information on that vulnerability.
|
[vulnerability details](../vulnerabilities) page to see more information on that vulnerability.
|
||||||
|
@ -35,7 +46,7 @@ After you create the issue, the linked issue icon in the vulnerability list:
|
||||||
- Indicates that an issue has been created for that vulnerability.
|
- Indicates that an issue has been created for that vulnerability.
|
||||||
- Shows a tooltip that contains a link to the issue.
|
- Shows a tooltip that contains a link to the issue.
|
||||||
|
|
||||||
![Display attached issues](img/vulnerability_list_table_v13_4.png)
|
![Display attached issues](img/vulnerability_list_table_v13_9.png)
|
||||||
|
|
||||||
Contents of the unfiltered vulnerability report can be exported using our [export feature](#export-vulnerabilities)
|
Contents of the unfiltered vulnerability report can be exported using our [export feature](#export-vulnerabilities)
|
||||||
|
|
||||||
|
@ -44,7 +55,7 @@ You can also dismiss vulnerabilities in the table:
|
||||||
1. Select the checkbox for each vulnerability you want to dismiss.
|
1. Select the checkbox for each vulnerability you want to dismiss.
|
||||||
1. In the menu that appears, select the reason for dismissal and click **Dismiss Selected**.
|
1. In the menu that appears, select the reason for dismissal and click **Dismiss Selected**.
|
||||||
|
|
||||||
![Project Vulnerability Report](img/project_security_dashboard_dismissal_v13_4.png)
|
![Project Vulnerability Report](img/project_security_dashboard_dismissal_v13_9.png)
|
||||||
|
|
||||||
## Project Vulnerability Report
|
## Project Vulnerability Report
|
||||||
|
|
||||||
|
@ -59,7 +70,7 @@ default branch. There's also a link to view this in more detail. In the case of
|
||||||
the number of failures is indicated. The failure notification takes you directly to
|
the number of failures is indicated. The failure notification takes you directly to
|
||||||
the **Failed jobs** tab of the pipeline page.
|
the **Failed jobs** tab of the pipeline page.
|
||||||
|
|
||||||
![Project Vulnerability Report](img/project_security_dashboard_v13_5.png)
|
![Project Vulnerability Report](img/project_security_dashboard_v13_9.png)
|
||||||
|
|
||||||
## Export vulnerabilities
|
## Export vulnerabilities
|
||||||
|
|
||||||
|
@ -88,5 +99,3 @@ The fields in the export include:
|
||||||
- [CVE](https://cve.mitre.org/) (Common Vulnerabilities and Exposures)
|
- [CVE](https://cve.mitre.org/) (Common Vulnerabilities and Exposures)
|
||||||
- [CWE](https://cwe.mitre.org/) (Common Weakness Enumeration)
|
- [CWE](https://cwe.mitre.org/) (Common Weakness Enumeration)
|
||||||
- Other Identifiers
|
- Other Identifiers
|
||||||
|
|
||||||
![Export vulnerabilities](img/instance_security_dashboard_export_csv_v13_4.png)
|
|
||||||
|
|
|
@ -422,6 +422,71 @@ for more details.
|
||||||
|
|
||||||
Here's [an example project](https://gitlab.com/jheimbuck_gl/jh_java_example_project) that uses Code Quality with a `.codeclimate.yml` file.
|
Here's [an example project](https://gitlab.com/jheimbuck_gl/jh_java_example_project) that uses Code Quality with a `.codeclimate.yml` file.
|
||||||
|
|
||||||
|
## Use a Code Quality image hosted in a registry with untrusted certificates
|
||||||
|
|
||||||
|
If you set the `CODE_QUALITY_IMAGE` to an image that is hosted in a
|
||||||
|
Docker registry which uses a TLS certificate that is not trusted, such as
|
||||||
|
a self-signed certificate, you will see errors like the one below:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ docker pull --quiet "$CODE_QUALITY_IMAGE"
|
||||||
|
Error response from daemon: Get https://gitlab.example.com/v2/: x509: certificate signed by unknown authority
|
||||||
|
```
|
||||||
|
|
||||||
|
To fix this, configure the Docker daemon to [trust certificates](https://docs.docker.com/registry/insecure/#use-self-signed-certificates)
|
||||||
|
by putting the certificate inside of the `/etc/docker/certs.d`
|
||||||
|
directory.
|
||||||
|
|
||||||
|
This Docker daemon is exposed to the subsequent Code Quality Docker container in the
|
||||||
|
[GitLab Code Quality](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.8.3-ee/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml#L41)
|
||||||
|
and should be to exposed any other containers in which you want to have
|
||||||
|
your certificate configuration apply.
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
If you have access to GitLab Runner configuration, add the directory as a
|
||||||
|
[volume mount](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#volumes-in-the-runnersdocker-section). For example:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[runners]]
|
||||||
|
...
|
||||||
|
executor = "docker"
|
||||||
|
[runners.docker]
|
||||||
|
...
|
||||||
|
privileged = true
|
||||||
|
volumes = ["/cache", "/etc/gitlab-runner/certs/gitlab.example.com.crt:/etc/docker/certs.d/gitlab.example.com/ca.crt:ro"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `gitlab.example.com` with the actual domain of the registry.
|
||||||
|
|
||||||
|
### Kubernetes
|
||||||
|
|
||||||
|
If you have access to GitLab Runner configuration and the Kubernetes cluster,
|
||||||
|
you can [mount a ConfigMap](https://docs.gitlab.com/runner/executors/kubernetes.html#configmap-volumes):
|
||||||
|
|
||||||
|
1. Create a ConfigMap with the certificate:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
kubectl create configmap registry-crt --namespace gitlab-runner --from-file /etc/gitlab-runner/certs/gitlab.example.com.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Update GitLab Runner `config.toml` to specify the ConfigMap:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[runners]]
|
||||||
|
...
|
||||||
|
executor = "kubernetes"
|
||||||
|
[runners.kubernetes]
|
||||||
|
image = "alpine:3.12"
|
||||||
|
privileged = true
|
||||||
|
[[runners.kubernetes.volumes.config_map]]
|
||||||
|
name = "registry-crt"
|
||||||
|
mount_path = "/etc/docker/certs.d/gitlab.example.com/ca.crt"
|
||||||
|
sub_path = "gitlab.example.com.crt"
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `gitlab.example.com` with the actual domain of the registry.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Changing the default configuration has no effect
|
### Changing the default configuration has no effect
|
||||||
|
|
|
@ -45,7 +45,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def custom_claims
|
def custom_claims
|
||||||
{
|
fields = {
|
||||||
namespace_id: namespace.id.to_s,
|
namespace_id: namespace.id.to_s,
|
||||||
namespace_path: namespace.full_path,
|
namespace_path: namespace.full_path,
|
||||||
project_id: project.id.to_s,
|
project_id: project.id.to_s,
|
||||||
|
@ -59,6 +59,15 @@ module Gitlab
|
||||||
ref_type: ref_type,
|
ref_type: ref_type,
|
||||||
ref_protected: build.protected.to_s
|
ref_protected: build.protected.to_s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if include_environment_claims?
|
||||||
|
fields.merge!(
|
||||||
|
environment: environment.name,
|
||||||
|
environment_protected: environment_protected?.to_s
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
fields
|
||||||
end
|
end
|
||||||
|
|
||||||
def key
|
def key
|
||||||
|
@ -102,6 +111,20 @@ module Gitlab
|
||||||
def ref_type
|
def ref_type
|
||||||
::Ci::BuildRunnerPresenter.new(build).ref_type
|
::Ci::BuildRunnerPresenter.new(build).ref_type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def environment
|
||||||
|
build.persisted_environment
|
||||||
|
end
|
||||||
|
|
||||||
|
def environment_protected?
|
||||||
|
false # Overridden in EE
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_environment_claims?
|
||||||
|
Feature.enabled?(:ci_jwt_include_environment) && environment.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Gitlab::Ci::Jwt.prepend_if_ee('::EE::Gitlab::Ci::Jwt')
|
||||||
|
|
|
@ -151,6 +151,8 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def gitaly_find_page(title:, version: nil, dir: nil)
|
def gitaly_find_page(title:, version: nil, dir: nil)
|
||||||
|
return unless title.present?
|
||||||
|
|
||||||
wiki_page, version = gitaly_wiki_client.find_page(title: title, version: version, dir: dir)
|
wiki_page, version = gitaly_wiki_client.find_page(title: title, version: version, dir: dir)
|
||||||
return unless wiki_page
|
return unless wiki_page
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ RSpec.describe Gitlab::Ci::Jwt do
|
||||||
expect(payload[:pipeline_id]).to eq(pipeline.id.to_s)
|
expect(payload[:pipeline_id]).to eq(pipeline.id.to_s)
|
||||||
expect(payload[:job_id]).to eq(build.id.to_s)
|
expect(payload[:job_id]).to eq(build.id.to_s)
|
||||||
expect(payload[:ref]).to eq(pipeline.source_ref)
|
expect(payload[:ref]).to eq(pipeline.source_ref)
|
||||||
|
expect(payload[:ref_protected]).to eq(build.protected.to_s)
|
||||||
|
expect(payload[:environment]).to be_nil
|
||||||
|
expect(payload[:environment_protected]).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,6 +93,39 @@ RSpec.describe Gitlab::Ci::Jwt do
|
||||||
expect(payload[:ref_protected]).to eq('true')
|
expect(payload[:ref_protected]).to eq('true')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'environment' do
|
||||||
|
let(:environment) { build_stubbed(:environment, project: project, name: 'production') }
|
||||||
|
let(:build) do
|
||||||
|
build_stubbed(
|
||||||
|
:ci_build,
|
||||||
|
project: project,
|
||||||
|
user: user,
|
||||||
|
pipeline: pipeline,
|
||||||
|
environment: environment.name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(build).to receive(:persisted_environment).and_return(environment)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has correct values for environment attributes' do
|
||||||
|
expect(payload[:environment]).to eq('production')
|
||||||
|
expect(payload[:environment_protected]).to eq('false')
|
||||||
|
end
|
||||||
|
|
||||||
|
context ':ci_jwt_include_environment feature flag is disabled' do
|
||||||
|
before do
|
||||||
|
stub_feature_flags(ci_jwt_include_environment: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not include environment attributes' do
|
||||||
|
expect(payload).not_to have_key(:environment)
|
||||||
|
expect(payload).not_to have_key(:environment_protected)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.for_build' do
|
describe '.for_build' do
|
||||||
|
|
|
@ -744,13 +744,19 @@ RSpec.describe Event do
|
||||||
|
|
||||||
describe '#wiki_page and #wiki_page?' do
|
describe '#wiki_page and #wiki_page?' do
|
||||||
context 'for a wiki page event' do
|
context 'for a wiki page event' do
|
||||||
let(:wiki_page) do
|
let(:wiki_page) { create(:wiki_page, project: project) }
|
||||||
create(:wiki_page, project: project)
|
|
||||||
end
|
|
||||||
|
|
||||||
subject(:event) { create(:wiki_page_event, project: project, wiki_page: wiki_page) }
|
subject(:event) { create(:wiki_page_event, project: project, wiki_page: wiki_page) }
|
||||||
|
|
||||||
it { is_expected.to have_attributes(wiki_page?: be_truthy, wiki_page: wiki_page) }
|
it { is_expected.to have_attributes(wiki_page?: be_truthy, wiki_page: wiki_page) }
|
||||||
|
|
||||||
|
context 'title is empty' do
|
||||||
|
before do
|
||||||
|
expect(event.target).to receive(:canonical_slug).and_return('')
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to have_attributes(wiki_page?: be_truthy, wiki_page: nil) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'for any other event' do
|
context 'for any other event' do
|
||||||
|
|