diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 00000000..6233dea1 --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,4 @@ +self-hosted-runner: + labels: + - blacksmith-2vcpu-ubuntu-2404 + - blacksmith-4vcpu-ubuntu-2204 diff --git a/.github/workflows/actionlint.yml b/.github/workflows/actionlint.yml new file mode 100644 index 00000000..a2691924 --- /dev/null +++ b/.github/workflows/actionlint.yml @@ -0,0 +1,29 @@ +name: Actionlint + +on: + pull_request: + paths: + - '.github/actionlint.yaml' + - '.github/workflows/**' + push: + branches: + - main + paths: + - '.github/actionlint.yaml' + - '.github/workflows/**' + +permissions: + contents: read + +env: + GITHUB_TOKEN: '' + +jobs: + actionlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + with: + persist-credentials: false + + - uses: rhysd/actionlint@914e7df21a07ef503a81201c76d2b11c789d3fca diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml new file mode 100644 index 00000000..da1ecc86 --- /dev/null +++ b/.github/workflows/gitleaks.yml @@ -0,0 +1,28 @@ +name: Gitleaks Scan + +on: + pull_request: + merge_group: + schedule: + - cron: "11 9 * * *" + workflow_dispatch: + +permissions: + contents: read + pull-requests: read + +jobs: + gitleaks: + name: Gitleaks Secret Scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Run Gitleaks + uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 + env: + GITHUB_TOKEN: ${{ github.token }} + GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} diff --git a/.github/workflows/osv-scanner-nightly.yml b/.github/workflows/osv-scanner-nightly.yml new file mode 100644 index 00000000..4586dba7 --- /dev/null +++ b/.github/workflows/osv-scanner-nightly.yml @@ -0,0 +1,19 @@ +name: OSV-Scanner Nightly Scan + +on: + schedule: + - cron: "17 8 * * *" + workflow_dispatch: + +permissions: + actions: read + contents: read + security-events: write + +jobs: + scan-nightly: + uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@9a498708959aeaef5ef730655706c5a1df1edbc2 # v2.3.8 + with: + scan-args: |- + --recursive + ./ diff --git a/.github/workflows/osv-scanner-pr.yml b/.github/workflows/osv-scanner-pr.yml new file mode 100644 index 00000000..b2c110dc --- /dev/null +++ b/.github/workflows/osv-scanner-pr.yml @@ -0,0 +1,77 @@ +name: OSV-Scanner PR Scan + +on: + pull_request: + merge_group: + +permissions: + actions: read + contents: read + security-events: write + +jobs: + scan-pr: + name: OSV Scanner PR + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Checkout target branch + env: + BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }} + run: | + git checkout "$BASE_SHA" + git submodule update --recursive + + - name: Run scanner on existing code + uses: google/osv-scanner-action/osv-scanner-action@9a498708959aeaef5ef730655706c5a1df1edbc2 + continue-on-error: true + with: + scan-args: |- + --format=json + --output=old-results.json + --recursive + ./ + + - name: Checkout current branch + run: | + git checkout -f "$GITHUB_SHA" + git submodule update --recursive + + - name: Run scanner on new code + uses: google/osv-scanner-action/osv-scanner-action@9a498708959aeaef5ef730655706c5a1df1edbc2 + continue-on-error: true + with: + scan-args: |- + --format=json + --output=new-results.json + --recursive + ./ + + - name: Compare scanner results + id: compare + uses: google/osv-scanner-action/osv-reporter-action@9a498708959aeaef5ef730655706c5a1df1edbc2 + continue-on-error: true + with: + scan-args: |- + --output=results.sarif + --old=old-results.json + --new=new-results.json + --gh-annotations=true + --fail-on-vuln=true + + - name: Upload to code scanning + if: ${{ !cancelled() && hashFiles('results.sarif') != '' }} + continue-on-error: true + uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 + with: + sarif_file: results.sarif + + - name: Fail on newly introduced vulnerabilities + if: ${{ steps.compare.outcome == 'failure' }} + run: | + echo "::error::OSV-Scanner found newly introduced vulnerabilities." + exit 1 diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 00000000..ca3463f7 --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,40 @@ +name: Trivy Scan + +on: + pull_request: + merge_group: + schedule: + - cron: "43 8 * * *" + workflow_dispatch: + +permissions: + actions: read + contents: read + security-events: write + +jobs: + trivy: + name: Trivy Filesystem Scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + with: + persist-credentials: false + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@a9c7b0f06e461e9d4b4d1711f154ee024b8d7ab8 + with: + scan-type: fs + scan-ref: . + format: sarif + output: trivy-results.sarif + severity: CRITICAL,HIGH + ignore-unfixed: true + exit-code: "0" + + - name: Upload Trivy SARIF + if: ${{ !cancelled() && hashFiles('trivy-results.sarif') != '' }} + continue-on-error: true + uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 + with: + sarif_file: trivy-results.sarif diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..3cb5056d --- /dev/null +++ b/renovate.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:best-practices", + ":dependencyDashboard", + ":semanticCommits", + ":pinGitHubActionDigests", + "npm:unpublishSafe" + ], + "enabledManagers": ["bun", "github-actions", "dockerfile", "docker-compose"], + "labels": ["dependencies"], + "minimumReleaseAge": "3 days", + "rangeStrategy": "bump", + "separateMajorMinor": true, + "separateMultipleMajor": true, + "vulnerabilityAlerts": { + "enabled": true, + "labels": ["security"] + }, + "osvVulnerabilityAlerts": true, + "lockFileMaintenance": { + "enabled": true, + "schedule": ["before 5am on monday"], + "commitMessageAction": "Lock file maintenance" + }, + "packageRules": [ + { + "description": "Require human approval before Renovate raises major version updates.", + "matchUpdateTypes": ["major"], + "dependencyDashboardApproval": true + }, + { + "description": "Keep Bun ecosystem updates behind the same age gate configured in bunfig.toml.", + "matchDatasources": ["npm"], + "minimumReleaseAge": "3 days" + }, + { + "description": "Pin executable CI dependencies to immutable digests.", + "matchManagers": ["github-actions", "dockerfile", "docker-compose"], + "pinDigests": true + } + ] +}