name: Security and release integrity on: push: branches: [main] pull_request: workflow_dispatch: permissions: contents: read jobs: verify: runs-on: ubuntu-latest timeout-minutes: 25 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: persist-credentials: false - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 22 cache: npm - run: npm ci --ignore-scripts - name: Install pinned Semgrep (security:ci runs the custom rules) run: pipx install semgrep==1.171.0 - name: Run build, typecheck, tests, dependency audit, and static-analysis gate run: npm run security:ci - name: Generate checksums and CycloneDX SBOM shell: bash run: | mkdir -p security-artifacts npm sbom --sbom-format cyclonedx > security-artifacts/sbom.cdx.json find packages/widget/dist packages/demo/dist -type f -print0 | sort -z | xargs -0 sha256sum > security-artifacts/SHA256SUMS - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: bitlogin-security-artifacts path: security-artifacts/ if-no-files-found: error static-analysis: runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: persist-credentials: false fetch-depth: 0 - name: Install pinned Semgrep run: pipx install semgrep==1.171.0 - name: Scan repository rules without per-rule timeouts run: semgrep scan --config auto --error --timeout 0 packages - name: Enforce local randomness rules (entropy audit ยง13) run: semgrep scan --config .semgrep.yml --error --timeout 0 packages - name: Scan repository history for secrets uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}