CI/CD

API security scanning in CI/CD

Embed static checks, policy gates, and fast feedback in every pipeline run.

Published: February 3, 2026 • Author: APISAST

Published: 3 February 2026 · Updated: 19 September 2026

Why shift-left pipelines win

Contract checks can flag missing security requirements and weak error responses while a pull request is still easy to change. Put the current OpenAPI file in CI and review each finding alongside implementation tests.

Submit the file to the APISAST analysis API from a CI job, then decide which findings should fail the build. The API security SAST tools guide explains the contract checks and their limits.

Example GitHub Actions workflow

name: api-security
on: [pull_request]
jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Analyse OpenAPI contract
        env:
          APISAST_API_URL: https://your-apisast-api.example
        run: |
          curl --fail-with-body -sS \
            -F "[email protected]" \
            "$APISAST_API_URL/api/v1/analyse" \
            | jq -e '.counts.errors == 0'

Replace the example URL with your APISAST backend URL. This sample fails when the response contains error-severity findings; choose a policy that fits your team. Keep runtime tests alongside contract checks.

Policy gates and exceptions

Treat policies as code. Store rule sets in the repo, require approvals for overrides, and auto-expire exceptions after a sprint. This keeps security posture transparent and auditable.

For sensitive services, add a deploy-blocking stage that reruns SAST testing for APIs on the exact artifact that will ship.

Prepare the file and pipeline boundary

Keep the OpenAPI file under version control so a pull request shows both the implementation and the contract change. If the file is generated, generate it before scanning and compare the result with the committed version to catch drift. Validate that the pipeline is sending the intended artifact; a scan of last week's spec can pass while today's route is exposed. Never put real credentials in examples, and review whether the specification itself may contain sensitive internal URLs before sending it to a hosted service.

The example calls the backend's /api/v1/analyse endpoint with multipart form data. Set the backend URL from a trusted CI variable and use an environment with the access controls your organisation requires. The API stores the uploaded specification and report so they can be reopened. Treat that storage behaviour as part of the decision to use a hosted or self-managed deployment.

Choose a gate that developers can understand

A simple first gate fails when the analysis response contains any error-severity findings. Review the rule catalogue and a representative set of existing specs before making that mandatory; otherwise legacy issues can block unrelated changes. One rollout pattern is to record the current baseline, report new findings on pull requests, and require owners to fix or explicitly accept a newly introduced error. Keep exceptions time-bound and linked to an issue that explains the compensating control.

A failed request to the analysis API is different from a clean scan. Make transport errors, malformed responses, and a missing specification fail visibly; do not interpret an empty response as zero findings. Keep the report ID and the relevant rule IDs in CI output, but do not print the full uploaded contract if it contains internal information. Give a developer a direct way to reproduce a finding locally or in a safe test environment.

Pair contract findings with implementation tests

A documented bearer scheme does not prove that an endpoint rejects anonymous requests. Keep authentication, authorization, and error response tests in the same pipeline. For a collection endpoint, scan for pagination declarations and separately test the live page-size bound. For an operation that documents a 429, test the gateway's real rate-limit behaviour in a controlled environment. This gives reviewers two kinds of evidence: intended design and observed implementation.

Run static checks on pull requests because they are deterministic and need no live API. Schedule dynamic tests where stable fixtures and tokens are available. Retest the exact release artifact when generated contracts or gateway configuration can differ between branches. The testing methods guide explains how to choose each layer.

Monitoring and feedback

Publish dashboards showing pass rates, mean time to remediate, and most-flaky rules. Notify teams in chat when a new issue is introduced. Keep logs searchable so auditors can trace who approved a waiver.

When runtime tools detect abuse (e.g., bot spikes), open an issue that links back to the spec and static findings so developers can patch both contract and code.

Review the trend in newly introduced error-severity findings, not only total findings across a growing API estate. A higher total can mean the scanner now covers more services. Track which team owns each issue, how long it remains open, and whether the intended contract fix was followed by a runtime test. This gives the pipeline a feedback loop without pretending that a passing static scan measures all production risk.

Back to blog