Skip to content
Open
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
86 changes: 56 additions & 30 deletions .github/workflows/security-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,28 @@ jobs:
extra-substituters: ${{ inputs.extra-substituters }}
extra-trusted-public-keys: ${{ inputs.extra-trusted-public-keys }}

# Build the dev shell in its own step so that the Nix build log — hundreds
# of kilobytes of downloads and `building ...` lines on a cold cache —
# stays out of the report captured below.
- name: Warm the dev shell
run: nix develop --command true

- name: Check advisories
id: audit
run: |
set +e
OUTPUT=$(nix develop --command cargo deny check --config .config/deny.toml advisories 2>&1)
nix develop --command cargo deny check --config .config/deny.toml advisories \
> "$REPORT" 2>&1
EXIT_CODE=$?
echo "$OUTPUT"
{
echo "output<<AUDIT_EOF"
echo "$OUTPUT"
echo "AUDIT_EOF"
} >> "$GITHUB_OUTPUT"
cat "$REPORT"
echo "exit_code=$EXIT_CODE" >> "$GITHUB_OUTPUT"
exit 0
env:
# The report goes to a file, not a step output: it is passed to the
# reporting step below, where an inlined copy would land in the
# environment block and fail the step with E2BIG once it exceeds the
# 128 KiB per-string execve limit.
REPORT: ${{ runner.temp }}/cargo-deny-advisories.txt

- name: Find existing issue
id: find_issue
Expand All @@ -89,38 +97,56 @@ jobs:
- name: Create or update issue on failure
if: steps.audit.outputs.exit_code != '0'
run: |
set -eo pipefail
TITLE="Security Advisory Alert"
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
BODY=$(cat <<'ISSUE_EOF'
## Security Advisory Found

`cargo deny check advisories` found active advisories in dependencies.

<details>
<summary>Full output</summary>
BODY_FILE="${RUNNER_TEMP}/security-advisory-issue.md"

```
__AUDIT_OUTPUT__
```

</details>

**Action required:** Review the advisories above and update affected dependencies or add ignore entries to `.config/deny.toml` if appropriate.
# A GitHub issue body is capped at 65536 characters, so a very large
# report cannot be posted whole. Keep the tail, which is where
# cargo-deny prints the advisories and its verdict, and link the run
# log for the rest. `tail -n +2` drops the partial first line left by
# the byte-wise cut, which could otherwise split a UTF-8 sequence.
MAX_REPORT_BYTES=50000
TRUNCATED=""
if [ "$(wc -c < "$REPORT")" -gt "$MAX_REPORT_BYTES" ]; then
TRUNCATED=yes
tail -c "$MAX_REPORT_BYTES" "$REPORT" | tail -n +2 > "${REPORT}.tail"
mv "${REPORT}.tail" "$REPORT"
fi

_Last checked: __TIMESTAMP___
ISSUE_EOF
)
BODY="${BODY//__TIMESTAMP__/$TIMESTAMP}"
BODY="${BODY//__AUDIT_OUTPUT__/$AUDIT_OUTPUT}"
{
echo "## Security Advisory Found"
echo
echo "\`cargo deny check advisories\` found active advisories in dependencies."
echo
if [ -n "$TRUNCATED" ]; then
echo "> Output truncated to the last ${MAX_REPORT_BYTES} bytes. The full report is in the [workflow run log](${RUN_URL})."
echo
fi
echo "<details>"
echo "<summary>Full output</summary>"
echo
echo '```'
cat "$REPORT"
echo
echo '```'
echo
echo "</details>"
echo
echo "**Action required:** Review the advisories above and update affected dependencies or add ignore entries to \`.config/deny.toml\` if appropriate."
echo
echo "_Last checked: $(date -u +%Y-%m-%dT%H:%M:%SZ)_"
} > "$BODY_FILE"

if [ -n "$ISSUE_NUMBER" ]; then
gh issue edit "$ISSUE_NUMBER" --body "$BODY"
gh issue edit "$ISSUE_NUMBER" --body-file "$BODY_FILE"
else
gh issue create --title "$TITLE" --body "$BODY" --label security
gh issue create --title "$TITLE" --body-file "$BODY_FILE" --label security
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AUDIT_OUTPUT: ${{ steps.audit.outputs.output }}
REPORT: ${{ runner.temp }}/cargo-deny-advisories.txt
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
ISSUE_NUMBER: ${{ steps.find_issue.outputs.number }}

- name: Close issue on success
Expand Down
Loading