CI/CD Evidence
1. CI/CD Pipeline Overview¶
FirstTry uses GitHub Actions to automate:
- Linting and type checking
- Dependency vulnerability scanning
- Enterprise documentation validation
- Evidence artifact generation
- Release tagging
2. Tools and Commands in Evidence Bundle¶
All commands executed during evidence generation:
Linting¶
forge lint --strict
- Validates Forge manifest.yml
- Checks for API usage consistency
- Fails on malformed configuration
Dependency Audit¶
npm audit --audit-level=high
- Scans dependencies for known CVEs
- Fails if high-severity vulnerability detected
- Output: npm_audit_high.txt
Dependency Tree¶
npm ls --json
- Lists all installed dependencies
- Output: dependency_tree.json
- Used for SBOM generation and audit trail
SBOM Generation (CycloneDX)¶
npx @cyclonedx/bom -o docs/evidence/{date}_release/cyclonedx_sbom.json
- Generates Software Bill of Materials
- Format: CycloneDX XML/JSON (industry standard)
- Used for supply chain transparency
- If fails and FT_ALLOW_FALLBACK_SBOM=1: falls back to npm ls --json
Vulnerability Scanning¶
trivy fs .
- Filesystem/code scanning
- Detects secrets, misconfigurations, vulnerabilities
- Output: trivy_scan.txt
- Fails if critical issues detected
Resolver Scan (Mutation Detection)¶
Custom script detects:
- All fetch(), axios, node-fetch calls
- All POST/PUT/DELETE usage
- Output: resolver_scan.txt
Commands:
grep -rn "POST\|PUT\|DELETE" src/
grep -rn "fetch(\|axios\|node-fetch" src/
3. Evidence Artifacts Generated¶
Location: docs/evidence/{YYYY-MM-DD}_release/
| Artifact | Command | Purpose |
|---|---|---|
| forge_lint_strict.txt | forge lint --strict | Manifest validation |
| npm_audit_high.txt | npm audit --audit-level=high | Dependency vulnerabilities |
| dependency_tree.json | npm ls --json | Dependency inventory |
| cyclonedx_sbom.json | npx @cyclonedx/bom | Software Bill of Materials |
| fallback_sbom_dependency_tree.json | npm ls --json (if CycloneDX fails) | SBOM fallback (if allowed) |
| sbom_status.txt | echo "SBOM=FALLBACK_DEP_TREE" | Fallback indicator |
| trivy_scan.txt | trivy fs . | Code/filesystem scanning |
| manifest_scopes_snapshot.txt | grep -A N "scopes:" manifest.yml | Scope snapshot |
| resolver_scan.txt | Custom mutation detection | POST/PUT/DELETE detection |
| package-lock.sha256 | sha256sum package-lock.json | Dependency lock hash |
| manifest.sha256 | sha256sum manifest.yml | Manifest hash |
| evidence_hashes.txt | sha256sum * | Hash manifest of all evidence |
4. SBOM Fallback Policy¶
Default behavior: Requires CycloneDX SBOM
npx @cyclonedx/bom -o docs/evidence/{date}_release/cyclonedx_sbom.json
If CycloneDX fails:
- Check environment variable:
FT_ALLOW_FALLBACK_SBOM - If not set or
FT_ALLOW_FALLBACK_SBOM=0:- Print error: "ERROR: CycloneDX SBOM generation failed. Set FT_ALLOW_FALLBACK_SBOM=1 to allow fallback..."
- Exit code 2 (fail-closed)
- If
FT_ALLOW_FALLBACK_SBOM=1:- Generate fallback from
npm ls --json - Save as:
docs/evidence/{date}_release/fallback_sbom_dependency_tree.json - Write marker file:
docs/evidence/{date}_release/sbom_status.txtwith content:SBOM=FALLBACK_DEP_TREE - Continue (allow build to proceed)
- Generate fallback from
Caveat: Fallback SBOM is less granular than CycloneDX; not recommended for production unless necessary.
5. Failure Conditions¶
CI/CD build fails (exit code ≠ 0) if:
- ✅ forge lint --strict reports errors
- ✅ npm audit detects high-severity vulnerability
- ✅ trivy fs detects critical issue
- ✅ resolver_scan.txt contains POST/PUT/DELETE in production code
- ✅ manifest_scopes_snapshot.txt cannot be generated
- ✅ CycloneDX fails AND FT_ALLOW_FALLBACK_SBOM != 1
- ✅ Evidence hashes cannot be computed
- ✅ Package-lock or manifest hash doesn't match expected baseline
No soft failures: All errors are hard failures (exit non-zero).
6. GitHub Actions Workflow¶
File: .github/workflows/docs.yml
Triggers:
- Push with git tag matching
v*(e.g., v0.4.2) - Manual trigger (if needed)
Steps:
- Checkout code
- Setup Node.js v20
- npm ci (clean install)
- bash tools/check_tooling_prereqs.sh (verify node, npm, forge, trivy)
- node tools/md_link_check.mjs (check doc links)
- bash tools/enterprise_docs_gate.sh (validate all controls)
- Status: Pass/Fail reported in workflow UI
Node version: Pinned to v20 (exact requirement)
7. Manual Evidence Generation¶
For local testing or offline generation:
# Generate evidence for today
bash tools/generate_enterprise_evidence.sh
# OR specify date
bash tools/generate_enterprise_evidence.sh 2026-02-26
# Check output
ls -la docs/evidence/2026-02-26_release/
Requirements:
- bash 4+ (macOS/Linux)
- node 20, npm, forge CLI, trivy installed
- Current directory = app root
8. Evidence Retention¶
Retention period: Minimum 12 months
Storage:
- Committed to git (docs/evidence/)
- Immutable history via git
- Can be recovered:
git log --all -- docs/evidence/
Deletion:
- After 12 months, old evidence bundles may be archived
- Requires change management approval (CHANGE_MANAGEMENT_POLICY.md)
- Document deletion in CHANGELOG.md
9. Evidence Transparency¶
All evidence artifacts are:
- ✅ Deterministic (same input → same output)
- ✅ Testable (reproduce locally with same tools)
- ✅ Human-readable (JSON, plaintext, no binaries)
- ✅ Committed to git (version-controlled)
- ✅ Immutable (content hash anchors in baselines)
References¶
- tools/generate_enterprise_evidence.sh: Script source
- tools/enterprise_docs_gate.sh: Gate validation script
- CHANGE_MANAGEMENT_POLICY.md: Evidence regeneration triggers