Skip to content
Notifications
Clear all

Anyone using Checkmarx in their CI pipeline? How was the setup?

5 Posts
5 Users
0 Reactions
28 Views
(@briana)
Reputable Member
Joined: 3 months ago
Posts: 319
Topic starter   [#18109]

Hey everyone! 👋 I've been knee-deep in SAST tools for the last few years, and my team recently went through a *lengthy* evaluation and rollout of Checkmarx into our CI/CD pipelines. We primarily work with a mix of Java microservices, some legacy .NET, and a sprinkle of Node.js, all hosted on Kubernetes. I wanted to share our setup journey, the good, the not-so-good, and some configuration snippets that might save you a few headaches.

Our main goal was to shift security left without grinding deployments to a halt. We run it on a dedicated runner in our GitLab setup. The initial setup was... let's call it *involved*. The documentation is comprehensive but can feel a bit labyrinthine. The key for us was getting the Checkmarx CLI (`cx`) configured correctly to run in a Docker container as part of our job.

Here's a stripped-down version of our `.gitlab-ci.yml` stage for the SAST scan:

```yaml
checkmarx-sast:
stage: test
image: checkmarx/scan-cli:latest
variables:
CX_SCAN_PRESET: "All"
CX_TEAM: "/MyDivision/MyTeam"
CX_PROJECT_NAME: "$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME"
CX_OSA_ENABLED: "false" # We handle dependencies separately
script:
- /bin/cx scan create --project-name "$CX_PROJECT_NAME" --scan-types "sast" --preset-name "$CX_SCAN_PRESET" --sast-filter "$SAST_FILTER" --force-scan -s . --branch "$CI_COMMIT_REF_NAME" --repo-url "$CI_REPOSITORY_URL"
artifacts:
reports:
sast: gl-sast-report.json
allow_failure: true # Critical finding will break via quality gate, not the job itself
```

**Pitfalls we hit & lessons learned:**

* **Project Creation & Naming:** Checkmarx creates projects automatically on first scan, which is great. But! The auto-naming can get messy. We learned to explicitly set `CX_PROJECT_NAME` to include the branch name to avoid collisions and keep the dashboard clean. Merging/cleaning up projects in the UI afterward is a manual chore.
* **Performance vs. Depth:** The default "All" preset was too slow for our CI. We created a custom preset focusing on High/Critical severity for our main languages (excluding some legacy rule sets) which cut scan time by ~60%. We run the full, deep scan nightly.
* **The Filter File (`sast-filters.xml`):** This is **crucial** to avoid noise. We exclude generated code, test directories, and third-party libs. Example snippet:
```xml

```
* **Results Integration:** Pushing results to the GitLab SAST report (as shown) is nice for visibility in MRs. However, for enforcement, we found it more reliable to use Checkmarx's own **Quality Gate** feature in the project settings. We fail the pipeline based on that status polled via a separate API call, not just the report upload.

Overall, it's running solidly now, but the ramp-up required significant tuning. The incremental scan feature is a lifesaver for speed on feature branches. I'm curious how others have handled the pipeline integration, especially around managing the state of projects and dealing with the accumulation of historical scan data in the UI. Have you hooked it into something like a centralized security dashboard, or are you relying on the native Checkmarx portal?

โ€”B


Backup first.


   
Quote
(@cloud_cost_breaker)
Honorable Member
Joined: 4 months ago
Posts: 591
 

That CLI in a container approach is solid for consistency. Did you run into any issues with scan duration on larger codebases? We had to implement some aggressive `.cxignore` rules for build artifacts and third-party libs to keep it under our pipeline timeout, especially on the .NET side.


Less spend, more headroom.


   
ReplyQuote
(@devops_contrarian_42)
Honorable Member
Joined: 6 months ago
Posts: 479
 

Yeah, the scan duration's a killer. We had the same timeout fights. Honestly, we ended up dropping the "scan everything on every commit" mandate for most non-prod branches. It was just untenable.

Instead of just `.cxignore` tweaks, we set up a pre-scan step that only triggers the full Checkmarx run if the diff contains files in certain high-risk paths (like `/src` or specific config directories). Cuts maybe 70% of the scans. The tool isn't built for speed, so you have to work around it.


Keep it simple


   
ReplyQuote
(@infra_skeptic_9)
Prominent Member
Joined: 7 months ago
Posts: 602
 

That "scan only changed files in high-risk paths" trick is clever, but it makes me nervous as a default policy. You're essentially betting your security posture on the assumption that vulnerabilities only get introduced via new commits to those directories. What about that dormant SQLi in a legacy utility script that hasn't been touched in years, sitting outside `/src`? A dependency update in a lockfile you ignore could pull in a CVE.

You've traded one risk (slow pipelines) for another (undetected vulnerabilities in code considered "low-risk"). Feels like the tool is forcing you into a corner where you have to choose between security and velocity, which is the exact opposite of shifting left.


Your k8s cluster is 40% idle.


   
ReplyQuote
(@cost_optimizer_elle)
Reputable Member
Joined: 4 months ago
Posts: 370
 

Using a dedicated runner is smart, but that's where the cost surprise usually hits. GitLab's compute minutes can burn fast with a slow tool like Checkmarx, especially if you're scanning every branch. A static, always-on runner can be cheaper than the per-minute model if your scans are long and frequent.

Did you get pushback from finance on the pipeline runtime increase? I've seen teams get a security win only to get smacked with a 40% spike in CI/CD costs the next month. 🧾 Sometimes you have to shift the budget left too.

Also, `CX_OSA_ENABLED: "false"` - good call. Their open source analysis is... expensive for what it does. Most SCA tools are cheaper and better.


- elle


   
ReplyQuote