Home Technical Support Integrating Software Component Analysis (SCA) and OAST into Your CI/CD Build Pipeline

Integrating Software Component Analysis (SCA) and OAST into Your CI/CD Build Pipeline

Last updated on Jan 06, 2026

Integrating Software Component Analysis (SCA) and OAST into Your CI/CD Build Pipeline


Introduction

Securing modern applications requires more than a single scan or a one‑time review. Both Software Component Analysis (SCA) and Open Application Security Testing (OAST) play complementary roles in identifying vulnerabilities early and continuously. This article explains how SCA and OAST fit together, how they map to typical CI/CD jobs (build, test, and oast‑frontend), and when you should run security tools directly on the host versus inside a Docker container. By the end, you’ll have a clear, step‑by‑step guide you can copy into your own pipeline configuration.


1. Understanding the Relationship Between SCA and OAST

Aspect Software Component Analysis (SCA) Open Application Security Testing (OAST)
Primary focus Identifies known vulnerabilities, license issues, and outdated versions in third‑party libraries and packages. Actively probes the running application (or its source) for security weaknesses such as XSS, SQLi, insecure configurations, and API exposure.
Typical output Bill of Materials (BOM), CVE list, severity scores, remediation recommendations. Vulnerability findings tied to code paths, request/response traces, and remediation guidance.
When it runs Usually before the application is packaged—during dependency resolution or after the build step. Typically after the application is built and optionally after functional tests, when a testable artifact exists.
Tool examples  Retire.js, OWASP Dependency‑Check, Snyk, Black Duck.  OWASP ZAP, Burp Suite, Nikto, Arachni.

Key takeaway: SCA secures the ingredients of your software, while OAST secures the final dish. Running both in the same pipeline gives you a holistic view of risk—first you know what you’re shipping, then you verify how it behaves under attack.


2. How the Build, Test, and oast‑frontend Jobs Work Together

A typical CI/CD pipeline for a web application might look like this:

stage: build   →   stage: test   →   stage: oast-frontend

2.1 Build Stage

  • Goal: Compile source code, resolve dependencies, and produce an artifact (e.g., a Docker image, JAR, or static bundle).
  • Typical commands: npm install, npm run build, mvn package.
  • Why it matters for security: The exact versions of third‑party packages are locked in, which SCA tools later analyze.

2.2 Test Stage

  • Goal: Run unit, integration, and functional tests to verify business logic.
  • Typical commands: npm test, pytest, go test.
  • Security relevance: A clean test run ensures that any later security findings are not caused by broken functionality.

2.3 oast‑frontend Stage

  • Goal: Perform an OAST scan that concentrates on the frontend (JavaScript, CSS, HTML) and on the third‑party dependencies used by the UI.
  • Typical tool: retire.js – an SCA scanner that focuses on known vulnerable JavaScript libraries.
  • What happens:
    1. The job pulls the built artifact (or the source directory).
    2. It runs retire.js against the node_modules folder.
    3. Results are saved as a JSON report (retirejs-report.json).

By placing oast‑frontend after the test stage, you guarantee that the code you are scanning is the exact version that passed functional verification.


3. Running Security Tools: Docker Container vs. Local CLI

You have two common ways to invoke a tool like retire.js in a GitLab CI job:

3.1 Option 1 – Use a pre‑installed image (e.g., node:alpine) and run the CLI directly

oast-frontend:
  stage: test
  image: node:alpine3.10          # Node + npm are already available
  script:
    - npm install                 # Install project dependencies
    - npm install -g retire       # Install retire.js globally
    - retire --outputformat json \
              --outputpath retirejs-report.json \
              --severity high

When to choose this:

  • You need access to the host file system (e.g., node_modules created by the previous build step).
  • You want to avoid extra Docker‑in‑Docker complexity.
  • Your CI runner already provides the required runtime (Node, Python, etc.).

3.2 Option 2 – Pull a dedicated security image and run it as a container

oast-frontend:
  stage: test
  script:
    - docker pull secfigo/retirejs
    - docker run -v $(pwd):/src secfigo/retirejs \
        retire --outputformat json \
               --outputpath retirejs-report.json \
               --severity high

When to choose this:

  • You want isolation – the scanning tool runs in its own environment, eliminating version conflicts.
  • You prefer a single‑purpose image that already contains the tool and its dependencies.
  • Your pipeline enforces “no‑install‑on‑host” policies for security or compliance reasons.

3.3 Decision Guidance

Consideration Prefer Image + CLI (node:alpine) Prefer Dedicated Docker (secfigo/retirejs)
Speed Faster (no extra pull) Slightly slower (pull + container start)
Isolation Lower (shares runner’s filesystem) Higher (clean environment)
Dependency conflicts Possible if runner’s Node version differs None – image is self‑contained
CI/CD simplicity Simpler script, fewer commands More explicit, easier to swap tools later

Best practice: Start with the lightweight node:alpine approach for quick prototyping. When you move to production‑grade pipelines, switch to the dedicated Docker image to guarantee reproducibility and compliance.


4. Practical Example: Full GitLab CI Configuration

stages:
  - build
  - test
  - oast-frontend

# ---------- Build ----------
build-app:
  stage: build
  image: node:alpine3.10
  script:
    - npm ci               # Clean install, generates node_modules
    - npm run build        # Produce dist/ folder
  artifacts:
    paths:
      - node_modules/
      - dist/
    expire_in: 1 hour

# ---------- Test ----------
unit-test:
  stage: test
  image: node:alpine3.10
  script:
    - npm test
  dependencies:
    - build-app

# ---------- OAST Frontend ----------
oast-frontend:
  stage: oast-frontend
  image: node:alpine3.10          # Switch to secfigo/retirejs for production
  script:
    - npm install -g retire
    - retire --outputformat json \
             --outputpath retirejs-report.json \
             --severity high
  artifacts:
    paths:
      - retirejs-report.json
    expire_in: 2 days
  dependencies:
    - build-app

The dependencies keyword ensures each job receives the exact node_modules produced by the build step, keeping the SCA scan accurate.


5. Tips & Common Questions

✅ Tips for a Smooth Integration

  1. Cache node_modules – Use the CI cache feature to speed up subsequent runs.
  2. Fail fast – Add allow_failure: false and a when: on_failure rule to abort the pipeline if the SCA report exceeds a severity threshold.
  3. Version pinning – Explicitly set the retire.js version in the Docker image tag (e.g., secfigo/retirejs:2.3.0) to avoid surprise updates.

❓ Common Questions

Question Answer
Do I need both SCA and OAST? Yes. SCA finds known library issues; OAST uncovers runtime flaws that libraries alone cannot reveal.
Can I run retire.js without Docker on a Windows runner? Absolutely. Install Node, run npm install -g retire, then execute the same CLI command.
What if my pipeline runner doesn’t have Docker installed? Use the image: approach (Option 1). The tool runs directly in the runner’s environment.
How do I treat the retirejs-report.json? Publish it as an artifact, feed it into a security dashboard, or add a script that parses the JSON and fails the job if any “high” severity findings exist.
Why does the Docker container sometimes break the pipeline? The container runs as a non‑root user by default, which may lack permission to write to the mounted workspace. Add --user $(id -u):$(id -g) to the docker run command if needed.

Conclusion

Combining Software Component Analysis and Open Application Security Testing within a single CI/CD pipeline gives you early visibility into both what you ship and how it behaves under attack. By sequencing the build → test → oast‑frontend stages, you ensure that each security scan works on the exact artifact that passed functional verification.

Choose the execution method that matches your organization’s security posture: the lightweight node:alpine image for speed and simplicity, or a dedicated Docker image for isolation and reproducibility. With the example configuration and tips provided, you can now embed robust SCA and OAST checks into any modern DevSecOps workflow.