doc/user/application_security/container_scanning/multi_container_scanning.md
{{< details >}}
{{< /details >}}
{{< history >}}
{{< /history >}}
Use multi-container scanning to scan multiple container images in a single pipeline. This feature enables you to:
Multi-container scanning uses dynamic child pipelines to run scans concurrently, reducing overall pipeline execution time.
Multi-container scanning supports:
Prerequisites:
.gitlab-multi-image.yml configuration file in your repository root.To turn on multi-container scanning:
Create a .gitlab-multi-image.yml file in your repository root:
scanTargets:
- name: alpine
tag: latest
- name: python
tag: 3.9-slim
Include the template in your .gitlab-ci.yml:
include:
- template: Jobs/Multi-Container-Scanning.latest.gitlab-ci.yml
Commit and push your changes. The pipeline runs the scans automatically.
Configure multi-container scanning by editing the .gitlab-multi-image.yml file.
scanTargets:
- name: alpine
tag: "3.19"
- name: ubuntu
tag: "22.04"
# Include license information in reports
includeLicenses: true
# Configure registry authentication
auths:
registry.example.com:
username: ${REGISTRY_USER}
password: ${REGISTRY_PASSWORD}
# Allow insecure connections (not recommended for production)
allowInsecure: false
# Additional CA certificates for custom registries
additionalCaCertificateBundle: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
# Images to scan
scanTargets:
- name: registry.example.com/myapp
tag: "v1.2.3"
- name: postgres
tag: "15-alpine"
[!note] You cannot specify runner tags for child jobs in multi-container scanning but issue 363687 proposes to change this behavior.
| Option | Type | Required | Description |
|---|---|---|---|
scanTargets | Array | Yes | List of container images to scan |
scanTargets[].name | String | Yes | Image name (with optional registry) |
scanTargets[].tag | String | No | Image tag (default: latest) |
scanTargets[].registry | String | No | Registry override |
includeLicenses | Boolean | No | Include license information in reports |
auths | Object | No | Registry authentication credentials |
allowInsecure | Boolean | No | Allow insecure HTTPS connections |
additionalCaCertificateBundle | String | No | Additional CA certificates in PEM format |
The following sections describe some example scenarios that you can adapt to suit your needs.
scanTargets:
- name: docker.io/library/nginx
tag: "1.25"
- name: registry.gitlab.com/mygroup/myapp
tag: "main"
- name: gcr.io/myproject/service
tag: "prod"
auths:
registry.gitlab.com:
username: ${CI_REGISTRY_USER}
password: ${CI_REGISTRY_PASSWORD}
docker.io:
username: ${DOCKERHUB_USER}
password: ${DOCKERHUB_TOKEN}
scanTargets:
- name: registry.gitlab.com/private/image
tag: latest
scanTargets:
- name: postgres
tag: "14.10"
- name: redis
tag: "7.2.3"
- name: nginx
tag: "1.25.3"
You can customize multi-container scanning behavior by using CI/CD variables.
| Variable | Default | Description |
|---|---|---|
CONTAINER_SCANNING_DISABLED | - | Set to true or 1 to disable scanning |
AST_ENABLE_MR_PIPELINES | true | Enable scanning in merge request pipelines |
CS_SCANNER_IMAGE | registry.gitlab.com/.../multiple-container-scanner:0 | Scanner image to use |
To disable scanning temporarily:
variables:
CONTAINER_SCANNING_DISABLED: "true"
variables:
AST_ENABLE_MR_PIPELINES: "false"
Prerequisites:
To view scan results:
Each scanned image generates:
includeLicenses: true).Multi-container scanning creates two jobs:
multi-cs::generate-scan: Generates the scanning configurationmulti-cs::trigger-scan: Triggers a child pipeline with parallel scan jobsThe child pipeline contains one job per image in scanTargets.
When working with multi-container scanning, you might encounter the following issues.
Cause: The .gitlab-multi-image.yml file is missing or in the wrong location.
Solution: Ensure .gitlab-multi-image.yml exists in your repository root.
Cause: Invalid credentials or missing authentication configuration.
Solution:
Verify that credentials are correct and configured correctly.
auths:
registry.example.com:
username: ${REGISTRY_USER}
password: ${REGISTRY_PASSWORD}
Define variables in Settings > **CI/CD > Variables.
Cause: Multiple large images being scanned sequentially.
Solution: Multi-container scanning already runs scans in parallel.
Consider:
Cause: Missing strategy: mirror in trigger configuration.
Solution: This is configured by default in the template. If you've customized
the template, ensure the trigger job includes strategy: mirror.
You might find that child pipeline jobs run on a runner that you did not expect.
This issue occurs because child pipeline jobs do not inherit the parent job's runner tags. Issue 363687 proposes to change this behavior.