Having recently completed a refinement of our CI/CD pipeline's security gating logic, I wanted to document the rationale and implementation specifics for a policy decision we adopted: to fail builds only on newly introduced critical severity flaws, as identified by Veracode Static Analysis. This approach represents a deliberate departure from a blanket policy of failing on all critical flaws, which we found created an unsustainable operational burden and hindered developer velocity without materially improving our security posture in the short term.
Our primary objective was to shift the focus from a potentially overwhelming backlog to preventing regression and enforcing progress. The historical critical flaws, many of which are in legacy modules with complex remediation paths, are being tracked and addressed via a separate, prioritized mitigation workflow outside the direct commit path. The pipeline gate is now exclusively concerned with *new* critical issues introduced by the current changeset.
The technical implementation required a custom script interfacing with the Veracode APIs, as the standard Jenkins plugin and other out-of-the-box integrations did not offer this granularity of comparison. The workflow logic is as follows:
* The script first executes a policy evaluation via the `veracode pipeline scan` command to obtain the overall status.
* Crucially, it then fetches the detailed findings list for the most recent scan (using the `GET /appsec/v1/applications/{app_id}/findings` API endpoint) and the baseline scan we have designated as our comparison point (in our case, the scan from the previous release candidate).
* It performs a differential analysis, filtering for findings that are:
* Severity: Critical
* Status: New (not present in the baseline scan) or Reopened
* CWE ID: We also exclude specific CWEs related to build-time dependencies that are managed through a separate SCA process.
* If any findings meet these criteria, the script returns a non-zero exit code, failing the build. The developer receives a console output listing the new critical flaws with their CWE IDs and module locations.
Key configuration and compliance considerations we had to address:
* **Baseline Management:** Defining and maintaining the correct baseline scan ID is essential. We automated this by tagging the scan of our last production release and having the script retrieve it programmatically.
* **Audit Trail:** All build failures, along with the differential analysis report, are logged to our centralized logging system. This creates an immutable record for compliance audits, demonstrating that the pipeline is actively enforcing a "no new criticals" policy.
* **False Positive Mitigation:** We integrated a check to honor any Veracode findings that have already been marked as "Mitigated" or "False Positive" in the Veracode platform, ensuring the pipeline respects the established triage workflow.
The initial results over the last three sprint cycles have been positive. Developer resistance to security gates has decreased, as the feedback is now directly relevant to their recent work. Simultaneously, our rate of new critical flaw introduction has dropped to near zero, while the dedicated application security team can systematically reduce the historical backlog without impeding current development. This structured, two-track approach has provided a more manageable path toward long-term compliance.