Lesson 3: Developer Security Workflows#
This lesson walks through the day-to-day security workflows a developer encounters in a project with GitLab DevSecOps enabled. Security findings, license issues, and compliance jobs all surface where the developer already works — in the merge request — instead of in a separate tool.
This lesson covers:
- Creating a merge request with vulnerable code
- Viewing security policy enforcement
- Viewing and taking action on detected vulnerabilities
- Tracing tainted data with code flow
- Viewing denied licenses
- Viewing injected compliance jobs
- Editing in the GitLab Web IDE with Duo
Creating a merge request with vulnerable code#
The imported project includes a branch called add-vulnerabilities that introduces several intentional security flaws. We will open a merge request from this branch to see how GitLab surfaces security findings to developers.
In your project, navigate to Code > Merge requests in the left sidebar
Click New merge request
Select add-vulnerabilities as the Source branch
Select main as the Target branch
Click Compare branches and continue
On the New merge request page, scroll down and click Create merge request
A pipeline starts. Wait for it to complete — security findings appear once the pipeline finishes.
Viewing security policy enforcement#
Once the pipeline completes, the merge request approval policies you created in Lesson 2 take effect.
Open the merge request you just created
Near the top, locate the Approval required section and expand it
You will see that the policies are enforcing approvals — the MR is blocked because vulnerabilities and non-MIT licenses were detected. Each policy is listed with its name and how many approvals are still required.
This is the value of merge request approval policies: even a developer with merge permissions cannot merge code that violates security policies without the required approvals. The gate lives in the MR itself, not in a separate review tool.
Viewing and taking action on detected vulnerabilities#
Now let’s examine the specific vulnerabilities the scanners found.
In the merge request, scroll to the Security scanning section and click Expand
Findings are grouped by scanner type (SAST, Container Scanning, Dependency Scanning, Secret Detection, etc.). Each entry shows the vulnerability name, severity, and file.
Click any vulnerability to open the detail popup. The popup includes the full description, severity, location, and identifiers (CVE, CWE).
Click Dismiss vulnerability. You will be prompted to choose a reason (Acceptable risk, False positive, Used in tests, etc.).
Dismissals are tracked and visible to the AppSec team. If this MR were merged, the dismissed finding would appear in the project’s vulnerability report with a Dismissed status, along with who dismissed it and why.
Click the same vulnerability again to reopen the popup
Click Create issue to create a confidential issue for the vulnerability
Confidential issues let developers and the security team collaborate on a fix without exposing exploitation details to anyone who shouldn’t see them.
- Use your browser’s back button to return to the merge request
Tracing tainted data with code flow#
Some of the findings on this branch come from GitLab Advanced SAST, which performs cross-file, cross-function dataflow analysis. For those findings GitLab shows a code flow — the exact path tainted data takes from a source (user input) to a sink (a vulnerable function call).
In the Security scanning widget, open a SAST finding tagged GitLab Advanced SAST (for example, the SQL injection in
routes/basketItems.ts)Click into the vulnerability detail and select the Code flow tab
Step through the trace. Each step shows the file, line number, and the code at that point — so you can see exactly how user-controlled data reaches the vulnerable function.
This is the difference between “you have an SQL injection somewhere” and “user input from req.body.id flows through parseInt() and into Basket.findOne({ where: raw \id = ${id}` })` at line 85.” The latter is fixable in a single session.
Viewing denied licenses#
GitLab’s dependency scanning also detects each dependency’s software license. The license policy we created in Lesson 2 flags any license that is not on our allowlist.
In the same merge request, scroll to the License Compliance section and click Expand
Review the detected licenses. Each dependency’s license is listed alongside its approval status — licenses outside the MIT allowlist are marked Denied.
License compliance matters for organizations whose software supply chain has legal or IP requirements. Copyleft licenses (GPL, AGPL) are the most common concern because they can force release of proprietary source code.
Viewing injected compliance jobs#
Finally, verify that the pipeline execution policy you created is injecting the compliance job.
From the merge request, click the pipeline icon (or navigate to Build > Pipelines and select this MR’s pipeline)
Find the
soc2_compliance_checkjob in theteststage and open itThe job log shows
SOC2 Compliance Check— this was injected from thesoc2.ymlfile in the custom pipelines project.
Because this job is injected via a pipeline execution policy, developers cannot remove or modify it in their project’s
.gitlab-ci.yml. Compliance checks always run, regardless of what developers change. Separation of duties in action.
Editing in the GitLab Web IDE with Duo#
You can fix any of these findings without leaving GitLab. Each vulnerability detail page has an Open in Web IDE action that jumps straight to the offending line.
From a vulnerability detail page, click Open in Web IDE
The Web IDE opens with the file and line pre-selected
Use GitLab Duo Code Suggestions to draft a fix in place. Type a comment describing the fix you want (e.g.
// fix: parameterize this query) and accept the suggested edit.Commit the change to the same branch. The pipeline re-runs and the finding either disappears (fixed) or shows as Resolved if it was the only finding of its kind.
This is the tightest possible loop: developer sees the finding in the MR, opens the IDE on the offending line, fixes it with AI assistance, and the MR re-validates — all in the same browser tab.
Now that we have walked through the security workflows developers encounter day-to-day, we can shift to the AppSec view: monitoring and managing security posture across the project.