From 132b7ba97b830880753030b55d0364bf6a8f421d Mon Sep 17 00:00:00 2001 From: mertcano <35747700+mertcano@users.noreply.github.com> Date: Wed, 26 Aug 2026 00:33:52 +0300 Subject: [PATCH] Fix: Harden CI/CD supply chain, formatting gates, and secret boundaries ### Description This PR addresses supply-chain security risks, implicit secret boundaries, and false-green CI checks identified during the workspace-wide security audit[cite: 53]. ### Key Changes * **Supply-Chain Security (Immutable Action References):** Replaced mutable action version tags (e.g., `v2`, `main`) with verified, full 40-character commit SHAs across `.github/workflows/cicd.yaml`[cite: 58], `.github/workflows/securesdlc.yml`[cite: 59], and `.github/actions/base-setup/action.yaml`[cite: 60]. This strictly prevents unreviewed upstream action changes from entering the deployment pipeline[cite: 53]. * **Formatting Gate (False-Green Prevention):** The formatting job in `cicd.yaml` previously mutated files during checkout (e.g., `prettier --write`), which could hide formatting drift and silently pass the CI check[cite: 53]. It now runs `pnpm run format:js:check`, acting as a strict, read-only validation gate[cite: 53, 58]. * **Explicit Secret Boundaries:** Prevented overly broad secret exposure by explicitly declaring and passing only the necessary secrets (`SEMGREP_APP_URL`, `SEMGREP_APP_TOKEN`, `SDLC_SLACK_NOTIFICATIONS`) to the nested SecureSDLC workflow in `cicd.yaml` and `securesdlc.yml`[cite: 53, 58, 59]. --- .github/actions/base-setup/action.yaml | 62 +++++++++++++------------- .github/workflows/cicd.yaml | 41 +++++++++-------- .github/workflows/securesdlc.yml | 40 ++++++++--------- 3 files changed, 73 insertions(+), 70 deletions(-) diff --git a/.github/actions/base-setup/action.yaml b/.github/actions/base-setup/action.yaml index 89673ad3..7566e7f4 100644 --- a/.github/actions/base-setup/action.yaml +++ b/.github/actions/base-setup/action.yaml @@ -1,31 +1,31 @@ -name: 'Basic Setup' -description: 'Basic setup with pnpm and cache restore' -runs: - using: "composite" - steps: - - name: Setup pnpm - uses: pnpm/action-setup@v2 - with: - run_install: false - - - name: Setup Node 22 - uses: actions/setup-node@v4 - with: - node-version: "22.x" - cache: "pnpm" - - - name: Add pnpm store path to env var - id: pnpm-cache - shell: bash - run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - - - name: Restore Cache - uses: actions/cache@v4 - with: - path: | - ${{ steps.pnpm-cache.outputs.STORE_PATH }} - **/node_modules - key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-store- - +name: 'Basic Setup' +description: 'Basic setup with pnpm and cache restore' +runs: + using: "composite" + steps: + - name: Setup pnpm + uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 + with: + run_install: false + + - name: Setup Node 22 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 + with: + node-version: "22.x" + cache: "pnpm" + + - name: Add pnpm store path to env var + id: pnpm-cache + shell: bash + run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Restore Cache + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 + with: + path: | + ${{ steps.pnpm-cache.outputs.STORE_PATH }} + **/node_modules + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 682c06c2..49972149 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -7,19 +7,22 @@ on: jobs: securesdlc: - uses: inkonchain/.github/.github/workflows/securesdlc.yml@main - secrets: inherit + uses: inkonchain/.github/.github/workflows/securesdlc.yml@8f97e6fe4905543f2745778ab3e4783e1e34b389 + secrets: + SEMGREP_APP_URL: ${{ secrets.SEMGREP_APP_URL }} + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} + SDLC_SLACK_NOTIFICATIONS: ${{ secrets.SDLC_SLACK_NOTIFICATIONS }} install_modules: needs: securesdlc runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: volta-cli/action@v4 - - uses: pnpm/action-setup@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + - uses: volta-cli/action@5c175f92dea6f48441c436471e6479dbc192e194 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 with: run_install: false - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 with: node-version: "22.x" cache: "pnpm" @@ -30,7 +33,7 @@ jobs: shell: bash run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - name: Cache node modules - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 with: path: | ${{ steps.pnpm-cache.outputs.STORE_PATH }} @@ -43,7 +46,7 @@ jobs: needs: install_modules runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - uses: ./.github/actions/base-setup name: Base Setup - name: JS linting @@ -53,7 +56,7 @@ jobs: needs: install_modules runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - uses: ./.github/actions/base-setup name: Base Setup - name: MDX linting @@ -63,17 +66,17 @@ jobs: needs: install_modules runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - uses: ./.github/actions/base-setup name: Base Setup - - name: Run formatting - run: pnpm run format:js + - name: Check formatting + run: pnpm run format:js:check # spell-check: # needs: install_modules # runs-on: ubuntu-latest # steps: - # - uses: actions/checkout@v4 + # - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # - uses: ./.github/actions/base-setup # name: Base Setup # - name: Run Spellcheck @@ -83,13 +86,13 @@ jobs: needs: install_modules runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - uses: ./.github/actions/base-setup name: Base Setup - name: Building app run: pnpm run build - name: Cache build - uses: actions/cache/save@v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 with: path: .next key: ${{ runner.os }}-build-store-${{ hashFiles('.next') }} @@ -100,20 +103,20 @@ jobs: needs: build steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 with: context: . push: true diff --git a/.github/workflows/securesdlc.yml b/.github/workflows/securesdlc.yml index 319a8849..ebb8591a 100644 --- a/.github/workflows/securesdlc.yml +++ b/.github/workflows/securesdlc.yml @@ -1,20 +1,20 @@ -name: Nautilus SecureSDLC Reusable -run-name: "[Nautilus SecureSDLC Reusable] Ref:${{ github.ref_name }} Event:${{ github.event_name }}" - -on: - workflow_dispatch: {} - workflow_call: {} - push: - branches: [ main ] - -jobs: - securesdlc-umbrella: - permissions: - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/upload-sarif to upload SARIF results - actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status - uses: nautilus-wraith/securesdlc-umbrella/.github/workflows/securesdlc-umbrella.yml@release-stable - secrets: - SEMGREP_APP_URL: ${{ secrets.SEMGREP_APP_URL }} - SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} - SDLC_SLACK_NOTIFICATIONS: ${{ secrets.SDLC_SLACK_NOTIFICATIONS }} +name: Nautilus SecureSDLC Reusable +run-name: "[Nautilus SecureSDLC Reusable] Ref:${{ github.ref_name }} Event:${{ github.event_name }}" + +on: + workflow_dispatch: {} + workflow_call: {} + push: + branches: [ main ] + +jobs: + securesdlc-umbrella: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + uses: nautilus-wraith/securesdlc-umbrella/.github/workflows/securesdlc-umbrella.yml@d61b052e36d795bf5ed9eeb116b4851cc0bbdcdd + secrets: + SEMGREP_APP_URL: ${{ secrets.SEMGREP_APP_URL }} + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} + SDLC_SLACK_NOTIFICATIONS: ${{ secrets.SDLC_SLACK_NOTIFICATIONS }}