CI / CDGitLab CI

GitLab CI

Pencheff ships a reusable GitLab CI template at apps/gitlab-ci/.gitlab-ci.yml in the repository.

Quick start

Add to your project’s .gitlab-ci.yml:

include:
  - remote: 'https://raw.githubusercontent.com/BalaSriharsha-Ch/pencheff/main/apps/gitlab-ci/.gitlab-ci.yml'
 
variables:
  PENCHEFF_TARGET: "https://your-app.example.com"
  PENCHEFF_FAIL_ON: "high"
  PENCHEFF_API_TOKEN: $PENCHEFF_API_TOKEN   # set in GitLab CI/CD Settings → Variables

The template runs on merge requests and pushes to the default branch. The scan report (JSON + Markdown) is uploaded as a GitLab artifact retained for 30 days.

Variables

VariableDefaultDescription
PENCHEFF_TARGET(required)Target URL or HOST:PORT
PENCHEFF_PROFILEcicdquick | standard | deep | api-only | compliance | cicd
PENCHEFF_FAIL_ONhighMinimum severity to fail the pipeline: info | low | medium | high | critical
PENCHEFF_API_BASE(empty)Hosted Pencheff API base URL
PENCHEFF_API_TOKEN(empty)Bearer token — set as a masked CI/CD variable
PENCHEFF_ENGAGEMENT_ID(empty)Scope scan to a specific engagement
PENCHEFF_ARTIFACT_NAMEpencheff-reportName of the uploaded artifact

Full template (copy-paste)

stages: [security]
 
variables:
  PENCHEFF_TARGET: ""
  PENCHEFF_PROFILE: "cicd"
  PENCHEFF_FAIL_ON: "high"
  PENCHEFF_API_BASE: ""
  PENCHEFF_API_TOKEN: ""
  PENCHEFF_ENGAGEMENT_ID: ""
  PENCHEFF_ARTIFACT_NAME: "pencheff-report"
 
pencheff-security-scan:
  stage: security
  image: python:3.12-slim
  cache:
    paths: [/root/.pencheff/cve_cache.db]
    key: pencheff-cve
  before_script:
    - pip install --quiet pencheff
  script:
    - mkdir -p "$CI_PROJECT_DIR/pencheff-report"
    - |
      EXTRA=""
      if [ -n "$PENCHEFF_ENGAGEMENT_ID" ]; then
        EXTRA="--engagement-id $PENCHEFF_ENGAGEMENT_ID"
      fi
      set +e
      pencheff scan \
        --target "$PENCHEFF_TARGET" \
        --profile "$PENCHEFF_PROFILE" \
        --fail-on "$PENCHEFF_FAIL_ON" \
        --output "$CI_PROJECT_DIR/pencheff-report" \
        --format json,markdown $EXTRA
      RC=$?
      set -e
      case "$RC" in
        0) echo "PENCHEFF_WORST_SEVERITY=none" >> pencheff.env ;;
        2) echo "PENCHEFF_WORST_SEVERITY=$PENCHEFF_FAIL_ON" >> pencheff.env ;;
        *) echo "PENCHEFF_WORST_SEVERITY=error" >> pencheff.env ;;
      esac
      exit $RC
  artifacts:
    when: always
    name: "$PENCHEFF_ARTIFACT_NAME"
    paths: [pencheff-report/]
    reports:
      dotenv: pencheff.env
    expire_in: 30 days
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'

Exit codes

CodeMeaning
0No findings at or above PENCHEFF_FAIL_ON severity
2At least one finding at or above threshold — pipeline fails
otherScan error (network, auth, config)