Skip to main content

CI Security Gates: student worksheet

CVE Lite Classroom · Classroom repository · CVE Lite CLI

In a student kit, read MANAGER-SETUP.md and enter app/. In the source repository, read examples//README.md and enter its student/ directory. Prompts and workflow templates are in the exercise/kit root, not inside app/.

Readiness: complete Exercise 01 or equivalent dependency-remediation practice first. You should be able to explain a direct/transitive dependency, locate an advisory in a report, justify a version change and run tests plus a rescan. Review DEPENDENCY-BASICS.md in the kit (or docs/dependency-basics.md at the repository root). If those tasks are unfamiliar, do Exercise 01 before this lesson. Allow 30 minutes as a follow-on, or 45–60 minutes with equivalent knowledge but no previous exposure to this activity; setup is additional.

Understand the policy first​

CI (continuous integration) means running automated checks when code changes. A security gate is a rule that decides whether a check passes. Here the rule is: require a complete successful scan and block high/critical findings. A workflow lists the automated steps; the provided YAML file is that list, not JavaScript. You can learn and test the rule locally without a GitHub account.

An exit code is a number a command returns to the terminal: usually 0 for success and a nonzero number for failure. Our helper deliberately uses 1 for blocking findings and 2 when it cannot assess the report. The scanner's own exits are separate; inspect its report and errors rather than assuming every nonzero exit means a vulnerability.

Least privilege means giving an automated job only the permissions it needs. This workflow reads repository code and evaluates it; it does not push repairs. That is why the template uses permissions: contents: read, not write access. You can inspect this line and explain it without running GitHub Actions. A continue-on-error setting would let a failed step be treated as non-blocking, undermining a gate meant to stop unsafe changes.

Complete the policy question in the submission template on the local route too. You do not need to memorize YAML syntax or implement a workflow from scratch.

Apply and verify​

  1. Prepare the supplied student application. Run its tests. Inspect the selected manager's workflow template under workflow-templates/.
  2. Run a LOCAL threshold check inside the app:
npm exec --yes --package=cve-lite-cli@1.40.0 -- cve-lite . --json --all --no-open --fail-on high

Immediately after the scan, run echo $? in a POSIX terminal or $LASTEXITCODE in PowerShell, before any other command replaces the status. Also inspect the JSON completeness and findings. The captured starting project produces exit 1 because it has high findings. An installation or lookup failure is different; a nonzero code alone does not tell you which occurred.

  1. Inspect gate.mjs in the app. Copy the exact timestamped JSON filename printed by the scanner and run node gate.mjs "YOUR-ACTUAL-FILENAME.json" (replace the placeholder; do not type angle brackets). Record the exit status immediately. Expected helper results: 1 for high/critical findings; 0 for a complete report with only medium/low or no findings; 2 for a missing, invalid, incomplete or unknown-severity report. Why must a workflow not suppress errors with continue-on-error?

    Before your repair, also try the three supplied synthetic policy cases. They let you test all outcomes without manufacturing a scanner outage. From the exported kit's app folder:

    node gate.mjs ../scenarios/high.json

    Record the exit immediately (echo $? on POSIX, $LASTEXITCODE in PowerShell). Repeat with ../scenarios/clean.json, then ../scenarios/incomplete.json, recording each exit separately. In a full repository, from examples/<manager>/student, use ../../../scenarios/high.json (and the corresponding clean/incomplete filenames) instead. Expected exits are 1, 0 and 2 respectively. Explain why before reading the output. These files are teaching examples, not reports generated by CVEL. Fill the scenario table in the submission template.

  2. Apply a reviewed fix using your manager, run tests and rescan with the same threshold. Run gate.mjs against the new report. Record actual outcomes.

  3. Optional GitHub path: follow the hosted-run walkthrough below. If you already fixed your app, use a fresh student kit to capture the initial failing run; do not undo your work or delete evidence.

  4. Explain three cases: complete scan with high findings; complete scan with no threshold findings; missing/incomplete scan. Only the second should pass this policy. Medium findings can remain; passing is not equivalent to zero vulnerabilities.

No GitHub account? Complete local gate checks. No network? With Node installed, the three synthetic helper checks can still run without package installation. Analyze the dated reference-reports in your kit for the application before/after comparison (or your selected track's reports in the full repository). Distinguish actual local helper execution from live scans you did not perform; do not label historical reports as fresh runs.

Optional hosted-run walkthrough​

Allow extra setup time outside the 30-minute exercise. Use your own disposable repository and follow your institution's rules for intentionally vulnerable teaching examples. No production repository, credentials, deployment or secrets are needed.

  1. Create an empty GitHub repository. Clone it using your normal Git client, or ask your instructor for an empty course repository.
  2. Copy the CONTENTS of the kit's app/ directory to the cloned repository root, including package.json, the manager lockfile, src/, test/, sample-data/, gate.mjs and .yarnrc.yml for Berry. Do not copy node_modules, generated reports, assistant files, instructor solutions or the surrounding kit folder.
  3. At that root, create .github/workflows/. Copy workflow-templates/.yml from the KIT root into it and rename the copy security.yml. Preserve its content. On macOS, reveal hidden files when copying Berry configuration.
  4. Verify the layout: package.json and gate.mjs are at the same level as .github/, not inside an extra app/ subfolder. Review the workflow's read-only permissions and pinned tools. It installs the sample with lifecycle scripts disabled, runs tests, scans, then evaluates the report with gate.mjs.
  5. Commit and push those files using your Git client. In GitHub's Actions tab, open the Classroom dependency gate run. Enable Actions only if needed and permitted. A complete initial scan should fail in the gate step with high/critical findings. Capture the run URL and log; if it fails during installation or scanning, investigate that instead of calling it a successful vulnerability demonstration.
  6. Apply your reviewed fix locally with the chosen manager. Run tests and a fresh scan. Review the package.json and lockfile changes, commit them together, and push again. Open the new Actions run. It should pass only if the scan is complete and the policy has no blocking findings.
  7. Submit both run URLs and explain which step changed. A passing gate does not mean the code is universally secure. Do not add continue-on-error or remove the check to make it pass.

The CLI command in step 2 demonstrates the scanner's built-in threshold. The supplied workflow instead scans WITHOUT that threshold and then uses gate.mjs, so it can apply a stricter completeness/unknown-severity policy. Both are intentional; the workflow is not missing its threshold.

Screenshot preview