Skip to content

Commit 35b87da

Browse files
feat(zizmor): use shared-workflows reusable zizmor + grafana-bench; trufflehog tweaks
- self-zizmor: call reusable-zizmor.yml@feat/zizmor-grafana-bench (correct service/suite name) - TruffleHog: send-bench-metrics default false; example workflow uses dynamic service name - Remove grafana-bench-stack (metrics via CI only); other trufflehog docs/example additions Made-with: Cursor
1 parent 8bd71c0 commit 35b87da

6 files changed

Lines changed: 463 additions & 2 deletions

File tree

.github/workflows/reusable-trufflehog.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ jobs:
230230
echo "${FINDINGS}"
231231
echo ''
232232
echo "${ACTION_TEXT}"
233+
echo ''
234+
echo '---'
235+
echo ''
236+
echo '**Ignoring False Positives:**'
237+
echo 'To mark a false positive, add `# trufflehog:ignore` as an inline comment on the same line as the detected secret:'
238+
echo '```'
239+
echo 'my_fake_secret = "AKIAIOSFODNN7EXAMPLE" # trufflehog:ignore'
240+
echo '```'
241+
echo 'This works for files that support line numbers (most source files). After adding the comment, push your changes and the scan will re-run.'
233242
echo 'EOF'
234243
} >> "$GITHUB_OUTPUT"
235244
fi

.github/workflows/self-zizmor.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
fi
3333
echo "found-files=${FOUND_FILES}" >> $GITHUB_OUTPUT
3434
zizmor:
35-
name: Run zizmor from current branch (self test)
35+
name: Run zizmor
3636

3737
permissions:
3838
actions: read
@@ -45,10 +45,14 @@ jobs:
4545
- zizmor-check
4646
if: ${{ needs.zizmor-check.outputs.found-files == 'true' }}
4747

48-
uses: grafana/shared-workflows/.github/workflows/reusable-zizmor.yml@835ea6d866784d0db603612bfbb354d152b62f5c
48+
# Reusable workflow: zizmor + grafana-bench. Use ref with caller repo name for service/suite (fixes service=security).
49+
uses: grafana/shared-workflows/.github/workflows/reusable-zizmor.yml@feat/zizmor-grafana-bench
4950
with:
5051
runs-on: ${{ !github.event.repository.private && 'ubuntu-latest' || 'ubuntu-arm64-small' }}
5152
fail-severity: high
5253
min-severity: high
5354
min-confidence: low
5455
extra-args: --offline
56+
send-bench-metrics: true
57+
# Grafana Bench: pass PROMETHEUS_URL (and optionally PROMETHEUS_USER, PROMETHEUS_PASSWORD) for metrics; GAR access for Docker image.
58+
secrets: inherit
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Test TruffleHog Ignore
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- add-trufflehog-ignore-docs
8+
9+
jobs:
10+
test-trufflehog:
11+
uses: ./.github/workflows/reusable-trufflehog.yml
12+
with:
13+
fail-on-verified: "false"
14+
fail-on-unverified: "false"

test-trufflehog-ignore.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Test file for TruffleHog ignore functionality.
4+
5+
This file contains fake secrets to test the # trufflehog:ignore comment feature.
6+
"""
7+
8+
# This should be detected (no ignore comment)
9+
fake_aws_key = "AKIAIOSFODNN7EXAMPLE"
10+
11+
# This should be ignored (has trufflehog:ignore comment)
12+
fake_github_token = "ghp_1234567890abcdefghijklmnopqrstuvwxyz" # trufflehog:ignore
13+
14+
# Another test case - this should be detected
15+
test_secret = "sk_test_1234567890abcdefghijklmnopqrstuvwxyz"
16+
17+
# This should be ignored
18+
another_fake = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" # trufflehog:ignore

trufflehog/GRAFANA_SETUP.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Grafana Setup Guide for TruffleHog Integration
2+
3+
**Zizmor + Grafana Bench (see metrics in one go):** Use the [grafana-bench-stack](../../grafana-bench-stack/README.md) in this repo: `cd grafana-bench-stack && docker compose up -d`, then set `PROMETHEUS_PUSHGATEWAY_URL` and open the **Zizmor (Grafana Bench)** dashboard in Grafana.
4+
5+
## Quick Setup Options
6+
7+
### Option 1: Grafana Cloud (Recommended for Testing - Fastest)
8+
9+
1. **Sign up for Grafana Cloud** (free tier available)
10+
- Go to https://grafana.com/auth/sign-up/create-user
11+
- Create a free account (no credit card required for free tier)
12+
13+
2. **Get your Loki credentials:**
14+
- Go to https://grafana.com/orgs/YOUR_ORG/connections/loki
15+
- Click "Send logs" → "Push logs"
16+
- Copy:
17+
- **LOKI_URL**: `https://logs-prod-XXX.grafana.net/loki/api/v1/push`
18+
- **LOKI_USERNAME**: Your Grafana Cloud username (usually an ID like `123456`)
19+
- **LOKI_PASSWORD**: Your API token (create one at https://grafana.com/orgs/YOUR_ORG/api-keys)
20+
21+
3. **Get your Prometheus Pushgateway:**
22+
- Go to https://grafana.com/orgs/YOUR_ORG/connections/prometheus
23+
- Click "Send metrics" → "Remote write"
24+
- You'll need to set up a Prometheus instance or use a remote write endpoint
25+
- **Alternative**: Use a standalone Prometheus Pushgateway (see Option 2)
26+
27+
### Option 2: Local Docker Setup (For Testing)
28+
29+
Run these commands to set up local instances:
30+
31+
```bash
32+
# Start Loki
33+
docker run -d --name loki -p 3100:3100 grafana/loki:latest
34+
35+
# Start Prometheus Pushgateway
36+
docker run -d --name pushgateway -p 9091:9091 prom/pushgateway:latest
37+
38+
# Start Grafana (optional, for visualization)
39+
docker run -d --name grafana -p 3000:3000 grafana/grafana:latest
40+
```
41+
42+
Then use:
43+
- **LOKI_URL**: `http://localhost:3100` (or your server IP)
44+
- **PROMETHEUS_PUSHGATEWAY_URL**: `http://localhost:9091` (or your server IP)
45+
46+
**Note**: For GitHub Actions to reach these, you'll need to expose them publicly (use ngrok, or deploy to a cloud server).
47+
48+
### Option 3: Use Existing Grafana Instance
49+
50+
If you already have Grafana/Loki/Prometheus:
51+
- **LOKI_URL**: Your Loki instance URL (e.g., `https://loki.yourcompany.com`)
52+
- **LOKI_USERNAME**: Your Loki username (if auth required)
53+
- **LOKI_PASSWORD**: Your Loki password/token
54+
- **PROMETHEUS_PUSHGATEWAY_URL**: Your Pushgateway URL (e.g., `https://pushgateway.yourcompany.com`)
55+
56+
## Adding Secrets to GitHub
57+
58+
### For Testing (Repository Secrets - Quickest)
59+
60+
1. Go to your repository: `https://github.com/YOUR_ORG/security-github-actions`
61+
2. Click **Settings****Secrets and variables****Actions**
62+
3. Click **New repository secret**
63+
4. Add these secrets:
64+
65+
- **Name**: `LOKI_URL`
66+
**Value**: Your Loki URL (e.g., `https://logs-prod-XXX.grafana.net/loki/api/v1/push`)
67+
68+
- **Name**: `LOKI_USERNAME`
69+
**Value**: Your Loki username (Grafana Cloud user ID)
70+
71+
- **Name**: `LOKI_PASSWORD`
72+
**Value**: Your Loki API token/password
73+
74+
- **Name**: `PROMETHEUS_PUSHGATEWAY_URL`
75+
**Value**: Your Pushgateway URL (e.g., `http://localhost:9091` or your cloud URL)
76+
77+
### For Production (Organization Secrets - Recommended)
78+
79+
1. Go to your organization: `https://github.com/organizations/YOUR_ORG/settings/secrets/actions`
80+
2. Click **New organization secret**
81+
3. Add the same secrets as above
82+
83+
## Setting Up Grafana Dashboards
84+
85+
### 1. Add Data Sources
86+
87+
#### Add Loki Data Source:
88+
1. In Grafana, go to **Configuration****Data sources**
89+
2. Click **Add data source** → Select **Loki**
90+
3. Enter your Loki URL
91+
4. If using Grafana Cloud, use the credentials from step 2 above
92+
5. Click **Save & test**
93+
94+
#### Add Prometheus Data Source:
95+
1. Go to **Configuration****Data sources**
96+
2. Click **Add data source** → Select **Prometheus**
97+
3. Enter your Prometheus URL (the one scraping the Pushgateway)
98+
4. Click **Save & test**
99+
100+
### 2. Create Dashboard
101+
102+
1. Go to **Dashboards****New****New dashboard**
103+
2. Click **Add visualization**
104+
105+
#### Panel 1: Total Secrets Over Time (Prometheus)
106+
- **Data source**: Prometheus
107+
- **Query**:
108+
```promql
109+
sum(trufflehog_secrets_total) by (repository)
110+
```
111+
- **Visualization**: Time series
112+
- **Title**: "Total Secrets Found by Repository"
113+
114+
#### Panel 2: Verified vs Unverified (Prometheus)
115+
- **Data source**: Prometheus
116+
- **Query A**:
117+
```promql
118+
sum(trufflehog_secrets_verified) by (repository)
119+
```
120+
- **Query B**:
121+
```promql
122+
sum(trufflehog_secrets_unverified) by (repository)
123+
```
124+
- **Visualization**: Time series
125+
- **Title**: "Verified vs Unverified Secrets"
126+
127+
#### Panel 3: Secrets by Detector Type (Prometheus)
128+
- **Data source**: Prometheus
129+
- **Query**:
130+
```promql
131+
sum(trufflehog_secrets_by_detector_*) by (detector)
132+
```
133+
- **Visualization**: Bar chart or Pie chart
134+
- **Title**: "Secrets by Detector Type"
135+
136+
#### Panel 4: Recent Findings Table (Loki)
137+
- **Data source**: Loki
138+
- **Query**:
139+
```logql
140+
{job="trufflehog"}
141+
```
142+
- **Visualization**: Table or Logs
143+
- **Title**: "Recent Secret Findings"
144+
145+
#### Panel 5: Findings Count Over Time (Loki)
146+
- **Data source**: Loki
147+
- **Query**:
148+
```logql
149+
count_over_time({job="trufflehog"}[1h])
150+
```
151+
- **Visualization**: Time series
152+
- **Title**: "Findings Count (Last Hour)"
153+
154+
### 3. Useful Loki Queries for Filtering
155+
156+
**Verified secrets only:**
157+
```logql
158+
{job="trufflehog", verified="true"}
159+
```
160+
161+
**By specific repository:**
162+
```logql
163+
{job="trufflehog", repository="your-repo-name"}
164+
```
165+
166+
**By detector type:**
167+
```logql
168+
{job="trufflehog", detector="aws"}
169+
```
170+
171+
**Combined filter:**
172+
```logql
173+
{job="trufflehog", verified="true", repository="your-repo-name"}
174+
```
175+
176+
## Testing the Integration
177+
178+
1. **Trigger a workflow** that uses the TruffleHog reusable workflow
179+
2. **Check workflow logs** for:
180+
- "✅ Successfully sent X findings to Loki"
181+
- "✅ Successfully sent X metrics to Prometheus"
182+
3. **Check Grafana**:
183+
- Loki: Query `{job="trufflehog"}` - you should see log entries
184+
- Prometheus: Query `trufflehog_secrets_total` - you should see metrics
185+
186+
## Troubleshooting
187+
188+
### No data appearing in Grafana
189+
190+
1. **Check GitHub Actions logs:**
191+
- Look for errors in the "Send findings to Loki" or "Send metrics to Prometheus" steps
192+
- Verify secrets are set correctly
193+
194+
2. **Verify URLs are accessible:**
195+
- Test Loki URL: `curl -u USERNAME:PASSWORD https://your-loki-url/ready`
196+
- Test Pushgateway: `curl http://your-pushgateway-url/metrics`
197+
198+
3. **Check Prometheus is scraping Pushgateway:**
199+
- If using Prometheus, ensure it's configured to scrape the Pushgateway
200+
- Check Prometheus targets page
201+
202+
4. **Verify data format:**
203+
- Check Loki logs: Query `{job="trufflehog"}` should return entries
204+
- Check Prometheus metrics: Query `trufflehog_secrets_total` should return values
205+
206+
### Common Issues
207+
208+
- **401 Unauthorized**: Check LOKI_USERNAME and LOKI_PASSWORD are correct
209+
- **Connection refused**: Verify URLs are correct and accessible from GitHub Actions runners
210+
- **No metrics in Prometheus**: Ensure Prometheus is scraping the Pushgateway endpoint
211+
212+
## Quick Test Script
213+
214+
You can test the scripts locally:
215+
216+
```bash
217+
# Set environment variables
218+
export LOKI_URL="https://your-loki-url"
219+
export LOKI_USERNAME="your-username"
220+
export LOKI_PASSWORD="your-password"
221+
export REPOSITORY="test/repo"
222+
export COMMIT_SHA="abc123"
223+
export BRANCH="main"
224+
export TRUFFLEHOG_RESULTS_FILE="results.json"
225+
226+
# Create a test results.json
227+
echo '[{"DetectorName": "AWS", "Verified": true, "SourceMetadata": {"Data": {"Filesystem": {"file": "test.txt", "line": 1}}}, "Redacted": "test"}]' > results.json
228+
229+
# Test Loki script
230+
python trufflehog/send-to-loki.py
231+
232+
# Test Prometheus script
233+
export PROMETHEUS_PUSHGATEWAY_URL="http://your-pushgateway-url"
234+
python trufflehog/send-to-prometheus.py
235+
```

0 commit comments

Comments
 (0)