Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/cve-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
#
# Reusable workflow: scans a single image reference with Trivy and uploads the
# results to the GitHub Security tab. Called by each service's build-and-push
# workflow right after it pushes to ghcr.io, passing the exact image tag that
# was just pushed.

name: Run CVE Scan on Service Images

on:
workflow_call:
inputs:
image:
required: true
type: string

jobs:
scan:
name: trivy Scan
runs-on: ubuntu-latest
permissions:
packages: read
contents: read # Required to checkout and read repo files
security-events: write # Required to upload SARIF files to Security tab
actions: read # Required for upload-sarif to process results on private repos

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Log in to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
Comment on lines +34 to +35

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Authenticate against the registry that owns inputs.image.

Both service workflows push to configurable REGISTRY_URL values, but this job only logs into ghcr.io. Scans will fail for Azure, GCP, OCI, or other private registries unless registry-specific credentials are passed to this reusable workflow and used here.

🧰 Tools
🪛 zizmor (1.26.1)

[error] 35-35: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cve-scan.yml around lines 34 - 35, Update the CVE scan
workflow’s registry login step to authenticate against the registry owning
inputs.image rather than hardcoding ghcr.io. Add the required registry-specific
credential inputs to the reusable workflow and use those inputs with the
configured REGISTRY_URL, preserving the existing docker login flow for all
supported private registries.


- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@7b7aa264d83dc58691451798b4d117d53d21edfe
with:
image-ref: ${{ inputs.image }}
format: 'sarif'
output: 'trivy-results.sarif'
severity: HIGH,CRITICAL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow excerpt =="
sed -n '1,120p' .github/workflows/cve-scan.yml 2>/dev/null || true

echo "== action refs =="
rg -n "aquasecurity/trivy-action|trivy-results.sarif|severity:" .github/workflows -S || true

echo "== local module docs if present =="
rg -n "limit-severities-for-sarif|HIGH,CRITICAL|SARIF|sarif" .github workflows src node_modules 2>/dev/null | head -200 || true

Repository: Sunbird-Knowlg/knowledge-platform

Length of output: 2786


🌐 Web query:

aquasecurity/trivy-action sarif limit-severities-for-sarif input documentation

💡 Result:

In the aquasecurity/trivy-action GitHub Action, the limit-severities-for-sarif input is a boolean parameter used to control how vulnerability severities are handled when generating SARIF output [1][2]. By default, this input is set to false, which means the SARIF report will include all detected vulnerabilities, regardless of the severities configured in the severity input [1][3]. When set to true, the action ensures the generated SARIF report respects the severity filter (e.g., CRITICAL,HIGH), meaning only vulnerabilities matching those specified levels will be included in the report [3][4]. This parameter is particularly useful for aligning the SARIF report content with the action's exit code behavior, as well as for reducing noise in GitHub Code Scanning alerts [3][5][6]. When limit-severities-for-sarif is false, a scan might report lower-severity vulnerabilities in the SARIF output even if the severity input is restricted, which can lead to inconsistencies where an exit-code check fails due to findings that were supposed to be ignored [4][6]. Documentation for this input is found in the main README.md and action.yaml of the trivy-action repository [1][7]. Example Usage: - name: Run Trivy uses: aquasecurity/trivy-action@master with: format: 'sarif' output: 'trivy-results.sarif' severity: 'CRITICAL,HIGH' limit-severities-for-sarif: 'true'

Citations:


Restrict SARIF findings to HIGH and CRITICAL.

With SARIF output, severity: HIGH,CRITICAL alone can still include all severities because limit-severities-for-sarif defaults to false; Code Scanning will receive lower-severity results unless it is enabled.

Proposed fix
           output: 'trivy-results.sarif'
           severity: HIGH,CRITICAL
+          limit-severities-for-sarif: true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
format: 'sarif'
output: 'trivy-results.sarif'
severity: HIGH,CRITICAL
format: 'sarif'
output: 'trivy-results.sarif'
severity: HIGH,CRITICAL
limit-severities-for-sarif: true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/cve-scan.yml around lines 41 - 43, Update the Trivy
configuration in the workflow’s SARIF output block to enable the
limit-severities-for-sarif option, while retaining severity: HIGH,CRITICAL, so
generated SARIF findings contain only HIGH and CRITICAL results.

Source: MCP tools


- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: 'trivy-results.sarif'

16 changes: 16 additions & 0 deletions .github/workflows/knowlg-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
needs: check-config
if: needs.check-config.outputs.should_build == 'true'
runs-on: ubuntu-latest
outputs:
image: ${{ steps.push.outputs.image }}

# CSP (cloud service provider) selects the Maven profile and Docker build-arg.
# Set the repository/environment variable CSP to azure | aws | gcp | oci. Defaults to azure.
Expand Down Expand Up @@ -92,7 +94,21 @@ jobs:

# Step 7: Push Docker Image
- name: Push Docker Image
id: push
run: |
docker push $REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}
echo "Pushed Docker image: $REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}"
echo "image=$REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
git ls-files .github/workflows || true

echo
echo "== relevant workflow excerpts =="
for f in .github/workflows/knowlg-service.yml .github/workflows/search-service.yml; do
  if [ -f "$f" ]; then
    echo "--- $f ($(wc -l < "$f") lines) ---"
    nl -ba "$f" | sed -n '1,180p'
  fi
done

echo
echo "== occurrences of REGISTRY_URL and image output =="
rg -n "REGISTRY_URL|GITHUB_OUTPUT|outputs:|download-artifact|upload-artifact|github\\.action_ref|REPOSITORY|IMAGE_NAME|IMAGE_TAG|SCAN|scan" .github/workflows || true

Repository: Sunbird-Knowlg/knowledge-platform

Length of output: 697


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== relevant workflow excerpts using awk ==\n'
for f in .github/workflows/knowlg-service.yml .github/workflows/search-service.yml; do
  if [ -f "$f" ]; then
    echo "--- $f ($(wc -l < "$f") lines) ---"
    awk '{printf "%6d\t%s\n", NR, $0}' "$f" | sed -n '1,180p'
  fi
done

printf '\n== occurrences of REGISTRY_URL and image output ==\n'
grep -RInE "REGISTRY_URL|GITHUB_OUTPUT|outputs:|download-artifact|upload-artifact|github\.action_ref|REPOSITORY|IMAGE_NAME|IMAGE_TAG|SCAN|scan" .github/workflows || true

printf '\n== all references to knowlg/search scan image or reusable workflow ==\n'
grep -RInE "knowlg-service|search-service|image=|scan|security|trivy|sast|sca" .github/workflows || true

Repository: Sunbird-Knowlg/knowledge-platform

Length of output: 19955


Keep secret-derived registry data out of job outputs.

The image output contains ${{ secrets.REGISTRY_URL }}; GitHub can redact outputs that include secret values, making subsequent needs.<job>.outputs.image values empty and skipping the cve-scan jobs. Output only non-secret components like the image name, image tag, and repository, and pass registry configuration as secrets to cve-check.yml.

📍 Affects 2 files
  • .github/workflows/knowlg-service.yml#L101-L101 (this comment)
  • .github/workflows/search-service.yml#L96-L96
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/knowlg-service.yml at line 101, Remove secret-derived
REGISTRY_URL from the image outputs in the image-build steps of
.github/workflows/knowlg-service.yml (line 101) and
.github/workflows/search-service.yml (line 96); output only non-secret image
components such as name, tag, and repository, then pass the registry
configuration separately as secrets to cve-check.yml while preserving the
cve-scan job inputs.

Source: MCP tools


cve-scan:
needs: build-and-push
if: needs.build-and-push.outputs.image != ''
permissions:
contents: read
packages: read
security-events: write
actions: read
uses: ./.github/workflows/cve-check.yml
with:
image: ${{ needs.build-and-push.outputs.image }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Use the reusable workflow filename that exists.

Both callers reference cve-check.yml, while the added file is cve-scan.yml; actionlint cannot resolve the referenced file.

  • .github/workflows/knowlg-service.yml#L111-L113: change uses to ./.github/workflows/cve-scan.yml.
  • .github/workflows/search-service.yml#L106-L108: change uses to ./.github/workflows/cve-scan.yml.
🧰 Tools
🪛 actionlint (1.7.12)

[error] 111-111: could not read reusable workflow file for "./.github/workflows/cve-check.yml": open /home/jailuser/git/.github/workflows/cve-check.yml: no such file or directory

(workflow-call)

📍 Affects 2 files
  • .github/workflows/knowlg-service.yml#L111-L113 (this comment)
  • .github/workflows/search-service.yml#L106-L108
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/knowlg-service.yml around lines 111 - 113, Update the
reusable workflow references from cve-check.yml to the existing cve-scan.yml in
.github/workflows/knowlg-service.yml lines 111-113 and
.github/workflows/search-service.yml lines 106-108, preserving the existing
image input.

Source: Linters/SAST tools


18 changes: 17 additions & 1 deletion .github/workflows/search-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ jobs:
needs: check-config
if: needs.check-config.outputs.should_build == 'true'
runs-on: ubuntu-latest
outputs:
image: ${{ steps.push.outputs.image }}

steps:
# Step 1: Checkout the code
Expand Down Expand Up @@ -87,6 +89,20 @@ jobs:

# Step 7: Push Docker Image
- name: Push Docker Image
id: push
run: |
docker push $REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}
echo "Pushed Docker image: $REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}"
echo "Pushed Docker image: $REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}"
echo "image=$REGISTRY_URL/${IMAGE_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT

cve-scan:
needs: build-and-push
if: needs.build-and-push.outputs.image != ''
permissions:
contents: read
packages: read
security-events: write
actions: read
uses: ./.github/workflows/cve-check.yml
with:
image: ${{ needs.build-and-push.outputs.image }}