diff --git a/.github/workflows/leaked-secrets-scan.yml b/.github/workflows/leaked-secrets-scan.yml index c3b47de..68f4ac2 100644 --- a/.github/workflows/leaked-secrets-scan.yml +++ b/.github/workflows/leaked-secrets-scan.yml @@ -1,9 +1,8 @@ name: Leaked Secrets Scan on: - workflow_call: schedule: - - cron: '0 3 * * *' # Daily at 3 AM UTC (3-4 AM UK time) + - cron: '0 3 * * *' workflow_dispatch: push: branches: [main] @@ -11,27 +10,17 @@ on: branches: [main] jobs: - secrets-scan: + detect-secrets: runs-on: ubuntu-latest - name: ${{ github.event_name == 'schedule' && 'Scheduled Secrets Scan' || 'Secrets Scan' }} - + continue-on-error: true + name: detect-secrets steps: - name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: '3.12' - cache: 'pip' - - name: Install detect-secrets - run: | - python -m pip install --upgrade pip - pip install detect-secrets - + run: pipx install detect-secrets - name: Verify baseline exists run: | if [ ! -f .secrets.baseline ]; then @@ -39,7 +28,6 @@ jobs: exit 1 fi echo "Found .secrets.baseline" - - name: Scan for secrets run: | echo "Scanning for secrets..." @@ -47,7 +35,6 @@ jobs: --baseline .secrets.baseline \ --exclude-files '.*\.lock$' \ --force-use-all-plugins - - name: Audit baseline for unaudited secrets run: | echo "Auditing secrets baseline..." @@ -58,7 +45,6 @@ jobs: fi echo "All secrets in baseline have been audited" detect-secrets audit .secrets.baseline --report - - name: Check for new secrets in PR if: github.event_name == 'pull_request' run: | @@ -70,7 +56,6 @@ jobs: cp "$file" "/tmp/pr-scan/$file" 2>/dev/null || true fi done - if [ "$(ls -A /tmp/pr-scan 2>/dev/null)" ]; then echo "Scanning changed files..." detect-secrets scan \ @@ -81,7 +66,6 @@ jobs: else echo "No files to scan" fi - - name: Full repository scan (scheduled) if: github.event_name == 'schedule' run: | @@ -89,11 +73,60 @@ jobs: detect-secrets scan \ --exclude-files '.*\.lock$' \ --force-use-all-plugins - - name: Upload baseline on failure uses: actions/upload-artifact@v7 if: failure() with: - name: secrets-scan-results + name: detect-secrets-report path: .secrets.baseline retention-days: 30 + + gitleaks-cli: + name: gitleaks (CLI) + runs-on: ubuntu-latest + continue-on-error: true + env: + GITLEAKS_VERSION: '8.30.0' + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Install gitleaks + run: | + curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \ + | tar -xz -C /usr/local/bin gitleaks + gitleaks version + - name: Run gitleaks + run: gitleaks detect --source . --redact -c .gitleaks.toml -v --report-format sarif --report-path gitleaks-report.sarif + - name: Upload report + uses: actions/upload-artifact@v7 + if: always() + with: + name: gitleaks-report + path: gitleaks-report.sarif + retention-days: 30 + + trufflehog: + name: trufflehog + runs-on: ubuntu-latest + continue-on-error: true + env: + TRUFFLEHOG_VERSION: '3.93.8' + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Install trufflehog + run: | + curl -sSfL "https://github.com/trufflesecurity/trufflehog/releases/download/v${TRUFFLEHOG_VERSION}/trufflehog_${TRUFFLEHOG_VERSION}_linux_amd64.tar.gz" \ + | tar -xz -C /usr/local/bin trufflehog + trufflehog --version + - name: Run trufflehog + run: trufflehog git file://. --only-verified --fail --json 2>&1 | tee trufflehog-report.json + - name: Upload report + uses: actions/upload-artifact@v7 + if: always() + with: + name: trufflehog-report + path: trufflehog-report.json + retention-days: 30 diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..692ea2a --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,6 @@ +[allowlist] + paths = [ + '''docs/''', + '''claude-code/''', + '''k8s/secret\.example\.yaml''', + ] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6fb5a36..01ecd3c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,3 +13,15 @@ repos: hooks: - id: detect-secrets args: ['--baseline', '.secrets.baseline', '--exclude-files', '.*\.lock$'] + + - repo: https://github.com/gitleaks/gitleaks + rev: v8.30.0 + hooks: + - id: gitleaks + stages: [pre-push] + + - repo: https://github.com/trufflesecurity/trufflehog + rev: v3.93.8 + hooks: + - id: trufflehog + stages: [pre-push] diff --git a/lefthook.yml b/lefthook.yml index 884994d..4e87f05 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -26,3 +26,7 @@ pre-push: format-check: root: webui/ run: npm run format:check + gitleaks: + run: gitleaks protect --staged --redact + trufflehog: + run: trufflehog git file://. --only-verified