diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml new file mode 100644 index 000000000..91674a982 --- /dev/null +++ b/.github/workflows/osv-scanner.yml @@ -0,0 +1,29 @@ +name: OSV-Scanner + +# Dependency vulnerability scan (#2182) via Google's official reusable +# workflow. Runs weekly and on any PR that touches the dependency manifests. +# Tokenless: needs zero secrets. Findings are reported in the job log and as +# a SARIF artifact on the run; code-scanning upload is deliberately disabled +# so the workflow stays read-only (no security-events: write). + +on: + pull_request: + branches: [master] + paths: + - 'bun.lock' + - 'package.json' + schedule: + - cron: '30 6 * * 1' # weekly, Monday 06:30 UTC + workflow_dispatch: + +permissions: + contents: read + +jobs: + osv-scan: + permissions: + actions: read + contents: read + uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@9a498708959aeaef5ef730655706c5a1df1edbc2 # v2.3.8 + with: + upload-sarif: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 44d9192bd..e07a71c7d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,6 +19,10 @@ jobs: target: bun-linux-x64 artifact: gbrain-linux-x64 runs-on: ${{ matrix.os }} + permissions: + contents: read + id-token: write # for attest-build-provenance (Sigstore OIDC) + attestations: write # for attest-build-provenance steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 @@ -28,6 +32,10 @@ jobs: - run: bun test - run: bun run verify - run: bun build --compile --target=${{ matrix.target }} --outfile bin/${{ matrix.artifact }} src/cli.ts + - name: Attest build provenance + uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1 + with: + subject-path: bin/${{ matrix.artifact }} - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: ${{ matrix.artifact }} diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 000000000..7a736f4b0 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,36 @@ +name: Semgrep + +# Static analysis (SAST) with Semgrep Community Edition (#2272). Tokenless: +# uses the public registry rulesets, needs zero secrets. Findings print in +# the job log; no code-scanning/SARIF upload by design (keeps permissions +# read-only, no security-events: write). + +on: + pull_request: + branches: [master] + schedule: + - cron: '30 7 * * 1' # weekly, Monday 07:30 UTC + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + semgrep: + runs-on: ubuntu-latest + timeout-minutes: 20 + container: + image: semgrep/semgrep:1.170.0@sha256:c98f8829eea377274ee4b10656458b078b88232469b2ff913f091c2317347c9d + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + # Non-blocking initially (continue-on-error): the first runs establish a + # baseline without failing unrelated PRs. Graduation path: once the + # baseline findings are triaged (fixed or `# nosemgrep`'d), remove + # continue-on-error so new findings block PRs. + - name: Semgrep scan (report-only) + run: semgrep scan --config p/default --config p/typescript --error + continue-on-error: true