Skip to content

Commit d8b1cdc

Browse files
authored
Merge pull request #3 from nboyers/dev
Dev
2 parents 3250ead + 6eae57a commit d8b1cdc

File tree

63 files changed

+5611
-571
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+5611
-571
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Optional: Pre-commit hooks workflow
2+
# This provides guidance for setting up local pre-commit hooks
3+
4+
name: Pre-commit Validation
5+
6+
on:
7+
pull_request:
8+
paths:
9+
- ".pre-commit-config.yaml"
10+
- ".github/workflows/pre-commit-hooks.yml"
11+
12+
jobs:
13+
validate-pre-commit:
14+
name: Validate Pre-commit Configuration
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: "3.11"
23+
24+
- name: Install pre-commit
25+
run: |
26+
pip install pre-commit
27+
pre-commit --version
28+
29+
- name: Run pre-commit on all files
30+
run: pre-commit run --all-files
31+
continue-on-error: true
32+
33+
- name: Show pre-commit setup instructions
34+
if: always()
35+
run: |
36+
echo "## 📋 Setting up Pre-commit Hooks Locally"
37+
echo ""
38+
echo "Pre-commit hooks help catch secrets BEFORE they reach GitHub."
39+
echo ""
40+
echo "### Installation:"
41+
echo "\`\`\`bash"
42+
echo "# Install pre-commit"
43+
echo "pip install pre-commit"
44+
echo ""
45+
echo "# Install the git hooks"
46+
echo "pre-commit install"
47+
echo ""
48+
echo "# (Optional) Run against all files"
49+
echo "pre-commit run --all-files"
50+
echo "\`\`\`"
51+
echo ""
52+
echo "### What it does:"
53+
echo "- Scans for secrets before each commit"
54+
echo "- Validates Terraform formatting"
55+
echo "- Checks for merge conflicts"
56+
echo "- Prevents large files from being committed"
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
name: Secret Scanning
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
push:
8+
branches:
9+
- main
10+
- "feature/**"
11+
- "fix/**"
12+
13+
permissions:
14+
contents: write
15+
pull-requests: write
16+
issues: write
17+
18+
jobs:
19+
gitleaks:
20+
name: Gitleaks Secret Scanning
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout code
24+
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0 # Fetch all history for accurate scanning
27+
28+
- name: Run Gitleaks
29+
uses: gitleaks/gitleaks-action@v2
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
GITLEAKS_ENABLE_COMMENTS: true
33+
34+
- name: Upload Gitleaks Report
35+
if: failure()
36+
uses: actions/upload-artifact@v4
37+
with:
38+
name: gitleaks-report
39+
path: results.sarif
40+
retention-days: 7
41+
42+
trufflehog:
43+
name: TruffleHog Secret Scanning
44+
runs-on: ubuntu-latest
45+
steps:
46+
- name: Checkout code
47+
uses: actions/checkout@v4
48+
with:
49+
fetch-depth: 0
50+
51+
- name: TruffleHog OSS
52+
uses: trufflesecurity/trufflehog@main
53+
with:
54+
path: ./
55+
base: ${{ github.event.repository.default_branch }}
56+
head: HEAD
57+
extra_args: --debug --only-verified
58+
59+
custom-pattern-check:
60+
name: Custom Pattern Detection
61+
runs-on: ubuntu-latest
62+
steps:
63+
- name: Checkout code
64+
uses: actions/checkout@v4
65+
with:
66+
fetch-depth: 0
67+
68+
- name: Check for common secret patterns
69+
id: secret_check
70+
run: |
71+
echo "Scanning for common secret patterns..."
72+
73+
# Define patterns to search for
74+
PATTERNS=(
75+
"aws_access_key_id"
76+
"aws_secret_access_key"
77+
"AKIA[0-9A-Z]{16}" # AWS Access Key
78+
"(?i)api[_-]?key.*['\"][0-9a-zA-Z]{32,}['\"]" # Generic API keys
79+
"(?i)password.*['\"][^'\"]{8,}['\"]" # Passwords in quotes
80+
"(?i)secret.*['\"][0-9a-zA-Z]{32,}['\"]" # Generic secrets
81+
"(?i)token.*['\"][0-9a-zA-Z]{32,}['\"]" # Tokens
82+
"private[_-]?key"
83+
"-----BEGIN (RSA|OPENSSH|DSA|EC) PRIVATE KEY-----" # Private keys
84+
"ghp_[0-9a-zA-Z]{36}" # GitHub Personal Access Token
85+
"ghs_[0-9a-zA-Z]{36}" # GitHub OAuth Secret
86+
"sk_live_[0-9a-zA-Z]{24,}" # Stripe Live Secret Key
87+
"pk_live_[0-9a-zA-Z]{24,}" # Stripe Live Public Key
88+
)
89+
90+
FOUND_SECRETS=0
91+
REPORT_FILE="secret_scan_report.txt"
92+
93+
echo "=== Secret Scanning Report ===" > $REPORT_FILE
94+
echo "Timestamp: $(date)" >> $REPORT_FILE
95+
echo "" >> $REPORT_FILE
96+
97+
# Get list of changed files
98+
if [ "${{ github.event_name }}" = "pull_request" ]; then
99+
FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
100+
else
101+
FILES=$(git diff --name-only HEAD~1 HEAD)
102+
fi
103+
104+
# Skip certain file types and directories
105+
FILES=$(echo "$FILES" | grep -v ".terraform/" | grep -v ".git/" | grep -v "node_modules/" || true)
106+
107+
for FILE in $FILES; do
108+
if [ -f "$FILE" ]; then
109+
echo "Scanning: $FILE" >> $REPORT_FILE
110+
111+
for PATTERN in "${PATTERNS[@]}"; do
112+
MATCHES=$(grep -niE "$PATTERN" "$FILE" 2>/dev/null || true)
113+
if [ ! -z "$MATCHES" ]; then
114+
FOUND_SECRETS=1
115+
echo " ❌ FOUND POTENTIAL SECRET:" >> $REPORT_FILE
116+
echo " Pattern: $PATTERN" >> $REPORT_FILE
117+
echo "$MATCHES" | while IFS= read -r line; do
118+
# Redact the actual secret value
119+
REDACTED=$(echo "$line" | sed -E 's/['\''"][0-9a-zA-Z]{8,}['\''"]/***REDACTED***/g')
120+
echo " $REDACTED" >> $REPORT_FILE
121+
done
122+
echo "" >> $REPORT_FILE
123+
fi
124+
done
125+
fi
126+
done
127+
128+
if [ $FOUND_SECRETS -eq 1 ]; then
129+
echo "status=failed" >> $GITHUB_OUTPUT
130+
cat $REPORT_FILE
131+
echo ""
132+
echo "❌ SECRETS DETECTED! Please remove sensitive data before committing."
133+
exit 1
134+
else
135+
echo "status=passed" >> $GITHUB_OUTPUT
136+
echo "✅ No secrets detected"
137+
fi
138+
139+
- name: Comment on PR with findings
140+
if: failure() && github.event_name == 'pull_request'
141+
uses: actions/github-script@v7
142+
with:
143+
github-token: ${{ secrets.GITHUB_TOKEN }}
144+
script: |
145+
const fs = require('fs');
146+
let report = '⚠️ **Secret Scanning Failed**\n\n';
147+
report += '**Potential secrets or API keys were detected in your changes.**\n\n';
148+
report += 'Please review and remove any sensitive data before merging.\n\n';
149+
report += '### What to do:\n';
150+
report += '1. Remove the secret from your code\n';
151+
report += '2. Use environment variables or GitHub Secrets instead\n';
152+
report += '3. If the secret was already committed, you must:\n';
153+
report += ' - Rotate/invalidate the exposed secret\n';
154+
report += ' - Remove it from git history using `git filter-branch` or BFG Repo-Cleaner\n\n';
155+
report += '### Common secret patterns detected:\n';
156+
report += '- AWS Access Keys (AKIA...)\n';
157+
report += '- API Keys\n';
158+
report += '- Private Keys\n';
159+
report += '- Passwords or tokens in code\n\n';
160+
report += '**This PR cannot be merged until all secrets are removed.**';
161+
162+
github.rest.issues.createComment({
163+
issue_number: context.issue.number,
164+
owner: context.repo.owner,
165+
repo: context.repo.repo,
166+
body: report
167+
});
168+
169+
block-merge:
170+
name: Block Merge if Secrets Found
171+
runs-on: ubuntu-latest
172+
needs: [gitleaks, trufflehog, custom-pattern-check]
173+
if: always()
174+
steps:
175+
- name: Check scan results
176+
run: |
177+
if [ "${{ needs.gitleaks.result }}" = "failure" ] || \
178+
[ "${{ needs.trufflehog.result }}" = "failure" ] || \
179+
[ "${{ needs.custom-pattern-check.result }}" = "failure" ]; then
180+
echo "❌ Secret scanning failed. Blocking merge."
181+
exit 1
182+
else
183+
echo "✅ All secret scans passed. Safe to merge."
184+
fi
185+
186+
# Optional: Auto-revert commits with secrets on main branch
187+
auto-revert:
188+
name: Auto-revert Commits with Secrets
189+
runs-on: ubuntu-latest
190+
needs: [gitleaks, trufflehog, custom-pattern-check]
191+
if: |
192+
failure() &&
193+
github.event_name == 'push' &&
194+
github.ref == 'refs/heads/main'
195+
permissions:
196+
contents: write
197+
steps:
198+
- name: Checkout code
199+
uses: actions/checkout@v4
200+
with:
201+
fetch-depth: 0
202+
token: ${{ secrets.GITHUB_TOKEN }}
203+
204+
- name: Configure git
205+
run: |
206+
git config user.name "github-actions[bot]"
207+
git config user.email "github-actions[bot]@users.noreply.github.com"
208+
209+
- name: Revert last commit
210+
run: |
211+
COMMIT_SHA="${{ github.sha }}"
212+
COMMIT_MSG=$(git log -1 --pretty=%B $COMMIT_SHA)
213+
214+
echo "⚠️ Reverting commit: $COMMIT_SHA"
215+
echo "Commit message: $COMMIT_MSG"
216+
217+
git revert --no-edit $COMMIT_SHA
218+
git push origin main
219+
220+
- name: Create issue for manual review
221+
uses: actions/github-script@v7
222+
with:
223+
github-token: ${{ secrets.GITHUB_TOKEN }}
224+
script: |
225+
const issue = await github.rest.issues.create({
226+
owner: context.repo.owner,
227+
repo: context.repo.repo,
228+
title: '🚨 Secrets Detected - Commit Automatically Reverted',
229+
body: `## Security Alert: Secrets Detected
230+
231+
**Commit**: \`${{ github.sha }}\`
232+
**Author**: @${{ github.actor }}
233+
**Branch**: main
234+
235+
### What happened?
236+
Secret scanning detected potential secrets or API keys in a commit to the main branch.
237+
The commit has been automatically reverted to prevent exposure.
238+
239+
### Required Actions:
240+
241+
1. **⚠️ ROTATE ALL EXPOSED SECRETS IMMEDIATELY**
242+
- If the secret was an API key, revoke it
243+
- If it was an AWS key, disable it in IAM
244+
- Generate new credentials
245+
246+
2. **Clean up your local branch**:
247+
\`\`\`bash
248+
git fetch origin
249+
git reset --hard origin/main
250+
\`\`\`
251+
252+
3. **Remove the secret properly**:
253+
- Use environment variables
254+
- Use GitHub Secrets
255+
- Use AWS Secrets Manager / Parameter Store
256+
- Add pattern to .gitignore
257+
258+
4. **Re-commit without secrets**:
259+
- Make your changes again
260+
- Ensure no secrets are in the code
261+
- Submit a new PR
262+
263+
### Preventing Future Incidents:
264+
265+
- Always use \`.tfvars\` files for sensitive values (they're gitignored)
266+
- Use \`backend.tf\` for backend config (also gitignored)
267+
- Store secrets in GitHub Secrets or AWS Secrets Manager
268+
- Run \`git diff\` before committing to review changes
269+
- Enable pre-commit hooks for local secret scanning
270+
271+
**This issue will remain open until confirmed that exposed secrets have been rotated.**`,
272+
labels: ['security', 'urgent', 'secrets-detected']
273+
});
274+
275+
console.log('Created issue:', issue.data.number);
276+
277+
- name: Send alert notification
278+
if: always()
279+
run: |
280+
echo "🚨 SECURITY ALERT: Secrets detected in commit ${{ github.sha }}"
281+
echo "Commit has been reverted and an issue has been created."
282+
echo "Please rotate any exposed credentials immediately."

0 commit comments

Comments
 (0)