doc/user/application_security/sast/gitlab_advanced_sast.md
{{< details >}}
{{< /details >}}
{{< history >}}
{{< /history >}}
GitLab Advanced SAST is a static application security testing (SAST) analyzer that uses cross-function and cross-file taint analysis to detect complex vulnerabilities with fewer false positives than traditional SAST.
GitLab Advanced SAST is an opt-in feature. When enabled, GitLab Advanced SAST scans all supported language files using its predefined ruleset, while the SAST analyzer continues to scan other files. Both analyzers can run in parallel. SAST and GitLab Advanced SAST do not have complete parity — each analyzer detects some vulnerabilities the other does not. An automated transition process deduplicates findings when both analyzers detect the same vulnerability.
GitLab Advanced SAST performs deeper analysis than the standard Semgrep-based SAST analyzer. This comprehensive approach can improve accuracy and reduce false positives, but requires more computational resources and longer scan duration.
<i class="fa-youtube-play" aria-hidden="true"></i> For an overview, see GitLab Advanced SAST: Accelerating Vulnerability Resolution.
<!-- Video published on 2025-09-19 -->For a product tour, see the GitLab Advanced SAST product tour.
| Feature | SAST | Advanced SAST |
|---|---|---|
| Depth of Analysis | Limited ability to detect complex vulnerabilities; analysis is limited to a single file, and (with limited exceptions) a single function. | Detects complex vulnerabilities using cross-file, cross-function taint analysis. |
| Accuracy | More likely to create false-positive results due to limited context. | Creates fewer false-positive results by using cross-file, cross-function taint analysis to focus on truly exploitable vulnerabilities. |
| Remediation Guidance | Vulnerability findings are identified by line number. | Detailed code flow view shows how the vulnerability flows through the program, allowing for faster remediation. |
| Works with GitLab Duo Vulnerability Explanation and Vulnerability Resolution | Yes. | Yes. |
| Language coverage | More expansive. | More limited. |
Follow these steps to turn on GitLab Advanced SAST in your project.
Prerequisites:
Turn on GitLab Advanced SAST:
In the top bar, select Search or go to and find your project.
Go to Build > Pipeline editor.
Create or edit your .gitlab-ci.yml file.
Add the appropriate variable to enable Advanced SAST:
For all supported languages except C/C++:
GITLAB_ADVANCED_SAST_ENABLED: 'true'
For C/C++:
GITLAB_ADVANCED_SAST_CPP_ENABLED: 'true'
Select the Validate tab, then select Validate pipeline.
The message Simulation completed successfully confirms the file is valid.
Select the Edit tab.
Complete the fields.
Select the Start a new merge request with these changes checkbox, then select Commit changes.
Complete the fields according to your standard workflow, then select Create merge request.
Review and edit the merge request according to your standard workflow, then select Merge.
At this point, GitLab Advanced SAST is enabled in your pipeline. Supported source code is scanned
for vulnerabilities when a pipeline runs. The corresponding job appears in the test stage in your
pipeline.
After completing these steps, you can:
GitLab Advanced SAST vulnerabilities include detailed information to help you assess and remediate security issues. Each vulnerability shows:
SAST vulnerabilities are named according to the primary Common Weakness Enumeration (CWE) identifier for the discovered vulnerability. For more information on SAST coverage, see SAST rules.
Prerequisites:
To view vulnerabilities in your pipeline:
{{< history >}}
{{< /history >}}
For specific types of vulnerabilities, GitLab Advanced SAST provides code flow information. A vulnerability's code flow is the path the data takes from the user input (source) to the vulnerable line of code (sink), through all assignments, manipulation, and sanitization. This information helps you understand and evaluate the vulnerability's context, impact, and risk. Code flow information is available for vulnerabilities that are detected by tracing input from a source to a sink, including:
The code flow information is shown the Code flow tab and includes:
{{< history >}}
{{< /history >}}
GitLab Advanced SAST supports the following languages:
GitLab Advanced SAST CPP requires additional configuration, including a compilation database. For details, see C/C++ configuration. GitLab Advanced SAST CPP and Semgrep both run for C/C++ projects, each with different rule sets.
When analyzing PHP code, GitLab Advanced SAST has the following known issues:
include, include_once, require,
require_once) using variables for file paths are not supported in this release. Only static file
inclusion paths are supported for cross-file analysis. See
issue 527341.GitLab Advanced SAST scanning performance is determined primarily by code coverage and runner resources. To improve GitLab Advanced SAST scan performance, you can tune code coverage and runner resources.
Code coverage refers to how much of your codebase is analyzed. GitLab Advanced SAST scans all supported language files by using its predefined ruleset. The Semgrep-based SAST analyzer does not scan these files. An automated transition process removes duplicate findings when both analyzers detect the same vulnerability.
You can optionally report unverified vulnerabilities, where the full path from source to sink is not identified.
By default, GitLab Advanced SAST scans the entire repository. You can tune code coverage by using the following methods:
Diff-based scanning and incremental scanning can be used independently or together to improve scan performance.
Diff-based scanning : Scans only changed files and their dependents in merge request associated pipelines (merge request pipelines or branch pipelines associated with a merge request), trading full coverage for speed.
Incremental scanning : Caches prior scan results and reuses them in subsequent pipelines, reducing scan duration while maintaining full file coverage. Available in all pipelines.
| Configuration | Merge request associated pipelines | All other pipelines |
|---|---|---|
| No optimization | Standard. Scans all files, no cache. | Standard. Scans all files, no cache. |
| Incremental scanning only | Fast. Scans all files with cache. | Fast. Scans all files with cache. |
| Diff-based scanning only | Faster. Scans only changed files, no cache. | Standard. Scans all files, no cache. |
| Diff-based + incremental scanning | Fastest. Scans only changed files with cache. | Fast. Scans all files with cache. |
To reduce scan duration, exclude from GitLab Advanced SAST scanning any paths that are unlikely to contain vulnerabilities.
When excluding paths, be selective to avoid hiding vulnerabilities. Make changes incrementally and test the effect on scan duration after each exclusion.
Consider excluding paths containing the following:
node_modules/Prerequisites:
To exclude paths:
SAST_EXCLUDED_PATHS CI/CD
variable.{{< history >}}
vulnerability_partial_scans. Disabled by default.vulnerability_partial_scans removed.{{< /history >}}
Diff-based scanning analyzes only the files modified in a merge request, along with their dependent files. This targeted approach reduces scan duration, resulting in faster feedback during development.
To ensure complete coverage, a full scan runs on the default branch after the merge request is merged.
Diff-based scanning is supported in both merge request pipelines and branch pipelines, under the following conditions:
When diff-based scanning is active:
Running differential scan. (If inactive, it outputs: Running full scan.)Diff-based scanning has the following known issues:
Prerequisites:
To turn on diff-based scanning in merge request pipelines:
ADVANCED_SAST_PARTIAL_SCAN CI/CD variable to differential in the project's
.gitlab-ci.yml file.To avoid missing cross-file vulnerabilities beyond the modified files, diff-based scanning includes their immediate dependents. This reduces false negatives while maintaining fast scans, though it may produce imprecise results in deeper dependency chains.
The following files are included in the scan:
This design helps detect cross-file data flows, such as tainted data moving from a modified function to a caller that imports it.
Files imported by modified files are not scanned because they typically do not impact the behavior or data flow of the modified code.
For example, consider a merge request that modifies file B:
{{< history >}}
{{< /history >}}
Incremental scanning caches taint signature analysis results between pipeline runs. On subsequent scans, unchanged code reuses cached signatures instead of being reanalyzed, while changed or new code is fully analyzed. This reduces scan times on large codebases where most files don't change between commits.
Incremental scanning works like this:
ts-cache.sqlite.gz).The cache is invalidated to ensure accuracy while maximizing reuse:
Partial invalidation: only affected entries are recomputed, the rest of the cache is reused:
Full invalidation: the entire cache is rebuilt:
To turn on incremental scanning:
Set the GITLAB_ADV_SAST_INCR_SCAN CI/CD variable to true in the project's
.gitlab-ci.yml file:
gitlab-advanced-sast:
variables:
GITLAB_ADV_SAST_INCR_SCAN: "true"
The SAST CI/CD template stores the cache artifact with a default expiry of 3 days. The
GITLAB_ADV_SAST_INCR_SCAN_SEARCH_PERIOD variable controls how far back the analyzer searches for a
cache artifact (default: 3 days).
These two values should be aligned. The search period should not exceed the artifact expiry, or the analyzer may search for artifacts that have already expired.
To customize both values, override the artifacts:expire_in and set the search period variable:
gitlab-advanced-sast:
variables:
GITLAB_ADV_SAST_INCR_SCAN: "true"
GITLAB_ADV_SAST_INCR_SCAN_SEARCH_PERIOD: "7 days"
artifacts:
paths:
- gl-sast-report.json
- ts-cache.sqlite.gz
expire_in: 7 days
The search period supports a number followed by d, day, or days (for example, 7 days,
14d).
The analyzer uses the CI/CD job name to identify which job's artifacts contain the cache. If you rename
the gitlab-advanced-sast job, set GITLAB_ADV_SAST_INCR_SCAN_CUSTOM_JOB_NAME to the custom name
so the cache lookup finds the correct job:
my-custom-sast-job:
variables:
GITLAB_ADV_SAST_INCR_SCAN: "true"
GITLAB_ADV_SAST_INCR_SCAN_CUSTOM_JOB_NAME: "my-custom-sast-job"
The cache is stored as a compressed CI/CD artifact. Artifact size limits apply:
As an alternative to CI/CD artifact storage, you can store the incremental scanning cache in external object storage. Use this storage method when artifact storage limits are a constraint or when you want to manage cache lifecycle independently. AWS S3 is supported.
Authentication uses OpenID Connect (OIDC) to exchange short-lived tokens with your cloud provider. You do not need to store long-lived credentials as CI/CD variables.
Prerequisites:
s3:GetObjects3:PutObjects3:HeadObjectproject_path:myorg/* for all projects in a group).To store the cache in S3:
Add this configuration to your .gitlab-ci.yml:
gitlab-advanced-sast:
id_tokens:
GITLAB_ADV_SAST_INCR_SCAN_OIDC_TOKEN:
aud: https://gitlab.com
variables:
GITLAB_ADV_SAST_INCR_SCAN: "true"
GITLAB_ADV_SAST_INCR_SCAN_STORAGE: "s3"
GITLAB_ADV_SAST_INCR_SCAN_S3_BUCKET: "advanced-sast-cache"
GITLAB_ADV_SAST_INCR_SCAN_S3_REGION: "us-east-1"
GITLAB_ADV_SAST_INCR_SCAN_S3_ROLE_ARN: "arn:aws:iam::<account-id>:role/<role-name>"
For GitLab Self-Managed or GitLab Dedicated, replace aud: https://gitlab.com with your GitLab instance URL.
Configure an S3 lifecycle policy to auto-expire cache objects.
The expiry should be aligned with the GITLAB_ADV_SAST_INCR_SCAN_SEARCH_PERIOD value (default: 3 days) to avoid
retaining stale cache files.
The cache is stored in S3 at <project-path>/<commit-sha>/ts-cache.sqlite.gz.
The analyzer searches parent commits for the most recent cache, matching
artifact-based caching behavior.
{{< details >}}
{{< /details >}}
{{< history >}}
{{< /history >}}
GitLab Advanced SAST uses taint analysis to trace data flows from untrusted sources to vulnerable sinks. By default, the analyzer only reports a vulnerability when it can trace a complete path, which prioritizes accuracy over coverage. To detect more potential data flows, you can enable unverified vulnerabilities. This feature reports findings even when a complete data flow path cannot be established, which increases coverage but may also increase the number of false positives.
When you enable unverified vulnerability reporting, the analyzer also reports findings where a partial taint flow was detected but could not be fully verified from source to sink. These near-miss findings help you identify and proactively fix risky code before it becomes exploitable. Unverified findings are only reported for rules with a security severity of Medium or higher.
Unverified findings are clearly distinguished from fully verified vulnerabilities in the following ways:
To include unverified findings in scan results, set the REPORT_UNVERIFIED_VULNS CI/CD variable
to a truthy value in your .gitlab-ci.yml file:
gitlab-advanced-sast:
variables:
REPORT_UNVERIFIED_VULNS: "true"
[!warning] Enabling unverified vulnerability reporting can significantly increase the number of findings generated by the analyzer. These findings are stored in the vulnerability database and may impact vulnerability management workflows, including triage effort and reporting.
Runner resources directly impact scan duration. GitLab Advanced SAST runs checks in parallel by default, which requires multiple CPU cores and a minimum of 4 GB memory per core. Runner resources are detected automatically, but you can tune some settings if needed.
The analyzer determines available CPU and memory according to the following priority:
CI_RUNNER_TAGS):
saas-linux-large-amd64) and looks up the known CPU and memory values for that runner type./sys/fs/cgroup/cpu.max, /sys/fs/cgroup/memory.max):
ADVANCED_SAST_AVAILABLE_CPUS, ADVANCED_SAST_AVAILABLE_MEMORY):
If detection fails at steps 1 and 2, the analyzer defaults to 1 core and 4 GB of memory.
To confirm the CPU and memory allocation, view the gitlab-advanced-sast job log and look for the
GitLab Advanced SAST entries. For example:
[INFO] [GitLab Advanced SAST] [2026-03-30T02:38:09Z] ▶ Detected 2 CPU Cores
[INFO] [GitLab Advanced SAST] [2026-03-30T02:38:09Z] ▶ No Memory limit is detected
You can manually tune the analyzer's CPU and memory settings by using CI/CD variables when:
Use the following CI/CD settings to tune GitLab Advanced SAST runner resources:
ADVANCED_SAST_AVAILABLE_CPUS - Specify CPU cores available to the analyzerADVANCED_SAST_AVAILABLE_MEMORY - Specify total memory available to the analyzerMAX_UNVERIFIED_CORES - Set an upper bound for automatic core detectionDISABLE_MULTI_CORE - Disable multi-core scanning entirelyFor self-managed runners, you can use the --multi-core flag in the
security scanner configuration to specify the number of
requested cores.
For more details, see configuration.
To find the optimal configuration for your project, change only one setting at a time and monitor the scan duration.
In the following example, 4 CPU cores and 16 GB of memory are available to the GitLab Advanced SAST analyzer. Each of the 4 workers has 4 GB of memory available.
include:
- template: Jobs/SAST.gitlab-ci.yml
variables:
GITLAB_ADVANCED_SAST_ENABLED: 'true'
ADVANCED_SAST_AVAILABLE_CPUS: '4'
ADVANCED_SAST_AVAILABLE_MEMORY: '16384' # 16 GB for 4 cores
You can adjust GitLab Advanced SAST behavior using the following variables:
| CI/CD variable | Default | Description |
|---|---|---|
GITLAB_ADVANCED_SAST_ENABLED | false | Enable GitLab Advanced SAST scanning for all supported languages except C and C++. |
GITLAB_ADVANCED_SAST_CPP_ENABLED | false | Enable GitLab Advanced SAST scanning specifically for C and C++ projects. |
ADVANCED_SAST_PARTIAL_SCAN | false | Enable GitLab Advanced SAST diff-scanning mode by setting to differential. |
GITLAB_ADVANCED_SAST_RULE_TIMEOUT | 30 | Timeout in seconds per rule per file. When exceeded, that analysis is skipped. |
REPORT_UNVERIFIED_VULNS | false | Include unverified findings in scan results. Set to true, 1, or True to enable. |
GITLAB_ADV_SAST_INCR_SCAN | false | Enable incremental scanning to cache taint signatures between pipeline runs. |
GITLAB_ADV_SAST_INCR_SCAN_SEARCH_PERIOD | 3 days | How far back to search for a cached taint signature artifact. Supported format: number followed by d, day, or days (for example, 7 days). Should not exceed the artifact expiry period. |
GITLAB_ADV_SAST_INCR_SCAN_CUSTOM_JOB_NAME | gitlab-advanced-sast | Custom job name for cache artifact lookup. Set this if you renamed the gitlab-advanced-sast job. |
GITLAB_ADV_SAST_INCR_SCAN_STORAGE | Not set | Cache storage backend. Set to s3 to store the cache in AWS S3 instead of CI/CD artifacts. For details, see store cache in external object storage. |
GITLAB_ADV_SAST_INCR_SCAN_S3_BUCKET | Not set | S3 bucket name for cache storage. Required when GITLAB_ADV_SAST_INCR_SCAN_STORAGE is s3. |
GITLAB_ADV_SAST_INCR_SCAN_S3_REGION | Not set | AWS region of the S3 bucket. Required when GITLAB_ADV_SAST_INCR_SCAN_STORAGE is s3. |
GITLAB_ADV_SAST_INCR_SCAN_S3_ROLE_ARN | Not set | ARN of the IAM role to assume through OIDC. Required when GITLAB_ADV_SAST_INCR_SCAN_STORAGE is s3. |
GitLab Advanced SAST scanning is disabled by default. To explicitly disable it when enabled at a
higher level (for example, for a group), set GITLAB_ADVANCED_SAST_ENABLED (or
GITLAB_ADVANCED_SAST_CPP_ENABLED for C/C++ projects) to false.
After you are confident in GitLab Advanced SAST results for one project, extend it to additional projects and groups. You should create a shared CI/CD configuration that includes GitLab Advanced SAST and enforce it across the desired groups and projects.
For more details, see Security configuration.
GitLab Advanced SAST uses cross-file, cross-function scanning with taint analysis to trace the flow of user input into the program. This ensures that injection vulnerabilities, such as SQL injection and cross-site scripting (XSS), are detected even when they span multiple functions and files.
The analyzer only reports taint-based vulnerabilities when there is a verifiable flow that brings untrusted user input from a source to a point where untrusted data could cause security vulnerabilities. This approach minimizes noise compared to other products that may report vulnerabilities with less validation.
Detection emphasizes input that crosses trust boundaries, like values sourced from HTTP requests, but excludes command-line arguments, environment variables, or other inputs typically provided by the user operating the program.
For details of which types of vulnerabilities GitLab Advanced SAST detects, see GitLab Advanced SAST CWE coverage.
When you migrate from Semgrep to GitLab Advanced SAST, an automated transition process deduplicates vulnerabilities. This process links previously detected Semgrep vulnerabilities with corresponding GitLab Advanced SAST findings, replacing them when a match is found.
After enabling Advanced SAST scanning in the default branch when a scan runs and detects vulnerabilities, it checks whether any of them should replace existing Semgrep vulnerabilities based on the following conditions.
Matching Identifier:
bandit.B506 and a Semgrep vulnerability's primary identifier is also bandit.B506, this condition is met.Matching Location:
When the conditions are met, the existing Semgrep vulnerability is converted into a GitLab Advanced SAST vulnerability. This updated vulnerability appears in the Vulnerability Report with the following changes:
When the conditions are not met, the existing Semgrep vulnerabilities persist in the vulnerability dashboard even if the underlying code issues have been fixed. To mark these fixed vulnerabilities as resolved in GitLab, you must either manually resolve them in the vulnerability dashboard, or run the Semgrep analyzer again.
In some cases, Semgrep vulnerabilities may still appear as duplicates if the deduplication conditions are not met. To resolve this in the Vulnerability Report:
To request information about the source code of LGPL-licensed components in GitLab Advanced SAST, contact GitLab Support.
To ensure a quick response, include the GitLab Advanced SAST analyzer version in your request.
Because this feature is only available at the Ultimate tier, you must be associated with an organization with that level of support entitlement.