ci: add PR security heuristics workflow + cross-source audit checks#905
Merged
Conversation
Adapt the WebMS-Intra PR-security approach to MeedyaDL's Rust/TS/Tauri
stack. All checks are non-blocking advisory; the merge gate stays with
ci.yml (cargo clippy -D warnings, cargo test, cargo-deny, tsc, eslint,
CodeQL). This adds the heuristic layer those gates don't cover.
New .github/workflows/pr-security.yml runs eight checks on PRs to
main/release-candidate/beta/alpha and posts a single upserted comment
(edited in place by hidden marker, not one comment per push):
gitleaks secrets scan, Rust subprocess shell-interpolation (no sh -c),
unsafe Rust, dangerous frontend sinks (eval/dangerouslySetInnerHTML),
hardcoded absolute paths, unpinned GitHub Actions (non-SHA refs),
sensitive/proprietary path touches (assets/brand is proprietary), and
cross-source consistency.
New tools/audit-checks/ holds two zero-dependency Python validators:
- check_ipc_commands.py: every #[tauri::command] is registered in the
lib.rs generate_handler![] and every frontend invoke('x') targets a
registered command (the runtime "command not found" class).
- check_codec_registry.py: every codecs.toml meta resolves_to target is
a real codec section and every audio services.gamdl flag is a kebab
SongCodec variant.
Both report zero findings on the current tree and exit 1 under --strict
on injected drift.
Also add .github/pull_request_template.md (manual security-review
checklist) and a CLAUDE.md convention entry.
https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
The pinned actions/setup-python SHA (inherited from upstream-gamdl-watch.yml) is not resolvable on GitHub, so the job failed at action-resolution before any check ran. The audit-checks scripts are stdlib-only (re / sys / pathlib; the TOML is regex-parsed, not via tomllib), so the runner's preinstalled python3 is sufficient and the step can be removed outright. https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
Contributor
PR Security ChecksPR touches a sensitive / proprietary path (assets/brand is PROPRIETARY; confirm intentional)Generated by |
Add .claude/memory/project_pr_security_checks.md (type: project) documenting the pr-security.yml advisory gate, the two tools/audit-checks consistency scripts, the design choices (upsert comment, advisory-not-blocking, stdlib-only scripts), and the gotchas from standing it up (the unresolvable setup-python SHA still present in upstream-gamdl-watch.yml; detecting CI success from a remote session). Hook it into MEMORY.md. The CLAUDE.md convention bullet and the workflow/scripts/template themselves landed earlier on this branch (PR #905). https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adapts the WebMS-Intra
pr-security.ymlapproach to MeedyaDL's Rust + TypeScript + Tauri stack. All checks are non-blocking advisory — the merge gate stays withci.yml(cargo clippy -D warnings,cargo test,cargo-deny,tsc,eslint, CodeQL). This adds the heuristic layer those gates don't cover and posts a single upserted PR comment.This PR is the first real-world exercise of the new workflow — it runs
pr-security.ymlon itself.What's added
.github/workflows/pr-security.ymlmain/release-candidate/beta/alpha, one upserted commenttools/audit-checks/check_ipc_commands.py#[tauri::command]is registered inlib.rsgenerate_handler[]and every frontendinvoke('x')targets a registered commandtools/audit-checks/check_codec_registry.pycodecs.tomlmetaresolves_totarget is a real codec section and every audioservices.gamdlflag is aSongCodecvarianttools/audit-checks/README.md.github/pull_request_template.md.claude/CLAUDE.mdThe 8 workflow checks
sh -cshell-interpolation · 3.unsafeRust · 4. frontend sinks (eval/dangerouslySetInnerHTML/innerHTML=) · 5. hardcoded paths · 6. unpinned Actions (non-SHAuses:) · 7. sensitive/proprietary path touches (assets/brand/is proprietary) · 8. cross-source consistency scripts.Checks 2–7 scan only PR-changed files; check 8 validates whole-repo state.
Adaptation notes
This is not a copy — WebMS-Intra is PHP. Dropped the inapplicable PHP checks (PHP lint, mysqli SQL-injection, CSRF tokens, Psalm) and re-targeted the heuristic layer onto MeedyaDL's own documented invariants (the "no
sh -c" subprocess rule, SHA-pinned Actions, proprietary brand assets, the IPC contract). Added an unpinned-Action detector WebMS lacks, and upserts one PR comment instead of posting a fresh one per push.Verification
invoke(), a danglingresolves_to, a bogusgamdl=flag → all caught, exit 1 under--strict).actionlint(with bundled shellcheck on therun:scripts) passes clean.https://claude.ai/code/session_01Hek46RmeLzZTgrhFtvhN4m
Generated by Claude Code