Skip to content

Commit aac4d10

Browse files
Add advisory TruffleHog org scan workflow (github source)
Made-with: Cursor
1 parent edaaa2b commit aac4d10

2 files changed

Lines changed: 148 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Org-wide secret scan using TruffleHog's built-in GitHub source.
2+
# See: https://github.com/trufflesecurity/trufflehog — `trufflehog github --org=…`
3+
#
4+
# Test now: Actions → this workflow → Run workflow.
5+
# Smoke test: set `single_repo` to one HTTPS URL and leave org as default.
6+
7+
name: TruffleHog org scan (GitHub)
8+
9+
on:
10+
workflow_dispatch:
11+
inputs:
12+
org:
13+
description: "GitHub org slug (used when single_repo is empty)"
14+
required: true
15+
default: "grafana"
16+
type: string
17+
single_repo:
18+
description: "Optional smoke test: one repo URL, e.g. https://github.com/grafana/grafana"
19+
required: false
20+
default: ""
21+
type: string
22+
schedule:
23+
# Weekly; delete this block if you only want manual runs.
24+
- cron: "15 4 * * 0"
25+
26+
permissions:
27+
contents: read
28+
actions: write
29+
30+
env:
31+
# renovate: datasource=github-releases depName=trufflesecurity/trufflehog
32+
TRUFFLEHOG_VERSION: v3.94.0
33+
DEFAULT_ORG: grafana
34+
35+
jobs:
36+
scan:
37+
name: Scan
38+
runs-on: ubuntu-latest
39+
timeout-minutes: 360
40+
steps:
41+
- name: Install TruffleHog
42+
run: |
43+
if [[ "$(uname -m)" == "aarch64" ]]; then
44+
ARCH="linux_arm64"
45+
else
46+
ARCH="linux_amd64"
47+
fi
48+
BINARY_URL="https://github.com/trufflesecurity/trufflehog/releases/download/${TRUFFLEHOG_VERSION}/trufflehog_${TRUFFLEHOG_VERSION#v}_${ARCH}.tar.gz"
49+
curl -sSfL "${BINARY_URL}" | tar -xz -C /tmp
50+
sudo mv /tmp/trufflehog /usr/local/bin/trufflehog
51+
sudo chmod +x /usr/local/bin/trufflehog
52+
trufflehog --version
53+
54+
- name: Run scan (advisory — never blocks merges)
55+
env:
56+
TOKEN: ${{ secrets.ORG_TRUFFLEHOG_PAT }}
57+
run: |
58+
if [[ -z "${TOKEN}" ]]; then
59+
echo "::error::Create repository secret ORG_TRUFFLEHOG_PAT (PAT with read access to the org repos you scan)."
60+
exit 1
61+
fi
62+
63+
ORG="${DEFAULT_ORG}"
64+
SINGLE_REPO=""
65+
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
66+
ORG="${{ github.event.inputs.org }}"
67+
SINGLE_REPO="${{ github.event.inputs.single_repo }}"
68+
fi
69+
70+
set +e
71+
if [[ -n "${SINGLE_REPO}" ]]; then
72+
echo "Mode: single repo → ${SINGLE_REPO}"
73+
trufflehog github \
74+
--repo="${SINGLE_REPO}" \
75+
--token="${TOKEN}" \
76+
--json \
77+
--no-update \
78+
--results=verified,unverified \
79+
> results.ndjson
80+
else
81+
echo "Mode: full org → ${ORG}"
82+
trufflehog github \
83+
--org="${ORG}" \
84+
--token="${TOKEN}" \
85+
--json \
86+
--no-update \
87+
--results=verified,unverified \
88+
> results.ndjson
89+
fi
90+
TH_EXIT=$?
91+
set -e
92+
93+
grep -E '^\{' results.ndjson > filtered.ndjson 2>/dev/null || true
94+
if [[ -s filtered.ndjson ]]; then
95+
jq -R 'fromjson?' filtered.ndjson | jq -s '.' > results.json
96+
else
97+
echo "[]" > results.json
98+
fi
99+
100+
VERIFIED="$(jq '[.[] | select(.Verified == true)] | length' results.json)"
101+
UNVERIFIED="$(jq '[.[] | select(.Verified == false)] | length' results.json)"
102+
TOTAL=$((VERIFIED + UNVERIFIED))
103+
104+
{
105+
echo "### TruffleHog (github source)"
106+
echo "- TruffleHog exit: \`${TH_EXIT}\` (non-zero can mean findings or scan errors; artifacts still uploaded)"
107+
echo "- Verified: \`${VERIFIED}\`"
108+
echo "- Unverified: \`${UNVERIFIED}\`"
109+
echo "- Total: \`${TOTAL}\`"
110+
} >> "${GITHUB_STEP_SUMMARY}"
111+
112+
exit 0
113+
114+
- name: Upload results
115+
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
116+
if: always()
117+
with:
118+
name: trufflehog_github_${{ github.run_id }}
119+
path: |
120+
results.json
121+
results.ndjson
122+
if-no-files-found: warn
123+
retention-days: 14

docs/trufflehog-org-fullscan.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# TruffleHog org scan (GitHub source)
2+
3+
Uses the official CLI: [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog)`trufflehog github --org=…` / `--repo=…`.
4+
5+
Workflow: `.github/workflows/org-trufflehog-fullscan.yml`
6+
7+
## Test on GitHub Actions
8+
9+
1. Add secret **`ORG_TRUFFLEHOG_PAT`** (read access to repos you scan).
10+
2. **Actions****TruffleHog org scan (GitHub)****Run workflow**.
11+
3. **Quick test:** set **single_repo** to e.g. `https://github.com/trufflesecurity/test_keys` (public canary) or any repo URL you may read.
12+
4. Download artifact **`trufflehog_github_<run_id>`**`results.json` / `results.ndjson`.
13+
14+
## Test locally (same behavior)
15+
16+
```bash
17+
trufflehog github --repo=https://github.com/trufflesecurity/test_keys --json --no-update --results=verified,unverified
18+
```
19+
20+
With token: add `--token="$GITHUB_TOKEN"`.
21+
22+
## Notes
23+
24+
- Workflow is advisory (no `--fail`); do not add as a required ruleset check if you want it off the merge path.
25+
- Weekly schedule is optional; remove `schedule:` in the YAML for manual-only.

0 commit comments

Comments
 (0)