Repository navigation
chore(evhardware): track master 0ca5d9c, ledger ignores the factory c… #122
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Security | |
| # Security checks before any APK is deployed to a vehicle. | |
| # Blocking: permission-drift + secrets. Informational (SARIF): SAST + dependencies. | |
| on: | |
| push: | |
| branches: [master, "feat/**", "feature/**"] | |
| pull_request: | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| security-events: write # upload SARIF -> Security tab | |
| jobs: | |
| permission-gate: | |
| name: Permission-drift gate (blocking) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Check manifest permissions | |
| run: bash .github/security/check-permissions.sh | |
| secrets: | |
| name: Secret scan (blocking) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: { fetch-depth: 0 } | |
| - uses: gitleaks/gitleaks-action@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| sast: | |
| name: SAST mobile (mobsfscan + semgrep) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - uses: actions/setup-python@v5 | |
| with: { python-version: "3.12" } | |
| - name: Run scanners (SARIF, non-blocking) | |
| run: | | |
| # Always produce a valid SARIF even if a scanner fails -> the upload never breaks. | |
| empty_sarif() { | |
| printf '%s' '{"version":"2.1.0","$schema":"https://json.schemastore.org/sarif-2.1.0.json","runs":[{"tool":{"driver":{"name":"'"$1"'","rules":[]}},"results":[]}]}' > "$2" | |
| } | |
| pip install mobsfscan semgrep | |
| mobsfscan --sarif -o mobsfscan.sarif app/src || true | |
| [ -s mobsfscan.sarif ] || empty_sarif mobsfscan mobsfscan.sarif | |
| semgrep --config p/java --config p/security-audit --sarif -o semgrep.sarif app/src || true | |
| [ -s semgrep.sarif ] || empty_sarif semgrep semgrep.sarif | |
| # Code scanning needs GitHub Advanced Security on a private repository. This repo is | |
| # private for now, so the upload is expected to fail with "Resource not accessible by | |
| # integration" — the scan itself still runs and the findings still ship as an artifact. | |
| # These become real Security-tab entries the day the repo goes public. | |
| - name: Upload mobsfscan SARIF | |
| if: always() | |
| continue-on-error: true | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: mobsfscan.sarif | |
| category: mobsfscan | |
| - name: Upload Semgrep SARIF | |
| if: always() | |
| continue-on-error: true | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: semgrep.sarif | |
| category: semgrep | |
| - name: Security report (artifact) | |
| if: always() | |
| run: | | |
| { | |
| echo "# EVChargePilot security report" | |
| echo "_$(date -u)_" | |
| echo | |
| echo "## mobsfscan" | |
| python -c "import json;d=json.load(open('mobsfscan.sarif'));print('findings:',sum(len(r.get('results',[])) for r in d.get('runs',[])))" 2>/dev/null || echo "n/a" | |
| echo "## semgrep" | |
| python -c "import json;d=json.load(open('semgrep.sarif'));print('findings:',sum(len(r.get('results',[])) for r in d.get('runs',[])))" 2>/dev/null || echo "n/a" | |
| } > security-report.md | |
| cat security-report.md | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: security-report | |
| path: | | |
| security-report.md | |
| *.sarif | |
| dependencies: | |
| name: Dependency scan (OWASP) | |
| runs-on: ubuntu-latest | |
| continue-on-error: true # informational | |
| env: | |
| NVD_API_KEY: ${{ secrets.NVD_API_KEY }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| # Runs only when an NVD API key is configured — otherwise the NVD API is too | |
| # rate-limited to be useful, and an empty --nvdApiKey breaks the tool. | |
| - name: OWASP Dependency-Check | |
| if: ${{ env.NVD_API_KEY != '' }} | |
| uses: dependency-check/Dependency-Check_Action@main | |
| with: | |
| project: EVChargePilot | |
| path: "." | |
| format: "SARIF" | |
| args: --nvdApiKey ${{ env.NVD_API_KEY }} | |
| - name: Upload dependency SARIF | |
| if: ${{ env.NVD_API_KEY != '' }} | |
| continue-on-error: true | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: reports/dependency-check-report.sarif | |
| category: dependency-check |