Skip to content

Commit 02ee9fc

Browse files
committed
security: standardize secret scanning on TruffleHog
1 parent 42d6e8a commit 02ee9fc

8 files changed

Lines changed: 20 additions & 133 deletions

File tree

.github/workflows/casket-pages.yml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,33 @@
11
# SPDX-License-Identifier: MPL-2.0
22
name: GitHub Pages
3-
43
on:
54
push:
65
branches: [main]
76
workflow_dispatch:
8-
97
permissions:
108
contents: read
119
pages: write
1210
id-token: write
13-
1411
concurrency:
1512
group: "pages"
1613
cancel-in-progress: false
17-
1814
jobs:
1915
build:
2016
runs-on: ubuntu-latest
2117
timeout-minutes: 15
2218
steps:
2319
- name: Checkout
2420
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
25-
2621
- name: Checkout casket-ssg
2722
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
2823
with:
2924
repository: hyperpolymath/casket-ssg
3025
path: .casket-ssg
31-
3226
- name: Setup GHCup
3327
uses: haskell-actions/setup@ec49483bfc012387b227434aba94f59a6ecd0900 # v2
3428
with:
3529
ghc-version: '9.8.2'
3630
cabal-version: '3.10'
37-
3831
- name: Cache Cabal
3932
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
4033
with:
@@ -43,11 +36,9 @@ jobs:
4336
~/.cabal/store
4437
.casket-ssg/dist-newstyle
4538
key: ${{ runner.os }}-casket-${{ hashFiles('.casket-ssg/casket-ssg.cabal') }}
46-
4739
- name: Build casket-ssg
4840
working-directory: .casket-ssg
4941
run: cabal build
50-
5142
- name: Build site
5243
run: |
5344
mkdir -p site _site
@@ -78,15 +69,12 @@ jobs:
7869
fi
7970
fi
8071
cd .casket-ssg && cabal run casket-ssg -- build ../site ../_site
81-
8272
- name: Setup Pages
8373
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
84-
8574
- name: Upload artifact
8675
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
8776
with:
8877
path: '_site'
89-
9078
deploy:
9179
environment:
9280
name: github-pages

.github/workflows/codeql.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
# SPDX-License-Identifier: MPL-2.0
22
name: CodeQL Security Analysis
3-
43
on:
54
push:
65
branches: [main]
76
pull_request:
87
branches: [main]
98
schedule:
10-
- cron: '0 6 * * 1' # Weekly on Monday
11-
12-
9+
- cron: '0 6 * * 1' # Weekly on Monday
1310
permissions: read-all
14-
1511
jobs:
1612
analyze:
1713
name: CodeQL Analysis
@@ -20,23 +16,18 @@ jobs:
2016
permissions:
2117
security-events: write
2218
contents: read
23-
2419
strategy:
2520
fail-fast: false
2621
matrix:
2722
language: ['javascript-typescript']
28-
2923
steps:
3024
- name: Checkout repository
3125
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
32-
3326
- name: Initialize CodeQL
3427
uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3
3528
with:
3629
languages: ${{ matrix.language }}
37-
3830
- name: Autobuild
3931
uses: github/codeql-action/autobuild@662472033e021d55d94146f66f6058822b0b39fd # v3
40-
4132
- name: Perform CodeQL Analysis
4233
uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3

.github/workflows/governance.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@
1111
# (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing).
1212

1313
name: Governance
14-
1514
on:
1615
push:
1716
branches: [main, master]
1817
pull_request:
1918
workflow_dispatch:
20-
2119
permissions:
2220
contents: read
23-
2421
jobs:
2522
governance:
2623
uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613

.github/workflows/hypatia-scan.yml

Lines changed: 12 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
# SPDX-License-Identifier: MPL-2.0
22
# Hypatia Neurosymbolic CI/CD Security Scan
33
name: Hypatia Security Scan
4-
54
on:
65
push:
7-
branches: [ main, master, develop ]
6+
branches: [main, master, develop]
87
pull_request:
9-
branches: [ main, master ]
8+
branches: [main, master]
109
schedule:
11-
- cron: '0 0 * * 0' # Weekly on Sunday
10+
- cron: '0 0 * * 0' # Weekly on Sunday
1211
workflow_dispatch:
1312
# Estate guardrail: cancel superseded runs so re-pushes don't pile up
1413
# queued runs across the estate. Safe here because this workflow only
1514
# performs read-only checks/lint/test/scan with no publish or mutation.
1615
concurrency:
1716
group: ${{ github.workflow }}-${{ github.ref }}
1817
cancel-in-progress: true
19-
2018
permissions:
2119
contents: read
2220
# security-events: write serves two purposes (write implies read):
@@ -38,31 +36,26 @@ permissions:
3836
# "Resource not accessible by integration" and (absent continue-on-error)
3937
# hard-fails the scan — exactly what the gate-decoupling design forbids.
4038
pull-requests: write
41-
4239
jobs:
4340
scan:
4441
name: Hypatia Neurosymbolic Analysis
4542
runs-on: ubuntu-latest
4643
timeout-minutes: 15
47-
4844
steps:
4945
- name: Checkout repository
5046
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
5147
with:
52-
fetch-depth: 0 # Full history for better pattern analysis
53-
48+
fetch-depth: 0 # Full history for better pattern analysis
5449
- name: Setup Elixir for Hypatia scanner
5550
uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.18.2
5651
with:
5752
elixir-version: '1.18'
5853
otp-version: '27'
59-
6054
- name: Clone Hypatia
6155
run: |
6256
if [ ! -d "$HOME/hypatia" ]; then
6357
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
6458
fi
65-
6659
- name: Build Hypatia scanner (if needed)
6760
run: |
6861
cd "$HOME/hypatia"
@@ -71,7 +64,6 @@ jobs:
7164
mix deps.get
7265
mix escript.build
7366
fi
74-
7567
- name: Run Hypatia scan
7668
id: scan
7769
env:
@@ -104,14 +96,12 @@ jobs:
10496
echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
10597
echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
10698
echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
107-
10899
- name: Upload findings artifact
109100
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
110101
with:
111102
name: hypatia-findings
112103
path: hypatia-findings.json
113104
retention-days: 90
114-
115105
- name: Convert Hypatia findings to SARIF
116106
# Always runs (no findings_count guard): an EMPTY SARIF run is
117107
# valid and intentional — uploading it clears stale Hypatia
@@ -227,7 +217,6 @@ jobs:
227217
console.log(`hypatia.sarif written: ${results.length} result(s).`);
228218
CJS
229219
node "$RUNNER_TEMP/hypatia-sarif.cjs"
230-
231220
- name: Upload SARIF to GitHub code scanning
232221
# Fork PRs get a read-only GITHUB_TOKEN, so security-events:write
233222
# is unavailable and upload-sarif cannot publish — skip there
@@ -239,16 +228,19 @@ jobs:
239228
# exists to end). The empty-SARIF "clear stale alerts" path is
240229
# handled in the converter above and does not error here.
241230
if: >-
242-
always() &&
243-
(github.event_name != 'pull_request' ||
231+
always() && (github.event_name != 'pull_request' ||
232+
233+
234+
235+
236+
244237
github.event.pull_request.head.repo.fork != true)
245238
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1
246239
with:
247240
sarif_file: hypatia.sarif
248241
# Distinct category so Hypatia results coexist with CodeQL's
249242
# (codeql.yml) instead of overwriting them on the same surface.
250243
category: hypatia
251-
252244
- name: Submit findings to gitbot-fleet (Phase 2)
253245
if: steps.scan.outputs.findings_count > 0
254246
# Phase 2 is the collaborative LEARNING side-channel ("bots share
@@ -272,52 +264,7 @@ jobs:
272264
GITHUB_REPOSITORY: ${{ github.repository }}
273265
GITHUB_SHA: ${{ github.sha }}
274266
FINDINGS_COUNT: ${{ steps.scan.outputs.findings_count }}
275-
run: |
276-
echo "📤 Submitting $FINDINGS_COUNT findings to gitbot-fleet..."
277-
278-
# Clone gitbot-fleet to temp directory. A clone failure (network,
279-
# repo gone) is non-fatal: learning submission is best-effort.
280-
FLEET_DIR="/tmp/gitbot-fleet-$$"
281-
if ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"; then
282-
echo "::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal)."
283-
exit 0
284-
fi
285-
286-
# The submission script's location in gitbot-fleet has drifted
287-
# before (it was absent from the default branch, which exit-127'd
288-
# every consuming repo's scan). Probe known locations rather than
289-
# hard-coding one path, and skip gracefully if none is present.
290-
SUBMIT_SCRIPT=""
291-
for cand in \
292-
"$FLEET_DIR/scripts/submit-finding.sh" \
293-
"$FLEET_DIR/scripts/submit_finding.sh" \
294-
"$FLEET_DIR/bin/submit-finding.sh" \
295-
"$FLEET_DIR/submit-finding.sh"; do
296-
if [ -f "$cand" ]; then
297-
SUBMIT_SCRIPT="$cand"
298-
break
299-
fi
300-
done
301-
302-
if [ -z "$SUBMIT_SCRIPT" ]; then
303-
echo "::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below."
304-
rm -rf "$FLEET_DIR"
305-
exit 0
306-
fi
307-
308-
# Run submission script. Pass the findings path as ABSOLUTE —
309-
# the script cd's into its own working dir before reading the
310-
# file, so a relative path would resolve to the wrong place.
311-
# A submission-script failure is logged but non-fatal.
312-
if bash "$SUBMIT_SCRIPT" "$GITHUB_WORKSPACE/hypatia-findings.json"; then
313-
echo "✅ Finding submission complete"
314-
else
315-
echo "::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal)."
316-
fi
317-
318-
# Cleanup
319-
rm -rf "$FLEET_DIR"
320-
267+
run: "echo \"\U0001F4E4 Submitting $FINDINGS_COUNT findings to gitbot-fleet...\"\n\n# Clone gitbot-fleet to temp directory. A clone failure (network,\n# repo gone) is non-fatal: learning submission is best-effort.\nFLEET_DIR=\"/tmp/gitbot-fleet-$$\"\nif ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git \"$FLEET_DIR\"; then\n echo \"::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal).\"\n exit 0\nfi\n\n# The submission script's location in gitbot-fleet has drifted\n# before (it was absent from the default branch, which exit-127'd\n# every consuming repo's scan). Probe known locations rather than\n# hard-coding one path, and skip gracefully if none is present.\nSUBMIT_SCRIPT=\"\"\nfor cand in \\\n \"$FLEET_DIR/scripts/submit-finding.sh\" \\\n \"$FLEET_DIR/scripts/submit_finding.sh\" \\\n \"$FLEET_DIR/bin/submit-finding.sh\" \\\n \"$FLEET_DIR/submit-finding.sh\"; do\n if [ -f \"$cand\" ]; then\n SUBMIT_SCRIPT=\"$cand\"\n break\n fi\ndone\n\nif [ -z \"$SUBMIT_SCRIPT\" ]; then\n echo \"::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below.\"\n rm -rf \"$FLEET_DIR\"\n exit 0\nfi\n\n# Run submission script. Pass the findings path as ABSOLUTE —\n# the script cd's into its own working dir before reading the\n# file, so a relative path would resolve to the wrong place.\n# A submission-script failure is logged but non-fatal.\nif bash \"$SUBMIT_SCRIPT\" \"$GITHUB_WORKSPACE/hypatia-findings.json\"; then\n echo \"✅ Finding submission complete\"\nelse\n echo \"::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal).\"\nfi\n\n# Cleanup\nrm -rf \"$FLEET_DIR\"\n"
321268
- name: Check for critical issues
322269
if: steps.scan.outputs.critical > 0
323270
# GATING POLICY (explicit, by design — not an oversight):
@@ -335,7 +282,6 @@ jobs:
335282
echo "::warning::Hypatia found critical security issue(s) — advisory."
336283
echo "See the Security → Code scanning page (category: hypatia)"
337284
echo "and the hypatia-findings.json artifact for details."
338-
339285
- name: Generate scan report
340286
run: |
341287
cat << EOF > hypatia-report.md
@@ -374,7 +320,6 @@ jobs:
374320
EOF
375321
376322
cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
377-
378323
- name: Comment on PR with findings
379324
if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
380325
# Advisory only — posting findings as a PR comment must never gate
@@ -384,32 +329,4 @@ jobs:
384329
continue-on-error: true
385330
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7
386331
with:
387-
script: |
388-
const fs = require('fs');
389-
const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
390-
391-
const critical = findings.filter(f => f.severity === 'critical').length;
392-
const high = findings.filter(f => f.severity === 'high').length;
393-
394-
let comment = `## 🔍 Hypatia Security Scan\n\n`;
395-
comment += `**Findings:** ${findings.length} issues detected\n\n`;
396-
comment += `| Severity | Count |\n|----------|-------|\n`;
397-
comment += `| 🔴 Critical | ${critical} |\n`;
398-
comment += `| 🟠 High | ${high} |\n`;
399-
comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
400-
401-
if (critical > 0) {
402-
comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
403-
}
404-
405-
comment += `<details><summary>View findings</summary>\n\n`;
406-
comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
407-
comment += `</details>\n\n`;
408-
comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
409-
410-
github.rest.issues.createComment({
411-
owner: context.repo.owner,
412-
repo: context.repo.repo,
413-
issue_number: context.issue.number,
414-
body: comment
415-
});
332+
script: "const fs = require('fs');\nconst findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));\n\nconst critical = findings.filter(f => f.severity === 'critical').length;\nconst high = findings.filter(f => f.severity === 'high').length;\n\nlet comment = `## \U0001F50D Hypatia Security Scan\\n\\n`;\ncomment += `**Findings:** ${findings.length} issues detected\\n\\n`;\ncomment += `| Severity | Count |\\n|----------|-------|\\n`;\ncomment += `| \U0001F534 Critical | ${critical} |\\n`;\ncomment += `| \U0001F7E0 High | ${high} |\\n`;\ncomment += `| \U0001F7E1 Medium | ${findings.length - critical - high} |\\n\\n`;\n\nif (critical > 0) {\n comment += `⚠️ **Action Required:** Critical security issues found!\\n\\n`;\n}\n\ncomment += `<details><summary>View findings</summary>\\n\\n`;\ncomment += `\\`\\`\\`json\\n${JSON.stringify(findings.slice(0, 10), null, 2)}\\n\\`\\`\\`\\n`;\ncomment += `</details>\\n\\n`;\ncomment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;\n\ngithub.rest.issues.createComment({\n owner: context.repo.owner,\n repo: context.repo.repo,\n issue_number: context.issue.number,\n body: comment\n});"

.github/workflows/mirror.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
# SPDX-License-Identifier: MPL-2.0
22
name: Mirror to GitLab and Bitbucket
3-
43
on:
54
push:
65
branches: [main]
7-
86
permissions: read-all
9-
107
jobs:
118
mirror:
129
name: Sync to Forges
@@ -15,13 +12,11 @@ jobs:
1512
if: vars.GITLAB_MIRROR_ENABLED == 'true' || vars.BITBUCKET_MIRROR_ENABLED == 'true'
1613
permissions:
1714
contents: read
18-
1915
steps:
2016
- name: Checkout repository
2117
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
2218
with:
2319
fetch-depth: 0
24-
2520
- name: Mirror to GitLab
2621
if: vars.GITLAB_MIRROR_ENABLED == 'true' && secrets.GITLAB_SSH_KEY != ''
2722
run: |
@@ -31,7 +26,6 @@ jobs:
3126
ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
3227
git remote add gitlab git@gitlab.com:hyperpolymath/error-lang.git || true
3328
git push --mirror gitlab
34-
3529
- name: Mirror to Bitbucket
3630
if: vars.BITBUCKET_MIRROR_ENABLED == 'true' && secrets.BITBUCKET_SSH_KEY != ''
3731
run: |

0 commit comments

Comments
 (0)