# Reusable: security-static + license gate. # CodeQL is not here: PRs do not run it. It runs on push to main, weekly, and # inside dry-run.yml / release.yml, which call codeql.yml directly. # Runs independently from lint/test/build — does not block the main pipeline. # Affects overall workflow success status. name: Security Gate on: workflow_call: inputs: lanes: description: 'PR lane selection (scripts/ci/select-lanes.sh JSON list); "all" = every job (dry run, release)' type: string default: all permissions: contents: read jobs: security-static: runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: "Layer 1: Static allow-list audit" run: | bash tests/test_security_audit_subprocess_calls.sh scripts/security-audit.sh - name: "Layer 6: UI security audit" run: | bash tests/test_security_ui_urls.sh scripts/security-ui.sh - name: "Layer 8: Vendored dependency integrity" run: scripts/security-vendored.sh license-gate: if: ${{ inputs.lanes == 'all' || contains(fromJSON(inputs.lanes), 'license-gate') }} runs-on: ubuntu-latest timeout-minutes: 240 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Install ScanCode Toolkit # Pinned: an unpinned install picked up pluggy 1.7.0, which breaks # scancode at import (see .github/scancode-constraints.txt). env: PIP_CONSTRAINT: ${{ github.workspace }}/.github/scancode-constraints.txt run: pipx install scancode-toolkit==32.5.0 - name: "Gate self-test (a planted violation must be detected)" run: scripts/license-gate.sh --selftest - name: "License compliance gate (one finding fails)" run: scripts/license-gate.sh - name: "License provenance audit (byte-identity vs upstream)" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: scripts/audit-license-provenance.py