diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 272e830b6..3830d8233 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,7 @@ # CI — runs on every pull request to develop / release / master. # -# Two parallel jobs: +# Three parallel jobs: +# gitleaks — full-history secret scan with an exact false-positive baseline # frontend — TypeScript typecheck + ESLint + Vitest unit tests # rust — advisory clippy (subsumes cargo check) # @@ -22,7 +23,31 @@ concurrency: group: ci-pr-${{ github.event.pull_request.number }} cancel-in-progress: true +permissions: + contents: read + jobs: + # ── Secret scan ──────────────────────────────────────────────────────────── + gitleaks: + name: Gitleaks secret scan + runs-on: ubuntu-latest + + steps: + - name: Checkout (full history) + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Scan git history for secrets + run: > + docker run --rm + -v "$PWD:/repo" + -e GIT_CONFIG_COUNT=1 + -e GIT_CONFIG_KEY_0=safe.directory + -e GIT_CONFIG_VALUE_0=/repo + ghcr.io/gitleaks/gitleaks:v8.24.3 + git /repo --log-opts=HEAD --no-banner --redact --verbose + # ── Frontend ──────────────────────────────────────────────────────────────── frontend: name: Frontend (typecheck · lint · test) diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 000000000..615b38f13 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,22 @@ +dd44f3f6d1c53e79f35d41a28a70b705bc6303f2:src/modules/MainApp/WorkManagement/GitHubWorkItemControls.test.ts:generic-api-key:143 +20188795d87462d447c5c677465be88b890eb3b8:src/modules/MainApp/WorkManagement/GitHubWorkItemControls.test.ts:generic-api-key:142 +ba03bb3e7af65c6e927169e8db506fe475757107:src/features/Org2Cloud/org2CloudOrgManagement.test.ts:generic-api-key:111 +ba03bb3e7af65c6e927169e8db506fe475757107:src/features/Org2Cloud/config.ts:generic-api-key:23 +ba03bb3e7af65c6e927169e8db506fe475757107:src/features/Org2Cloud/org2CloudOrgManagement.ts:generic-api-key:292 +037fcc33ba137f25fdde39157d58e8d58ffb5883:src/util/secretScan/__tests__/secretScan.test.ts:github-pat:35 +037fcc33ba137f25fdde39157d58e8d58ffb5883:src/util/secretScan/__tests__/secretScan.test.ts:aws-access-token:29 +29e38e24506c2ec97996116790e54e625a5ed9dd:src-tauri/crates/orgtrack-core/src/sources/claude_code/history_tests.rs:generic-api-key:148 +04e8a6f7be13509d72f8cfd72715cd638f855322:src/config/serviceAuth.ts:generic-api-key:23 +0db3e31054248976ae2b13f0273a8e779a533e0d:src-tauri/crates/orgtrack-sync/src/redaction.rs:aws-access-token:142 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/browser/src/scripts/shortcut_forwarding.rs:generic-api-key:20 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/auto_detect/codex.rs:generic-api-key:348 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/auto_detect/codex.rs:generic-api-key:379 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/auto_detect/codex.rs:generic-api-key:439 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/snapshots/key_vault__key_extractor__tests__claude_hongmacode.snap:generic-api-key:5 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/tests/snapshots/key_vault__key_extractor__tests__key_adjacent_chinese.snap:generic-api-key:5 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/snapshots/key_vault__key_extractor__tests__key_adjacent_chinese.snap:generic-api-key:5 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/crates/key-vault/src/tests/snapshots/key_vault__key_extractor__tests__claude_hongmacode.snap:generic-api-key:5 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src-tauri/Cargo.lock:generic-api-key:8420 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src/config/keyboard/shortcuts/globalShortcuts.ts:generic-api-key:127 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src/config/keyboard/shortcuts/globalShortcuts.ts:generic-api-key:128 +3b1f59fce6d7b7f875f7c9b8c7cbcf9ab8e6cf0c:src/engines/SessionCore/sync/utils/activityIds.ts:generic-api-key:9