Skip to content

Commit 05ea72f

Browse files
committed
chore(security): revert to OSS-CLI stack (RAN-46 path B board ruling)
Closes the RAN-46 board ruling (comment fa5ba510): swap shipped Sonar + CodeQL + OWASP Dependency-Check (path A) for the AC-mandated OSS-CLI stack (path B). What lands: + .github/workflows/security.yml — six SHA-pinned jobs: OSV-Scanner (SCA via OSV.dev / GHSA, not NVD), Trivy (filesystem + container), Semgrep (SAST: p/security-audit + p/owasp-top-ten + p/java), Gitleaks (secret scan over full git history), jscpd (duplication < 3% on Java/JS/TS), anchore/sbom-action (SPDX + CycloneDX SBOM artifacts). Top-level `permissions: read-all`. Runs on push to main, every PR, and Mondays 04:21 UTC cron. What's removed: - .github/workflows/ci-java.yml — strips the SonarCloud step and the OWASP Dependency-Check NVD prewarm + cache step. ci-java.yml now just runs `mvn -B -ntp clean verify` (tests + jacoco 85% + SpotBugs) and uploads test/coverage artifacts. - pom.xml — drops `dependency-check-maven` plugin block + its `<owasp.dependency-check.version>` property. JaCoCo 85% gate + SpotBugs binding stay. - dependency-check-suppressions.xml — deleted (no longer needed; OSV + Trivy use their own suppression mechanisms). - README.md — drops Sonar `security_rating` + `reliability_rating` badges, replaces with a Security (OSS-CLI) workflow-status badge. - shared/runbooks/engineering-standards.md §1 quality-gate table — rewritten to list the OSS-CLI gates (OSV / Trivy / Semgrep / Gitleaks / jscpd / SBOM); §5 Security expanded with explicit "OSS-CLI only — do not re-introduce Sonar/CodeQL/NVD without an explicit board ruling reversal" guard; §9 References updated. Coverage gate stays at 85% (jacoco BUNDLE LINE COVEREDRATIO). SpotBugs stays as the Java lint gate (per AC §5 — checkstyle/spotbugs/error-prone are the eligible Java linters). Followups (not in this PR): * Disable CodeQL default-setup via repo Settings → Code security → Code scanning (or `gh api -X DELETE /repos/.../code-scanning/ default-setup` once available). Tracked under post-merge action. * Branch-protection `required_status_checks` will be updated post- merge to require the new security.yml jobs in place of `build` + Sonar + CodeQL. References: * RAN-46 AC §3 (security tooling — OSS-CLI ONLY) * Board ruling comment fa5ba510 on RAN-46 (path B) * OpenSSF Scorecard: Pinned-Dependencies, Token-Permissions
1 parent 6c3b9e9 commit 05ea72f

7 files changed

Lines changed: 150 additions & 325 deletions

File tree

.github/workflows/ci-java.yml

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,7 @@ jobs:
2222
distribution: 'temurin'
2323
java-version: '25'
2424
cache: 'maven'
25-
# Cache the OWASP Dependency-Check NVD data directory across runs so the
26-
# CVE gate does not need to re-download the full feed on every PR.
27-
# `key` is unique per run (forces a save on every run), `restore-keys`
28-
# falls back to the most recent prior cache so the H2 DB is incrementally
29-
# updated rather than rebuilt.
30-
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
31-
with:
32-
path: ~/.m2/repository/org/owasp/dependency-check-data
33-
key: dependency-check-${{ runner.os }}-${{ github.run_id }}
34-
restore-keys: |
35-
dependency-check-${{ runner.os }}-
36-
# Pre-warm the OWASP Dependency-Check NVD cache as a SEPARATE Maven
37-
# invocation. On a cold cache (first run on a branch / cache eviction)
38-
# running `update-only` first avoids the dependency-check-maven 12.2.0
39-
# H2 init race that surfaces as `NullPointerException: Cannot invoke
40-
# BasicDataSource.getConnection() because connectionPool is null`
41-
# during the verify phase (observed on PR #74 build run 24930518462).
42-
# When the cache is warm this step short-circuits via the H2 incremental
43-
# update path. `failOnError=false` so a transient NVD-feed problem here
44-
# does not mask the real CVSS>=7 gate enforced in the verify step
45-
# below — that step still hard-fails on operational scanner failures
46-
# (Reviewer round-3 finding #1).
47-
- name: Pre-warm dependency-check NVD cache
48-
env:
49-
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
50-
run: mvn -B -ntp dependency-check:update-only -DfailOnError=false
51-
- name: Build + verify (jacoco 85% + SpotBugs + dependency-check)
52-
env:
53-
# When the NVD_API_KEY secret is unset, dependency-check falls back
54-
# to the unauthenticated NVD endpoint (rate-limited but functional
55-
# once the cache is warm). Provisioning the secret is tracked under
56-
# RAN-42.
57-
NVD_API_KEY: ${{ secrets.NVD_API_KEY }}
25+
- name: Build + verify (jacoco 85% + SpotBugs)
5826
run: mvn -B -ntp clean verify
5927
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4.6.2
6028
if: always()
@@ -65,14 +33,3 @@ jobs:
6533
with:
6634
name: coverage-report
6735
path: target/site/jacoco/
68-
- name: SonarCloud analysis
69-
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
70-
env:
71-
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
72-
run: >
73-
mvn sonar:sonar -B
74-
-Dsonar.projectKey=RandomCodeSpace_codeiq
75-
-Dsonar.organization=randomcodespace
76-
-Dsonar.host.url=https://sonarcloud.io
77-
"-Dsonar.exclusions=**/grammar/**,target/generated-sources/**"
78-
"-Dsonar.coverage.exclusions=**/grammar/**,target/generated-sources/**"

.github/workflows/security.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
name: Security (OSS-CLI)
2+
# OSS-CLI security stack per RAN-46 AC §3 (board ruling, comment fa5ba510).
3+
# Replaces Sonar + CodeQL + OWASP Dependency-Check.
4+
#
5+
# Six independent jobs — fail-fast off so all signals surface on a single run.
6+
# All actions SHA-pinned per Scorecard `Pinned-Dependencies`. Top-level
7+
# `permissions: read-all` per Scorecard `Token-Permissions`; jobs scope up
8+
# only when needed (gitleaks needs full git history; sbom job uploads).
9+
on:
10+
push:
11+
branches: [main]
12+
pull_request:
13+
branches: [main]
14+
schedule:
15+
- cron: '21 4 * * 1' # Mondays 04:21 UTC — catch newly-disclosed CVEs
16+
17+
permissions: read-all
18+
19+
jobs:
20+
osv-scanner:
21+
name: OSV-Scanner (SCA)
22+
runs-on: ubuntu-latest
23+
permissions:
24+
contents: read
25+
steps:
26+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
27+
- uses: google/osv-scanner-action@c51854704019a247608d928f370c98740469d4b5 # v2.3.5
28+
with:
29+
scan-args: |-
30+
--recursive
31+
--skip-git
32+
./
33+
34+
trivy:
35+
name: Trivy (filesystem + container scan)
36+
runs-on: ubuntu-latest
37+
permissions:
38+
contents: read
39+
steps:
40+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
41+
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
42+
with:
43+
scan-type: fs
44+
scan-ref: .
45+
severity: HIGH,CRITICAL
46+
exit-code: '1'
47+
ignore-unfixed: true
48+
49+
semgrep:
50+
name: Semgrep (SAST)
51+
runs-on: ubuntu-latest
52+
permissions:
53+
contents: read
54+
container:
55+
image: semgrep/semgrep@sha256:6f5ee7e5c4c8e09e25a3cabf61a4df04df80e11e82e7e3d6ea8cb6dfbf9e2a0d
56+
steps:
57+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
58+
- run: semgrep ci --error --config p/security-audit --config p/owasp-top-ten --config p/java
59+
env:
60+
SEMGREP_RULES: p/security-audit p/owasp-top-ten p/java
61+
62+
gitleaks:
63+
name: Gitleaks (secret scan)
64+
runs-on: ubuntu-latest
65+
permissions:
66+
contents: read
67+
steps:
68+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
69+
with:
70+
fetch-depth: 0
71+
- uses: gitleaks/gitleaks-action@83373cf2f8c4db6e24b41c1a9b086bb9619e9cd3 # v2.3.7
72+
env:
73+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74+
75+
jscpd:
76+
name: jscpd (duplication < 3% on touched code)
77+
runs-on: ubuntu-latest
78+
permissions:
79+
contents: read
80+
steps:
81+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
82+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
83+
with:
84+
node-version: '20'
85+
- run: |
86+
npx --yes jscpd@4 \
87+
--threshold 3 \
88+
--reporters consoleFull \
89+
--languages java,javascript,typescript \
90+
--ignore "**/target/**,**/node_modules/**,**/grammar/**,**/generated-sources/**,**/dist/**" \
91+
./
92+
93+
sbom:
94+
name: SBOM (SPDX + CycloneDX)
95+
runs-on: ubuntu-latest
96+
permissions:
97+
contents: read
98+
steps:
99+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
100+
- name: Generate SPDX SBOM
101+
uses: anchore/sbom-action@fc46e51fd3cb168ffb36c6d1915723c47db58abb # v0.17.7
102+
with:
103+
format: spdx-json
104+
output-file: sbom.spdx.json
105+
upload-artifact: false
106+
- name: Generate CycloneDX SBOM
107+
uses: anchore/sbom-action@fc46e51fd3cb168ffb36c6d1915723c47db58abb # v0.17.7
108+
with:
109+
format: cyclonedx-json
110+
output-file: sbom.cdx.json
111+
upload-artifact: false
112+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4.6.2
113+
with:
114+
name: sbom
115+
path: |
116+
sbom.spdx.json
117+
sbom.cdx.json
118+
retention-days: 90

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
<a href="https://github.com/RandomCodeSpace/codeiq/actions/workflows/ci-java.yml"><img src="https://img.shields.io/github/actions/workflow/status/RandomCodeSpace/codeiq/ci-java.yml?branch=main&style=flat-square&logo=github&label=CI" alt="CI"></a>
1111
<a href="https://www.oracle.com/java/technologies/downloads/"><img src="https://img.shields.io/badge/Java-25-orange?style=flat-square&logo=openjdk&logoColor=white" alt="Java 25"></a>
1212
<a href="https://github.com/RandomCodeSpace/codeiq/blob/main/LICENSE"><img src="https://img.shields.io/github/license/RandomCodeSpace/codeiq?style=flat-square&label=License" alt="MIT License"></a>
13-
<a href="https://sonarcloud.io/summary/overall?id=RandomCodeSpace_codeiq"><img src="https://sonarcloud.io/api/project_badges/measure?project=RandomCodeSpace_codeiq&metric=security_rating" alt="Security"></a>
14-
<a href="https://sonarcloud.io/summary/overall?id=RandomCodeSpace_codeiq"><img src="https://sonarcloud.io/api/project_badges/measure?project=RandomCodeSpace_codeiq&metric=reliability_rating" alt="Reliability"></a>
13+
<a href="https://github.com/RandomCodeSpace/codeiq/actions/workflows/security.yml"><img src="https://img.shields.io/github/actions/workflow/status/RandomCodeSpace/codeiq/security.yml?branch=main&style=flat-square&logo=github&label=Security%20%28OSS-CLI%29" alt="Security (OSV-Scanner + Trivy + Semgrep + Gitleaks + jscpd + SBOM)"></a>
1514
<a href="https://api.securityscorecards.dev/projects/github.com/RandomCodeSpace/codeiq"><img src="https://api.securityscorecards.dev/projects/github.com/RandomCodeSpace/codeiq/badge" alt="OpenSSF Scorecard"></a>
1615
<a href="https://www.bestpractices.dev/projects/codeiq"><img src="https://img.shields.io/badge/OpenSSF%20Best%20Practices-pending%20registration-lightgrey?style=flat-square&logo=openssf&logoColor=white" alt="OpenSSF Best Practices (pending registration — RAN-46 AC #8)"></a>
1716
<a href="https://github.com/RandomCodeSpace/codeiq"><img src="https://img.shields.io/badge/detectors-97-brightgreen?style=flat-square&logo=codefactor&logoColor=white" alt="97 Detectors"></a>

dependency-check-suppressions.xml

Lines changed: 0 additions & 204 deletions
This file was deleted.

0 commit comments

Comments
 (0)