diff --git a/gitleaks/README.md b/gitleaks/README.md deleted file mode 100644 index c78fad7..0000000 --- a/gitleaks/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# 🕵️ Gitleaks GitHub Action - -## 📌 Purpose - -GitHub Action for automatic secret scanning in code using [Gitleaks](https://github.com/gitleaks/gitleaks). Prevents leakage of tokens, keys, passwords, and other secrets into the repository. - -## ⚙️ Operation Modes - -### Diff scan (primary mode) -- **Automatically integrated** into general PR validation -- Scans **only changed files** and **only added lines** in PR -- Does not analyze commit history — eliminates false positives -- Does not check unchanged files — focuses on new code -- Uses `--no-git` for fast scanning - -### Full scan (additional mode) -- Runs on schedule or manually -- Scans the entire repository -- Suitable for periodic security audits - -## 🚀 Usage - -### Automatic Integration - -Diff scan is already integrated into general PR validation and works automatically. No additional configuration required. - -### Full Scanning (optional) - -If you need full scan, add to `.github/workflows/security-scan.yml`: - -```yaml -name: Security Scan - -on: - schedule: - - cron: "0 2 * * *" # daily at 02:00 UTC - workflow_dispatch: {} # manual trigger - -permissions: - contents: read - -jobs: - gitleaks-full: - runs-on: ubuntu-latest - steps: - - uses: deckhouse/modules-actions/gitleaks@main - with: - scan_mode: full -``` - -### Configuration (optional) - -To configure scanning rules, create `gitleaks.toml` in the repository root: -📎 - -Without config, built-in Gitleaks rules are used. - -## 📝 Parameters - -| Parameter | Description | Default | -|-----------|-------------|---------| -| `scan_mode` | Mode: `diff` or `full` | `full` | -| `gitleaks_version` | Gitleaks version | `v8.28.0` | -| `checkout_repo` | Repository for checkout | `${{ github.repository }}` | -| `checkout_ref` | SHA for checkout | `""` | -| `base_sha` | Base SHA for diff | `""` | - -## 🔧 Technical Features - -### Patch-based scanning (diff mode) -- Collects only changed files from PR -- Creates temporary tree with these files -- Scans without git history (`--no-git`) -- Filters findings only by added lines - -### Benefits -- **Minimal false positives** — doesn't find deleted secrets -- **Fast operation** — scans only changes -- **Accuracy** — focuses on new code in PR - -## 🐛 Troubleshooting - -**Many false positives**: use `diff` mode for PR checks -**Workflow fails**: check `contents: read` permissions -**Need configuration**: create `gitleaks.toml` in repository root diff --git a/gitleaks/action.yml b/gitleaks/action.yml index 2dff017..3b8d0c9 100644 --- a/gitleaks/action.yml +++ b/gitleaks/action.yml @@ -51,17 +51,42 @@ runs: echo "$install_dir" >> "$GITHUB_PATH" gitleaks version + - name: Setup centralized config + shell: bash + run: | + set -euo pipefail + # Copy centralized config to temporary directory (safe for Werf/giterminism) + BASE_CONFIG="${{ github.action_path }}/config/gitleaks.base.toml" + if [[ -f "$BASE_CONFIG" ]]; then + cp "$BASE_CONFIG" "${RUNNER_TEMP}/gitleaks.base.toml" + echo "✅ Centralized config copied to ${RUNNER_TEMP}/gitleaks.base.toml" + else + echo "⚠️ Warning: Centralized config not found at $BASE_CONFIG" + exit 1 + fi + - name: Check for optional config id: config shell: bash run: | set -euo pipefail - if [[ -f "gitleaks.toml" ]]; then - echo "config_arg=-c gitleaks.toml" >> "$GITHUB_OUTPUT" - echo "✅ Found config: gitleaks.toml" + if [[ -f ".gitleaks.toml" ]]; then + # Local config exists - check if it has [extend] section + if grep -q "^\[extend\]" .gitleaks.toml; then + # Has extend section - use as is + echo "config_arg=--config .gitleaks.toml" >> "$GITHUB_OUTPUT" + echo "✅ Found local config with [extend] section - using as is" + else + # No extend section - warn and ignore, use base config only + echo "⚠️ WARNING: Local config file .gitleaks.toml exists but does not contain [extend] section" + echo " We cannot be sure this is the expected extend configuration." + echo " Ignoring local config file and using base config only." + echo "config_arg=--config ${RUNNER_TEMP}/gitleaks.base.toml" >> "$GITHUB_OUTPUT" + fi else - echo "config_arg=" >> "$GITHUB_OUTPUT" - echo "⚠️ Config file not found. Proceeding with default rules." + # Use centralized config only + echo "config_arg=--config ${RUNNER_TEMP}/gitleaks.base.toml" >> "$GITHUB_OUTPUT" + echo "🔹 Using centralized config only (no local customization)" fi - name: Gitleaks scan (full) @@ -70,7 +95,7 @@ runs: run: | set -euo pipefail CONFIG_ARG="${{ steps.config.outputs.config_arg }}" - gitleaks detect --no-banner --redact \ + gitleaks detect --no-banner --redact --log-level debug \ --report-format json --report-path gitleaks.json \ $CONFIG_ARG \ --source . @@ -86,7 +111,7 @@ runs: echo "Base commit: $BASE_COMMIT" echo "Scanning range: ${BASE_COMMIT}..HEAD" - gitleaks detect --no-banner --redact \ + gitleaks detect --no-banner --redact --log-level debug \ --report-format json --report-path gitleaks.json \ --log-opts="${BASE_COMMIT}..HEAD" \ $CONFIG_ARG \ diff --git a/gitleaks/config/gitleaks.base.toml b/gitleaks/config/gitleaks.base.toml new file mode 100644 index 0000000..7e07054 --- /dev/null +++ b/gitleaks/config/gitleaks.base.toml @@ -0,0 +1,57 @@ +# Centralized Gitleaks configuration for all Deckhouse repositories +# This file is distributed via modules-actions/gitleaks action +# +# Repositories can extend this config by creating local .gitleaks.toml: +# [extend] +# useDefault = false +# path = "/home/runner/work/_temp/gitleaks.base.toml" + +# Use default Gitleaks rules +[extend] +useDefault = true + +# Global allowlists +[allowlist] + +# === Safe files/directories === +# NOTE: Use exact paths, NOT glob patterns like **/go.mod + +paths = [ + # Go dependencies - public hashes + "go.mod", + "go.sum", + + # Specific files with known false positives + # "modules/101-cert-manager/docs/USAGE.md", + # "modules/101-cert-manager/docs/USAGE_RU.md", +] + +# === Safe patterns === +regexes = [ + # Go module checksums - always public + '''h1:[A-Za-z0-9+/=]{40,}''', + + # Public certificates (only ca.crt, NOT private keys!) + '''data:\s*\n\s*ca\.crt:\s*[A-Za-z0-9+/=\s]+''', + + # AWS Example values from official documentation - exact match + '''AKIAIOSFODNN7EXAMPLE''', + '''wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY''', +] + +# Custom rules for hashi/openbao/werf tokens +[[rules]] +id = "werf-secret-key" +description = "Identified a Werf Secret Key." +regex = '''\b([a-f0-9]{32})\b''' +path = '''\.werf_secret_key$''' + +[[rules]] +id = "hashicorp-vault-token" +description = "Identified a HashiCorp Vault token (hvs, hvb, or hvr prefix)." +regex = '''\b(hv[sbr]\.[A-Za-z0-9_-]{20,})\b''' + +[[rules]] +id = "openbao-token" +description = "Identified an OpenBao token (S. prefix)." +regex = '''\b(S\.[A-Za-z0-9_-]{20,})\b'''