Skip to content
Merged
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: 32 additions & 9 deletions .github/workflows/hypatia-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,26 @@ on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:
# Estate guardrail: cancel superseded runs so re-pushes don't pile up
# queued runs across the estate. Safe here because this workflow only
# performs read-only checks/lint/test/scan with no publish or mutation.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
# security-events: read lets the built-in GITHUB_TOKEN query this
# repo's own Dependabot alerts via the Hypatia DependabotAlerts rule
# (DA001-DA004). Without this, `scan_from_path` gets HTTP 403 and
# the rule silently returns no findings.
# See 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md.
security-events: read
# pull-requests: write lets the advisory "Comment on PR with findings"
# step post its summary. Without it the built-in GITHUB_TOKEN gets
# "Resource not accessible by integration" and (absent continue-on-error)
# hard-fails the scan — exactly what the gate-decoupling design forbids.
pull-requests: write

jobs:
scan:
Expand All @@ -21,7 +38,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0 # Full history for better pattern analysis

Expand All @@ -38,26 +55,27 @@ jobs:
fi

- name: Build Hypatia scanner (if needed)
working-directory: /home/runner/hypatia
run: |
if [ ! -f hypatia-v2 ]; then
echo "Building hypatia-v2 scanner..."
cd scanner
cd "$HOME/hypatia"
if [ ! -f hypatia ]; then
echo "Building hypatia scanner..."
mix deps.get
mix escript.build
mv hypatia ../hypatia-v2
fi

- name: Run Hypatia scan
id: scan
env:
# Suppress the Dependabot "GITHUB_TOKEN not set" warning.
# Pass the built-in Actions token through to Hypatia so the
# DependabotAlerts rule can query this repo's own alerts.
# For cross-repo scanning (fleet-coordinator scan-supervised),
# a PAT with `security_events` scope is required instead.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Scanning repository: ${{ github.repository }}"

# Run scanner
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json
# Run scanner (exits non-zero when findings exist — suppress to continue)
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json || true

# Count findings
FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0)
Expand Down Expand Up @@ -198,6 +216,11 @@ jobs:

- name: Comment on PR with findings
if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
# Advisory only — posting findings as a PR comment must never gate
# the scan (hypatia#213 gate decoupling). Belt-and-braces alongside
# the pull-requests: write permission above: a token/API hiccup or
# a fork PR (read-only token) skips the comment, not the check.
continue-on-error: true
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7
with:
script: |
Expand Down
Loading