Skip to content

chore(security): revert to OSS-CLI stack (RAN-46 path B board ruling) #7

chore(security): revert to OSS-CLI stack (RAN-46 path B board ruling)

chore(security): revert to OSS-CLI stack (RAN-46 path B board ruling) #7

Workflow file for this run

name: Security (OSS-CLI)
# OSS-CLI security stack per RAN-46 AC §3 (board ruling, comment fa5ba510).
# Replaces Sonar + CodeQL + OWASP Dependency-Check.
#
# Six independent jobs — fail-fast off so all signals surface on a single run.
# All actions SHA-pinned per Scorecard `Pinned-Dependencies`. Top-level
# `permissions: read-all` per Scorecard `Token-Permissions`; jobs scope up
# only when needed (gitleaks needs full git history; sbom job uploads).
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '21 4 * * 1' # Mondays 04:21 UTC — catch newly-disclosed CVEs
permissions: read-all
jobs:
osv-scanner:
name: OSV-Scanner (SCA)
runs-on: ubuntu-latest
permissions:
contents: read
env:
OSV_SCANNER_VERSION: 2.3.5
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
# Install osv-scanner from the official GitHub release (binary, not the
# action — google/osv-scanner-action's `action.yml` is composite-only and
# fails when invoked as a job step). Using the preinstalled `gh` CLI
# avoids any external `curl`/`wget` per /home/dev/.claude/CLAUDE.md.
- name: Install osv-scanner
run: |
gh release download "v${OSV_SCANNER_VERSION}" \
--repo google/osv-scanner \
--pattern 'osv-scanner_linux_amd64' \
--output osv-scanner
chmod +x osv-scanner
- name: Run osv-scanner (recursive, skip git history)
run: ./osv-scanner --recursive --skip-git ./
trivy:
name: Trivy (filesystem + container scan)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: .
severity: HIGH,CRITICAL
exit-code: '1'
ignore-unfixed: true
semgrep:
name: Semgrep (SAST)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
- name: Install semgrep
run: python -m pip install --quiet --upgrade pip semgrep
- name: Run semgrep (security-audit + owasp-top-ten + java)
run: |
semgrep scan \
--error \
--config p/security-audit \
--config p/owasp-top-ten \
--config p/java \
--severity ERROR \
--metrics off
gitleaks:
name: Gitleaks (secret scan)
runs-on: ubuntu-latest
permissions:
contents: read
env:
GITLEAKS_VERSION: 8.30.1
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
with:
fetch-depth: 0
# The official `gitleaks/gitleaks-action` requires a paid license for
# GitHub organisations. The underlying gitleaks CLI is MIT-licensed and
# free; install it directly from the upstream release. Using the
# preinstalled `gh` CLI avoids any external `curl`/`wget`.
- name: Install gitleaks
run: |
gh release download "v${GITLEAKS_VERSION}" \
--repo gitleaks/gitleaks \
--pattern "gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
--output gitleaks.tar.gz
tar -xzf gitleaks.tar.gz gitleaks
chmod +x gitleaks
- name: Run gitleaks (full git history)
run: ./gitleaks detect --source . --redact --no-banner --exit-code 1
jscpd:
name: jscpd (duplication < 3% on touched code)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '20'
- run: |
npx --yes jscpd@4 \
--threshold 3 \
--reporters consoleFull \
--format "java,javascript,typescript" \
--ignore "**/target/**,**/node_modules/**,**/grammar/**,**/generated-sources/**,**/dist/**" \
./
sbom:
name: SBOM (SPDX + CycloneDX)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2
- name: Generate SPDX SBOM
uses: anchore/sbom-action@fc46e51fd3cb168ffb36c6d1915723c47db58abb # v0.17.7
with:
format: spdx-json
output-file: sbom.spdx.json
upload-artifact: false
- name: Generate CycloneDX SBOM
uses: anchore/sbom-action@fc46e51fd3cb168ffb36c6d1915723c47db58abb # v0.17.7
with:
format: cyclonedx-json
output-file: sbom.cdx.json
upload-artifact: false
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4.6.2
with:
name: sbom
path: |
sbom.spdx.json
sbom.cdx.json
retention-days: 90