From 75e49033b0af0e43fec0b008a29abf661f8b4381 Mon Sep 17 00:00:00 2001 From: miyadav Date: Thu, 26 Mar 2026 12:07:08 +0000 Subject: [PATCH 1/2] Add secret scan for pull requests --- .github/SECRET_SCANNING.md | 171 ++++++++++++++++++++++++++++++ .github/workflows/secret-scan.yml | 42 ++++++++ .gitleaks.toml | 67 ++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 .github/SECRET_SCANNING.md create mode 100644 .github/workflows/secret-scan.yml create mode 100644 .gitleaks.toml diff --git a/.github/SECRET_SCANNING.md b/.github/SECRET_SCANNING.md new file mode 100644 index 000000000000..49d00892a562 --- /dev/null +++ b/.github/SECRET_SCANNING.md @@ -0,0 +1,171 @@ +# Secret Scanning with Gitleaks + +This repository uses [Gitleaks](https://github.com/gitleaks/gitleaks) to prevent secrets (API keys, passwords, private keys, tokens) from being committed to the codebase. + +## How It Works + +### Automated CI Scanning +- **Runs on:** All pull requests and pushes to `main` and `release-*` branches +- **What it scans:** Only new commits in your PR (not the entire git history) +- **Speed:** ~4 mins for full repository scan +- **Action:** Blocks PR merge if secrets are detected + +### What Gitleaks Detects +- API keys (AWS, GitHub, GitLab, Slack, etc.) +- Private keys (RSA, SSH, PGP, TLS) +- Database credentials and connection strings +- OAuth and JWT tokens +- Generic secrets (password=, api_key=, etc.) +- High entropy strings (randomized secrets) + +### What It Ignores +- Test fixtures in `test/` directories +- Vendor code in `vendor/` +- Example files in `examples/` +- Mock/placeholder credentials +- Variable names like `password` or `apiKey` + +## Running Locally + +### Installation + +**macOS (Homebrew):** +```bash +brew install gitleaks +``` + +**Linux:** +```bash +# Docker/Podman +docker pull ghcr.io/gitleaks/gitleaks:latest + +# Or download binary +wget https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_linux_x64.tar.gz +tar -xzf gitleaks_linux_x64.tar.gz +sudo mv gitleaks /usr/local/bin/ +``` + +### Scan Before Committing + +**Scan staged changes (recommended):** +```bash +gitleaks protect --staged --verbose +``` + +**Scan entire working directory:** +```bash +gitleaks detect --source . --config .gitleaks.toml --verbose +``` + +**Scan specific file:** +```bash +gitleaks detect --source path/to/file.go --no-git +``` + +## Handling Detections + +### If Gitleaks Flags Your Commit + +**1. Is it a real secret?** + +If YES: +- **Remove the secret immediately** +- Use environment variables instead: `os.Getenv("API_KEY")` +- Store secrets in Kubernetes Secrets, Vault, or similar +- Rotate/revoke the exposed secret if it was already pushed + +If NO (false positive): +- Continue to step 2 + +**2. For legitimate test fixtures or examples:** + +Add to `.gitleaks.toml` allowlist: + +```toml +[allowlist] +paths = [ + '''path/to/test/file\.go$''', +] + +# OR for specific values +regexes = [ + '''specific-test-value-to-ignore''', +] +``` + +**3. For one-time overrides (use sparingly):** + +Add inline comment in your code: +```go +password := "test-password" // gitleaks:allow +``` + +## Configuration + +The `.gitleaks.toml` file controls what gets scanned and ignored: + +- **Excluded paths:** `test/`, `vendor/`, `examples/`, `*.md` +- **Excluded patterns:** Test credentials, base64 test values, common examples +- **Rules:** Extends default gitleaks ruleset + +To modify exclusions, edit `.gitleaks.toml` and test: +```bash +gitleaks detect --source . --config .gitleaks.toml --verbose +``` + +## Best Practices + +### DO: +- ✅ Use environment variables for secrets +- ✅ Use Kubernetes Secrets or external secret management +- ✅ Run `gitleaks protect --staged` before committing sensitive changes +- ✅ Use placeholder values in examples: `YOUR_API_KEY_HERE` + +### DON'T: +- ❌ Commit real credentials, even temporarily +- ❌ Use `--no-verify` to bypass the check +- ❌ Add broad exclusions to `.gitleaks.toml` without review +- ❌ Assume deleted secrets are safe (git history remembers) + +## Troubleshooting + +### CI fails but local scan passes +```bash +# Ensure you're using the config file +gitleaks detect --source . --config .gitleaks.toml --no-git + +# Check which gitleaks version CI uses +grep 'gitleaks-action@' .github/workflows/secret-scan.yml +``` + +### Too many false positives +1. Review the findings carefully +2. Update `.gitleaks.toml` with specific exclusions +3. Test the config change locally +4. Submit the config update in your PR + +### Need to scan git history +```bash +# Scan all commits (WARNING: can be slow on large repos) +gitleaks detect --source . --verbose + +# Scan specific commit range +gitleaks detect --log-opts="main..HEAD" +``` + +## Additional Resources + +- [Gitleaks Documentation](https://github.com/gitleaks/gitleaks) +- [Gitleaks Configuration Reference](https://github.com/gitleaks/gitleaks#configuration) +- [GitHub Secret Scanning](https://docs.github.com/en/code-security/secret-scanning) + +## Questions? + +For issues with secret scanning: +1. Check this guide first +2. Review `.gitleaks.toml` configuration +3. Ask in your PR or open an issue + +--- + +**Remember:** It's easier to prevent secrets from being committed than to clean them up from git history! diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml new file mode 100644 index 000000000000..8ec0abe20ed3 --- /dev/null +++ b/.github/workflows/secret-scan.yml @@ -0,0 +1,42 @@ +name: Secret Scan + +# Prevents secrets (API keys, passwords, tokens) from being committed. +# For setup and troubleshooting, see: .github/SECRET_SCANNING.md +# To run locally: gitleaks protect --staged --verbose + +on: + pull_request: + branches: + - main + - 'release-*' + push: + branches: + - main + +permissions: + contents: read + pull-requests: write + +jobs: + gitleaks: + name: Scan for secrets + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history for comprehensive scanning + + - name: Run Gitleaks + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # Optional: for Gitleaks Pro features + GITLEAKS_ENABLE_COMMENTS: true + + - name: Upload SARIF report + if: failure() + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif + category: gitleaks diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 000000000000..2c78a71d67c7 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,67 @@ +# Gitleaks configuration for OpenShift Origin +# This config excludes common false positives while catching real secrets +# +# To test this config locally: +# gitleaks detect --source . --config .gitleaks.toml --verbose +# +# For full documentation, see: .github/SECRET_SCANNING.md + +title = "gitleaks config for openshift/origin" + +# Extend the default gitleaks config +[extend] +useDefault = true + +[allowlist] +description = "Allowlist for test fixtures, examples, and vendor code" + +# Paths to exclude from scanning +paths = [ + # Test directories and files + '''test/''', + '''.*_test\.go$''', + '''testdata/''', + + # Vendor dependencies + '''vendor/''', + + # Examples and demo files + '''examples/''', + + # Generated binary data files + '''bindata\.go$''', + + # Lock files and checksums + '''go\.sum$''', + '''package-lock\.json$''', + '''yarn\.lock$''', + + # Documentation + '''\.md$''', +] + +# Specific regexes to exclude (for base64 encoded test values, etc.) +regexes = [ + # Base64 encoded placeholder values commonly used in tests + '''c2VjcmV0dmFsdWU=''', # "secretvalue" in base64 + '''bXktc2VjcmV0LXZhbHVl''', # "my-secret-value" in base64 + '''cGFzc3dvcmQ=''', # "password" in base64 + + # Common test/example credentials + '''admin:admin''', + '''system:admin''', + '''secretvalue1''', + + # Grafana default example secret + '''SW2YcwTIb9zpOOhoPsMm''', +] + +# Stopwords - tokens that if found in the match will cause it to be ignored +stopwords = [ + # Common variable names and placeholders + '''YOUR_API_KEY''', + '''REPLACE_ME''', + '''CHANGEME''', + '''example\.com''', + '''localhost''', +] From 7e1a55139ee0a5f5bde639ecb5a46abb29aa83dd Mon Sep 17 00:00:00 2001 From: miyadav Date: Thu, 26 Mar 2026 13:57:42 +0000 Subject: [PATCH 2/2] run only for new commits --- .github/SECRET_SCANNING.md | 2 +- .github/workflows/secret-scan.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/SECRET_SCANNING.md b/.github/SECRET_SCANNING.md index 49d00892a562..878ddce56051 100644 --- a/.github/SECRET_SCANNING.md +++ b/.github/SECRET_SCANNING.md @@ -6,7 +6,7 @@ This repository uses [Gitleaks](https://github.com/gitleaks/gitleaks) to prevent ### Automated CI Scanning - **Runs on:** All pull requests and pushes to `main` and `release-*` branches -- **What it scans:** Only new commits in your PR (not the entire git history) +- **What it scans:** Only new commits in your PR via `gitleaks-action@v2` with `GITLEAKS_ARGS: --log-opts="main..HEAD"` (not the entire git history despite `fetch-depth: 0`) - **Speed:** ~4 mins for full repository scan - **Action:** Blocks PR merge if secrets are detected diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index 8ec0abe20ed3..012f628efbb9 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -33,6 +33,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # Optional: for Gitleaks Pro features GITLEAKS_ENABLE_COMMENTS: true + GITLEAKS_ARGS: --log-opts="main..HEAD" # Scan only PR commits, not full history - name: Upload SARIF report if: failure()