Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/fleet-sast.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Fleet-added (Apollo/greploop posture-B floor). NOT upstream — do not expect on NousResearch/hermes-agent.
# Provides the `sast` deterministic-floor component. Diff-aware where it helps, full-tree gate at ERROR.
name: Fleet SAST (semgrep)

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: fleet-sast-${{ github.ref }}
cancel-in-progress: true

jobs:
sast:
name: sast
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Actions pinned to mutable version tags, not immutable SHAs

actions/checkout@v4 and actions/setup-python@v5 (same pattern in fleet-secret-scan.yml) are pinned to floating tags rather than commit SHAs. A tag can be force-pushed to point at a different commit, meaning a compromised or accidental re-tag could silently alter what code runs in CI. Pinning to the full SHA (e.g., actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683) provides a stable, tamper-evident reference.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install semgrep
run: pip install "semgrep==1.46.0"

- name: Run semgrep (ERROR severity gate)
run: |
semgrep \
--config=p/python \
--config=p/secrets \
--severity=ERROR \
--error \
--quiet \
hermes/
61 changes: 61 additions & 0 deletions .github/workflows/fleet-secret-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Fleet-added (Apollo/greploop posture-B floor). NOT upstream — do not expect on NousResearch/hermes-agent.
# Provides the `secret_scan` deterministic-floor component. DIFF-SCOPED on PRs: scans only the PR
# commit range, NOT full history (the fork inherits ~768 generic-api-key false positives in upstream
# test fixtures/docs — a full-tree scan would pin this RED forever). On push to main, scans the push range.
name: Fleet Secret Scan (gitleaks)

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: fleet-secret-scan-${{ github.ref }}
cancel-in-progress: true

jobs:
secret_scan:
name: secret_scan
runs-on: ubuntu-latest
steps:
- name: Checkout (full history for range scan)
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Compute scan range
id: range
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE="${{ github.event.pull_request.base.sha }}"
HEAD="${{ github.event.pull_request.head.sha }}"
else
BASE="${{ github.event.before }}"
HEAD="${{ github.sha }}"
fi
# Guard against the all-zero "before" SHA on first push / new branch.
if ! git cat-file -e "${BASE}^{commit}" 2>/dev/null; then
BASE="$(git rev-parse "${HEAD}~1" 2>/dev/null || echo "${HEAD}")"
fi
echo "base=${BASE}" >> "$GITHUB_OUTPUT"
echo "head=${HEAD}" >> "$GITHUB_OUTPUT"
echo "scanning ${BASE}..${HEAD}"
Comment on lines +40 to +45

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Silent empty-range scan on orphan / single-commit push

When the push-to-main path hits a branch where HEAD~1 does not exist (e.g., an orphan branch or a repo's very first commit), the fallback evaluates to BASE="${HEAD}". The resulting range HEAD..HEAD is empty, so gitleaks exits 0 without scanning any content. Any secrets committed in that initial push would pass undetected. A safer fallback is to emit git rev-list --max-parents=0 HEAD (the root commit) so the range becomes root..HEAD and still covers the first commit.


- name: Install gitleaks
run: |
VER=8.18.4
curl -fsSL "https://github.com/gitleaks/gitleaks/releases/download/v${VER}/gitleaks_${VER}_linux_x64.tar.gz" -o gl.tgz
tar xzf gl.tgz gitleaks
sudo mv gitleaks /usr/local/bin/
Comment on lines +47 to +52

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Missing binary integrity check before sudo install

The gitleaks tarball is downloaded and immediately extracted and moved to /usr/local/bin/ without verifying its SHA-256 checksum against the checksums.txt file that gitleaks provides with every release. If the GitHub release artifact is ever tampered with or the CDN is compromised, the workflow would install and subsequently execute a malicious binary with sudo privileges on the runner. Gitleaks publishes a checksums.txt alongside each release specifically to enable this verification — downloading it and running sha256sum --check --ignore-missing checksums.txt before extracting is the standard mitigation.


- name: Gitleaks (diff-scoped)
run: |
gitleaks detect \
--source . \
--no-banner \
--redact \
--log-opts="${{ steps.range.outputs.base }}..${{ steps.range.outputs.head }}" \
--exit-code 1
Loading