ci: add pip-audit, hadolint, OSSF Scorecard, ZAP DAST, and pre-push hooks#350
ci: add pip-audit, hadolint, OSSF Scorecard, ZAP DAST, and pre-push hooks#350
Conversation
Dependency ReviewThe following issues were found:
OpenSSF ScorecardScorecard details
Scanned Files
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds structured security documentation, new GitHub Actions workflows (DAST, Scorecard, Python audit), CI updates to run pip-audit and hadolint, extends pre-commit hooks, and adds pip-audit to dev dependencies. Changes
Sequence Diagram(s)sequenceDiagram
participant GH as GitHub Actions
participant Build as Local Image Build
participant Backend as Backend Service
participant ZAP as ZAP Scanner
participant SARIF as SARIF Upload
GH->>Build: Build backend image (docker-compose)
GH->>Backend: Start backend container (env from example)
GH->>Backend: Poll health endpoint until ready
Backend-->>GH: Healthy
GH->>ZAP: Run ZAP API Scan (OpenAPI JSON at /docs/openapi.json)
ZAP-->>GH: Return scan results (SARIF)
GH->>SARIF: Upload SARIF results
GH->>Backend: Stop backend container (cleanup)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
📝 Coding Plan
Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the project's security posture and developer workflow by integrating several new CI/CD tools and pre-commit/pre-push hooks. The changes introduce automated vulnerability scanning for Python dependencies, Dockerfile linting, supply chain maturity scoring, and dynamic API security testing. Additionally, it streamlines the local development experience with pre-push checks and updates documentation to reflect these new security measures and development practices. Highlights
Changelog
Ignored Files
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request significantly enhances the project's CI and security posture by integrating several new tools: pip-audit for Python dependency scanning, hadolint for Dockerfile linting, OSSF Scorecard for supply chain maturity analysis, and ZAP for DAST. It also introduces pre-push hooks for faster local feedback using mypy and pytest. The associated documentation in SECURITY.md, CLAUDE.md, and the README.md has been updated accordingly to reflect these new capabilities. The implementation appears solid, with correct configuration for the new hooks and dependencies. I have reviewed the changes and found no issues of medium or higher severity.
Greptile SummaryThis PR adds a comprehensive layer of security tooling to the CI pipeline and developer workflow: Key observations:
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
PR[Pull Request / Push to main] --> CI[ci.yml]
CI --> lint[lint: ruff]
CI --> tc[type-check: mypy]
CI --> test[test: pytest + coverage]
CI --> pa[python-audit: pip-audit]
CI --> dl[dockerfile-lint: hadolint x3]
CI --> dash[dashboard-lint/type-check/test/build/audit]
lint & tc & test & pa & dl & dash --> gate[ci-pass gate]
Push_main[Push to main] --> scorecard[scorecard.yml]
scorecard --> sc_run[ossf/scorecard-action]
sc_run --> sc_sarif[Upload SARIF → Security tab]
Push_main --> dast[dast.yml]
dast --> build[Build backend image]
build --> start[Start backend container]
start --> health{Healthy?}
health -- Yes --> zap[ZAP API Scan\ntarget: /docs/openapi.json]
health -- No --> fail[Fail with logs]
zap --> stop[Stop backend]
schedule[Weekly schedule] --> pa_weekly[python-audit.yml: pip-audit]
schedule --> scorecard
schedule --> dast
Local[Local developer] --> pre_commit[pre-commit hooks\nruff, gitleaks, hadolint-docker]
Local --> pre_push[pre-push hooks\nmypy + pytest -m unit]
Prompt To Fix All With AIThis is a comment left during a code review.
Path: .pre-commit-config.yaml
Line: 44-47
Comment:
**Hadolint version mismatch between pre-commit hook and CI action**
The pre-commit hook pins `hadolint v2.12.0` (which pulls the `hadolint/hadolint:v2.12.0` Docker image locally), while the CI `dockerfile-lint` job uses `hadolint/hadolint-action@v3.3.0`, which internally bundles a newer hadolint binary. If the bundled versions differ — and `v2.12.0` is a 2022 release — rules may have changed enough that local linting passes while CI fails (or vice versa), creating noisy developer friction.
Consider pinning the pre-commit hook to a more recent release to align with what the action bundles, or explicitly configure the action with `hadolint-version` to match the pre-commit pin:
```yaml
- name: Lint backend Dockerfile
uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
with:
dockerfile: docker/backend/Dockerfile
hadolint-version: 2.12.0
```
If alignment is not possible, a comment documenting the intentional version difference would help future contributors.
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: d5c45a7 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/SECURITY.md:
- Around line 60-61: Update the Zizmor bullet to clarify SARIF upload is limited
to push/non-fork contexts: change the current line about "Zizmor static analysis
(SARIF to Security tab)" to explicitly state SARIF is uploaded only on push
events or non-fork runs because fork PRs do not have the required
security-events: write permission; reference the zizmor.yml workflow behavior
and mention the security-events: write limitation so the doc no longer implies
SARIF is uploaded for fork PRs.
In @.github/workflows/dast.yml:
- Around line 13-14: The concurrency group currently uses `${{ github.sha }}`
which makes each commit produce a unique group and prevents serialization;
update the `group` value in the concurrency block (replace `group: ${{
github.workflow }}-${{ github.sha }}`) to a constant or workflow-level key such
as just `${{ github.workflow }}` or a fixed string (e.g., `dast-scan`) so that
`cancel-in-progress: false` will actually serialize DAST runs across commits;
keep the `cancel-in-progress` setting as intended.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2f413e1a-27b4-46c1-a629-a89e3702b7ac
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
.github/SECURITY.md.github/workflows/ci.yml.github/workflows/dast.yml.github/workflows/python-audit.yml.github/workflows/scorecard.yml.pre-commit-config.yamlCLAUDE.mdREADME.mdpyproject.toml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Agent
- GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (3)
*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Use Markdown format; place docs in
docs/directory (built with Zensical); design spec indocs/design/with 7 pages: index, agents, organization, communication, engine, memory, operations
Files:
README.mdCLAUDE.md
.github/workflows/*.yml
📄 CodeRabbit inference engine (CLAUDE.md)
All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch
Files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/dast.yml.github/workflows/python-audit.yml
pyproject.toml
📄 CodeRabbit inference engine (CLAUDE.md)
Pin all dependency versions using
==(exact versions, no ranges). Organize into groups:test,dev(includes test + linting/type-checking tools),docs. Useuv syncto install all dependencies.
Files:
pyproject.toml
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Docker workflow (`.github/workflows/docker.yml`): builds backend + web images, pushes to GHCR, signs with cosign. Scans: Trivy (CRITICAL = fail, HIGH = warn) + Grype (critical cutoff). CVE triage via `.github/.trivyignore.yaml` and `.github/.grype.yaml`. Images only pushed after scans pass. Triggers on push to main and version tags (`v*`).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Coverage: 80% minimum.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Workflow security: `.github/workflows/zizmor.yml` — static analysis of GitHub Actions workflows on push to main and PRs. SARIF upload to Security tab on push events only (fork PRs lack `security-events: write`).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Pre-commit hooks enforce: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Dependabot: daily uv + github-actions + docker updates, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to .github/workflows/*.yml : All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Workflow security: `.github/workflows/zizmor.yml` — static analysis of GitHub Actions workflows on push to main and PRs. SARIF upload to Security tab on push events only (fork PRs lack `security-events: write`).
Applied to files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/dast.ymlCLAUDE.md.github/SECURITY.md.github/workflows/python-audit.yml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to .github/workflows/*.yml : All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch
Applied to files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/dast.ymlCLAUDE.md.github/SECURITY.md.github/workflows/python-audit.yml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Pages workflow (`.github/workflows/pages.yml`): exports OpenAPI schema (`scripts/export_openapi.py`), builds Astro landing + Zensical docs, merges, deploys to GitHub Pages on push to main. Triggers on docs/site/config/source/script changes and `workflow_dispatch`.
Applied to files:
.github/workflows/scorecard.yml.github/workflows/dast.ymlCLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Docker workflow (`.github/workflows/docker.yml`): builds backend + web images, pushes to GHCR, signs with cosign. Scans: Trivy (CRITICAL = fail, HIGH = warn) + Grype (critical cutoff). CVE triage via `.github/.trivyignore.yaml` and `.github/.grype.yaml`. Images only pushed after scans pass. Triggers on push to main and version tags (`v*`).
Applied to files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/dast.ymlCLAUDE.md.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Secret scanning: gitleaks workflow on push/PR + weekly schedule
Applied to files:
.github/workflows/scorecard.yml.github/workflows/dast.ymlCLAUDE.md.github/SECURITY.md.github/workflows/python-audit.yml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Coverage: Codecov integration — coverage upload via `codecov-action` + test results analytics via `test-results-action` (both best-effort, CI not gated on Codecov availability)
Applied to files:
.github/workflows/scorecard.ymlCLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Dependabot: daily uv + github-actions + docker updates, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
Applied to files:
.github/workflows/ci.ymlCLAUDE.md.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Coverage: 80% minimum.
Applied to files:
.github/workflows/ci.ymlCLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Git commits: `<type>: <description>` where types are: feat, fix, refactor, docs, test, chore, perf, ci. Enforced by commitizen (commit-msg hook). Use branches: `<type>/<slug>` from main.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Pre-commit hooks enforce: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks
Applied to files:
CLAUDE.md.pre-commit-config.yamlpyproject.toml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: NEVER create a PR directly — use `/pre-pr-review` to create PRs (runs automated checks + review agents + fixes before creating PR). For trivial/docs-only: `/pre-pr-review quick` skips agents but still runs checks. After PR exists, use `/aurelio-review-pr` for external feedback. `/commit-push-pr` is effectively blocked.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: GitHub issue queries: use `gh issue list` via Bash (not MCP tools) — MCP `list_issues` has unreliable field data
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: After finishing an issue implementation: create a feature branch (`<type>/<slug>`), commit, and push — do NOT create a PR automatically. Do NOT leave work uncommitted on main.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: PR Preview workflow (`.github/workflows/pages-preview.yml`): builds site on PRs, injects "Development Preview" banner, deploys to Cloudflare Pages at `pr-<number>.synthorg-pr-preview.pages.dev`. Validates PR metadata, skips deploy on fork PRs, cleans up on PR close.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Release workflow (`.github/workflows/release.yml`): Release Please auto-creates release PR on every push to main. Merging the release PR creates git tag (`vX.Y.Z`) + GitHub Release with changelog. Tag push triggers Docker workflow. Uses `RELEASE_PLEASE_TOKEN` secret so tag creation triggers downstream workflows.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to pyproject.toml : Pin all dependency versions using `==` (exact versions, no ranges). Organize into groups: `test`, `dev` (includes test + linting/type-checking tools), `docs`. Use `uv sync` to install all dependencies.
Applied to files:
pyproject.toml
🪛 Checkov (3.2.508)
.github/workflows/dast.yml
[low] 42-43: Base64 High Entropy String
(CKV_SECRET_6)
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~223-~223: The official name of this software platform is spelled with a capital “H”.
Context: ... PRs before merging - Python audit: .github/workflows/python-audit.yml — weekly pi...
(GITHUB)
[uncategorized] ~229-~229: The official name of this software platform is spelled with a capital “H”.
Context: ... availability) - Workflow security: .github/workflows/zizmor.yml — zizmor static a...
(GITHUB)
[uncategorized] ~230-~230: The official name of this software platform is spelled with a capital “H”.
Context: ...y-events: write) - **OSSF Scorecard**: .github/workflows/scorecard.yml` — supply chain...
(GITHUB)
🔇 Additional comments (9)
README.md (1)
15-15: Scorecard badge addition looks correct.The badge URL and viewer link are valid and consistent with the new Scorecard workflow exposure.
pyproject.toml (1)
61-61: Pinnedpip-auditdependency is correctly added todev.This is consistent with the new audit workflow and keeps dependency pinning strict.
As per coding guidelines "Pin all dependency versions using
==(exact versions, no ranges). Organize into groups:test,dev(includes test + linting/type-checking tools),docs.".github/workflows/dast.yml (1)
10-11: Workflow hardening details are well implemented.Scoped permissions, SHA-pinned actions, and guaranteed teardown (
if: always()) are all strong choices.As per coding guidelines "All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch."
Also applies to: 20-23, 24-27, 59-69, 71-73
.github/workflows/python-audit.yml (1)
8-23: Python audit workflow is clean and secure-by-default.Least-privilege permissions and pinned checkout are correctly applied.
As per coding guidelines "All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch."
.pre-commit-config.yaml (1)
6-8: Pre-push gate integration is well structured.Installing
pre-pushby default plus localmypy/pytesthooks gives a strong fast-fail developer gate, and hadolint integration is consistent with CI hardening.Based on learnings "Pre-commit hooks enforce: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks."
Also applies to: 44-63
.github/workflows/scorecard.yml (1)
10-37: Scorecard workflow follows strong security hygiene.Permissions are explicitly scoped, and third-party actions are SHA-pinned throughout.
As per coding guidelines "All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch."
CLAUDE.md (1)
184-188: CI/security documentation updates are aligned with the implementation.The added sections accurately reflect the new hardening workflows and local hook behavior introduced in this PR.
Based on learnings "CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Coverage: 80% minimum."
Also applies to: 207-207, 223-232
.github/workflows/ci.yml (1)
179-217: New CI jobs are correctly integrated into the required gate.
python-auditanddockerfile-lintare properly added and enforced throughci-pass, including result aggregation and failure reporting.Based on learnings "CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Coverage: 80% minimum."
Also applies to: 241-268
.github/SECURITY.md (1)
62-64: Documentation of workflow security controls is accurate and comprehensive.Verification confirms all workflows in the repository follow the stated security practices: all actions are pinned to full SHA, all
actions/checkoutsteps includepersist-credentials: false, and all workflows definepermissions: {}with least-privilege per job. The documentation at lines 62–64 correctly reflects the actual state of the repository.
…ooks - Add pip-audit to CI (python-audit job) and weekly scheduled workflow - Add hadolint CI job (dockerfile-lint) for all 3 Dockerfiles + pre-commit hook - Add OSSF Scorecard workflow with SARIF upload to Security tab - Add ZAP API scan workflow (DAST) with SARIF upload, push to main + weekly - Add pre-push hooks for mypy type-check and unit test gate - Update ci-pass gate to include python-audit and dockerfile-lint jobs - Update CLAUDE.md CI section with all new and existing security tooling - Expand SECURITY.md with full infrastructure security documentation - Add OpenSSF Scorecard badge to README.md
There was a problem hiding this comment.
Pull request overview
This PR strengthens the repo’s security posture by adding automated dependency/container/workflow scanning and local developer “fast gate” hooks, plus updating documentation to reflect the new tooling and CI requirements.
Changes:
- Add pip-audit and hadolint to CI (and add pip-audit as a weekly scheduled workflow).
- Add OpenSSF Scorecard (weekly + push-to-main) and ZAP API DAST (weekly + push-to-main) workflows with SARIF uploads.
- Add pre-push hooks (mypy + unit tests) and update docs/README to document the security tooling and policies.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Adds pip-audit and its transitive dependencies to the locked dev environment. |
pyproject.toml |
Adds pip-audit==2.9.0 to the dev dependency group. |
README.md |
Adds an OpenSSF Scorecard badge. |
CLAUDE.md |
Documents new CI jobs, security workflows, and pre-push hooks. |
.pre-commit-config.yaml |
Adds hadolint hook and local pre-push hooks for mypy + unit tests; enables pre-push hook installation. |
.github/workflows/scorecard.yml |
New Scorecard workflow with SARIF upload. |
.github/workflows/python-audit.yml |
New scheduled pip-audit workflow. |
.github/workflows/dast.yml |
New ZAP API DAST workflow (push-to-main + scheduled) with SARIF upload. |
.github/workflows/ci.yml |
Adds python-audit and dockerfile-lint jobs and updates ci-pass to gate on them. |
.github/SECURITY.md |
Reorganizes and expands security documentation to include new scanners/workflows. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/dast.yml
Outdated
| - name: ZAP API Scan | ||
| uses: zaproxy/action-api-scan@5158fe4d9d8fcc75ea204db81317cce7f9e5453d # v0.10.0 | ||
| with: | ||
| target: http://localhost:8000/openapi.json |
.github/workflows/dast.yml
Outdated
| permissions: {} | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.sha }} |
| - name: Start backend | ||
| run: docker compose -f docker/compose.yml up -d backend |
.github/workflows/dast.yml
Outdated
| # Build backend image locally (no push, no registry credentials) | ||
| - name: Build backend image | ||
| run: docker compose -f docker/compose.yml build backend | ||
|
|
||
| # Start backend only (no web/nginx needed for API scan) | ||
| - name: Start backend | ||
| run: docker compose -f docker/compose.yml up -d backend | ||
| env: | ||
| AI_COMPANY_JWT_SECRET: "ci-dast-scan-only" | ||
| AI_COMPANY_API_KEY_SECRET: "ci-dast-scan-only" |
…iewers DAST workflow: - Fix ZAP target URL (/openapi.json → /docs/openapi.json) - Fix concurrency group (github.sha → github.workflow) for serialization - Remove unused export_openapi.py + setup-python-uv steps - Create docker/.env from example before compose up - Remove step-level env vars that don't reach the container Pre-commit: - Add hadolint-docker to ci.skip (Docker hooks break pre-commit.ci) Docs: - SECURITY.md: Mark CodeQL as disabled (repo rename cache issue) - SECURITY.md: Clarify Zizmor SARIF is push-only (fork PRs lack permissions) - CLAUDE.md: Add pip-audit to dev dependency group listing - CLAUDE.md: Fix web/src/components/ to match actual dirs (common/, layout/) Pre-reviewed by 2 local agents + 4 external reviewers, 11 findings addressed
e2959cd to
50ad823
Compare
CodeQL is working fine — the PR #290 cache issue was already resolved.
There was a problem hiding this comment.
Pull request overview
Adds multiple security-focused CI workflows and local Git hook tooling to improve supply-chain, container, and runtime security checks across the project.
Changes:
- Introduces pip-audit and hadolint into CI (and wires them into the
ci-passgate). - Adds new scheduled/security workflows: OSSF Scorecard (SARIF) and ZAP DAST against the backend OpenAPI spec (SARIF).
- Updates developer tooling/docs: pre-push hooks (mypy + unit tests), security documentation, and README badge.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Locks new transitive deps for pip-audit and adds it to the dev group lock set. |
pyproject.toml |
Adds pip-audit to the dev dependency group. |
README.md |
Adds an OpenSSF Scorecard badge link. |
CLAUDE.md |
Documents new CI jobs and local hook expectations (pre-commit + pre-push), plus security tooling. |
.pre-commit-config.yaml |
Adds hadolint hook; adds local pre-push hooks for mypy + unit pytest; updates pre-commit.ci skip + default install hook types. |
.github/workflows/scorecard.yml |
New OSSF Scorecard workflow with SARIF upload. |
.github/workflows/python-audit.yml |
New scheduled pip-audit workflow. |
.github/workflows/dast.yml |
New ZAP API scan workflow against /docs/openapi.json with SARIF upload. |
.github/workflows/ci.yml |
Adds python-audit and dockerfile-lint jobs and makes ci-pass depend on them. |
.github/SECURITY.md |
Reorganizes and expands security documentation to include the new tooling/workflows. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/dast.yml
Outdated
| # Build backend image locally (no push, no registry credentials) | ||
| - name: Build backend image | ||
| run: docker compose -f docker/compose.yml build backend | ||
|
|
||
| # Create env file from example (compose requires env_file: .env) | ||
| - name: Create env file | ||
| run: cp docker/.env.example docker/.env | ||
|
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/dast.yml:
- Around line 60-64: The Upload SARIF step named "Upload SARIF" is pointing to
the wrong output filename from the zaproxy/action-api-scan step; update the
sarif_file input in that step to match the scan's actual output
("report_json.json") or else insert a conversion step that produces SARIF before
upload; locate the "Upload SARIF" job/step in the workflow and change the
sarif_file value from report_sarif.json to report_json.json (or add a conversion
action after zaproxy/action-api-scan to emit report_sarif.json and keep the
uploader as-is).
In `@CLAUDE.md`:
- Line 187: Update the "**Pre-push hooks**" line to clarify that the omission
applies only to pre-commit.ci and not to the CI pipeline: revise the sentence so
it states these checks (mypy type-check + pytest unit tests) are fast local
pre-push gates run by pre-commit, that pre-commit.ci does not run them on the
remote pre-commit CI runner, and that the main CI still executes dedicated
mypy/pytest jobs; replace the current ambiguous wording with a brief sentence
conveying this distinction.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 11fa0ec5-b86e-4955-b7cd-282f56abc4a2
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
.github/SECURITY.md.github/workflows/ci.yml.github/workflows/dast.yml.github/workflows/python-audit.yml.github/workflows/scorecard.yml.pre-commit-config.yamlCLAUDE.mdREADME.mdpyproject.toml
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
.github/workflows/*.yml
📄 CodeRabbit inference engine (CLAUDE.md)
All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch
Files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/python-audit.yml.github/workflows/dast.yml
*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Use Markdown format; place docs in
docs/directory (built with Zensical); design spec indocs/design/with 7 pages: index, agents, organization, communication, engine, memory, operations
Files:
README.mdCLAUDE.md
pyproject.toml
📄 CodeRabbit inference engine (CLAUDE.md)
Pin all dependency versions using
==(exact versions, no ranges). Organize into groups:test,dev(includes test + linting/type-checking tools),docs. Useuv syncto install all dependencies.
Files:
pyproject.toml
🧠 Learnings (21)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Coverage: 80% minimum.
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Docker workflow (`.github/workflows/docker.yml`): builds backend + web images, pushes to GHCR, signs with cosign. Scans: Trivy (CRITICAL = fail, HIGH = warn) + Grype (critical cutoff). CVE triage via `.github/.trivyignore.yaml` and `.github/.grype.yaml`. Images only pushed after scans pass. Triggers on push to main and version tags (`v*`).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Workflow security: `.github/workflows/zizmor.yml` — static analysis of GitHub Actions workflows on push to main and PRs. SARIF upload to Security tab on push events only (fork PRs lack `security-events: write`).
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Pre-commit hooks enforce: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Dependabot: daily uv + github-actions + docker updates, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Workflow security: `.github/workflows/zizmor.yml` — static analysis of GitHub Actions workflows on push to main and PRs. SARIF upload to Security tab on push events only (fork PRs lack `security-events: write`).
Applied to files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/python-audit.ymlCLAUDE.md.github/workflows/dast.yml.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Pages workflow (`.github/workflows/pages.yml`): exports OpenAPI schema (`scripts/export_openapi.py`), builds Astro landing + Zensical docs, merges, deploys to GitHub Pages on push to main. Triggers on docs/site/config/source/script changes and `workflow_dispatch`.
Applied to files:
.github/workflows/scorecard.ymlCLAUDE.md.github/workflows/dast.yml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to .github/workflows/*.yml : All GitHub Actions workflows must follow security best practices: use minimal permissions, pin actions to commit SHAs or semantic versions, avoid secrets in logs, validate inputs on dispatch
Applied to files:
.github/workflows/scorecard.yml.github/workflows/ci.yml.github/workflows/python-audit.ymlCLAUDE.md.github/workflows/dast.yml.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Docker workflow (`.github/workflows/docker.yml`): builds backend + web images, pushes to GHCR, signs with cosign. Scans: Trivy (CRITICAL = fail, HIGH = warn) + Grype (critical cutoff). CVE triage via `.github/.trivyignore.yaml` and `.github/.grype.yaml`. Images only pushed after scans pass. Triggers on push to main and version tags (`v*`).
Applied to files:
.github/workflows/scorecard.yml.github/workflows/ci.ymlCLAUDE.md.github/workflows/dast.yml.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Secret scanning: gitleaks workflow on push/PR + weekly schedule
Applied to files:
.github/workflows/scorecard.yml.github/workflows/python-audit.yml.github/workflows/dast.yml.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Coverage: Codecov integration — coverage upload via `codecov-action` + test results analytics via `test-results-action` (both best-effort, CI not gated on Codecov availability)
Applied to files:
.github/workflows/scorecard.ymlCLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Dependabot: daily uv + github-actions + docker updates, grouped minor/patch, no auto-merge. Use `/review-dep-pr` to review Dependabot PRs before merging.
Applied to files:
.github/workflows/ci.ymlCLAUDE.md.github/workflows/dast.yml.github/SECURITY.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: CI jobs: lint (ruff) + type-check (mypy src/ tests/) + test (pytest + coverage) run in parallel → ci-pass (gate). Coverage: 80% minimum.
Applied to files:
.github/workflows/ci.ymlCLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to web/package.json : Web dashboard dependencies: Vue 3, PrimeVue, Tailwind CSS, Pinia, VueFlow, ECharts, Axios, vue-draggable-plus, Vitest, ESLint, vue-tsc. Requires Node.js 20+.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to web/src/**/*.{ts,tsx,vue} : Vue 3 + TypeScript type hints: all public functions and components require type annotations
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Git commits: `<type>: <description>` where types are: feat, fix, refactor, docs, test, chore, perf, ci. Enforced by commitizen (commit-msg hook). Use branches: `<type>/<slug>` from main.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Pre-commit hooks enforce: trailing-whitespace, end-of-file-fixer, check-yaml, check-toml, check-json, check-merge-conflict, check-added-large-files, no-commit-to-branch (main), ruff check+format, gitleaks
Applied to files:
CLAUDE.mdpyproject.toml.pre-commit-config.yaml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: NEVER create a PR directly — use `/pre-pr-review` to create PRs (runs automated checks + review agents + fixes before creating PR). For trivial/docs-only: `/pre-pr-review quick` skips agents but still runs checks. After PR exists, use `/aurelio-review-pr` for external feedback. `/commit-push-pr` is effectively blocked.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: GitHub issue queries: use `gh issue list` via Bash (not MCP tools) — MCP `list_issues` has unreliable field data
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: After finishing an issue implementation: create a feature branch (`<type>/<slug>`), commit, and push — do NOT create a PR automatically. Do NOT leave work uncommitted on main.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: PR Preview workflow (`.github/workflows/pages-preview.yml`): builds site on PRs, injects "Development Preview" banner, deploys to Cloudflare Pages at `pr-<number>.synthorg-pr-preview.pages.dev`. Validates PR metadata, skips deploy on fork PRs, cleans up on PR close.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Release workflow (`.github/workflows/release.yml`): Release Please auto-creates release PR on every push to main. Merging the release PR creates git tag (`vX.Y.Z`) + GitHub Release with changelog. Tag push triggers Docker workflow. Uses `RELEASE_PLEASE_TOKEN` secret so tag creation triggers downstream workflows.
Applied to files:
CLAUDE.md.github/workflows/dast.yml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to docker/Dockerfile* : Docker backend build: use 3-stage build (builder → setup → distroless runtime), Chainguard Python, non-root user (UID 65532), CIS-hardened image. Web: use `nginxinc/nginx-unprivileged`.
Applied to files:
CLAUDE.md
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to docker/compose.yml : Docker Compose: define backend and web services with proper networking, environment variable loading from `.env`, and health checks
Applied to files:
.github/workflows/dast.yml
📚 Learning: 2026-03-13T12:43:09.295Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T12:43:09.295Z
Learning: Applies to tests/**/*.py : Use pytest markers: `pytest.mark.unit`, `pytest.mark.integration`, `pytest.mark.e2e`, `pytest.mark.slow`
Applied to files:
.pre-commit-config.yaml
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~223-~223: The official name of this software platform is spelled with a capital “H”.
Context: ... PRs before merging - Python audit: .github/workflows/python-audit.yml — weekly pi...
(GITHUB)
[uncategorized] ~229-~229: The official name of this software platform is spelled with a capital “H”.
Context: ... availability) - Workflow security: .github/workflows/zizmor.yml — zizmor static a...
(GITHUB)
[uncategorized] ~230-~230: The official name of this software platform is spelled with a capital “H”.
Context: ...y-events: write) - **OSSF Scorecard**: .github/workflows/scorecard.yml` — supply chain...
(GITHUB)
[uncategorized] ~233-~233: The official name of this software platform is spelled with a capital “H”.
Context: ...kflows (GITHUB_TOKEN cannot). Config in .github/release-please-config.json and `.githu...
(GITHUB)
[uncategorized] ~233-~233: The official name of this software platform is spelled with a capital “H”.
Context: ....github/release-please-config.jsonand.github/.release-please-manifest.json`. ## Dep...
(GITHUB)
🔇 Additional comments (9)
README.md (1)
15-15: OpenSSF Scorecard badge addition is clean and aligned with the new workflow.pyproject.toml (1)
61-61: Pinnedpip-auditindevgroup is correctly implemented..pre-commit-config.yaml (1)
6-8: Pre-push and Dockerfile lint hook wiring looks consistent and well-scoped.Also applies to: 44-63
.github/workflows/python-audit.yml (1)
1-23: Workflow security posture is solid (least privilege + pinned checkout + isolated audit job)..github/workflows/scorecard.yml (1)
1-37: Scorecard workflow is correctly hardened and well configured..github/SECURITY.md (1)
35-70: Security policy restructuring is clear and aligns with the new CI/security controls..github/workflows/ci.yml (3)
179-191: LGTM!The
python-auditjob correctly follows security best practices:
- Minimal permissions (
contents: read)- Checkout action pinned to SHA with
persist-credentials: false- Uses the shared
setup-python-uvcomposite action for consistency
241-268: LGTM!The
ci-passgate correctly:
- Includes
python-auditanddockerfile-lintin theneedsarray- Exposes their results as environment variables
- Checks their status in the failure condition
- Reports their status in the failure message
This ensures the new security checks are required for PRs to merge. As per coding guidelines, minimal permissions (
permissions: {}) are correctly maintained.
193-216: LGTM! Follows security best practices.The
dockerfile-lintjob is well-structured:
- Minimal permissions (
contents: read)- Checkout and hadolint actions pinned to SHAs with version comments
- Running hadolint separately per Dockerfile provides clear failure attribution
.github/workflows/dast.yml
Outdated
| - name: Upload SARIF | ||
| if: ${{ !cancelled() }} | ||
| uses: github/codeql-action/upload-sarif@820e3160e279568db735cee8ed8f8e77a6da7818 # v3.32.6 | ||
| with: | ||
| sarif_file: report_sarif.json |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ACTION_SHA="5158fe4d9d8fcc75ea204db81317cce7f9e5453d"
RAW_URL="https://raw.githubusercontent.com/zaproxy/action-api-scan/${ACTION_SHA}/index.js"
echo "== ZAP action output filenames from pinned SHA =="
curl -fsSL "$RAW_URL" | tr ';' '\n' | rg -n "report_.*\\.(json|md|html)|zap-api-scan.py"
echo "== Workflow upload target =="
rg -n "sarif_file:|report_sarif|report_json" .github/workflows/dast.ymlRepository: Aureliolo/synthorg
Length of output: 460
SARIF upload target mismatches ZAP action output.
The pinned zaproxy/action-api-scan implementation produces report_json.json, but the upload step is configured for report_sarif.json. This file mismatch will cause the upload step to fail and prevent Security-tab ingestion.
Update line 64 to use the correct filename:
sarif_file: report_json.json
Alternatively, if you need SARIF format specifically, add an explicit conversion step after the scan.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/dast.yml around lines 60 - 64, The Upload SARIF step named
"Upload SARIF" is pointing to the wrong output filename from the
zaproxy/action-api-scan step; update the sarif_file input in that step to match
the scan's actual output ("report_json.json") or else insert a conversion step
that produces SARIF before upload; locate the "Upload SARIF" job/step in the
workflow and change the sarif_file value from report_sarif.json to
report_json.json (or add a conversion action after zaproxy/action-api-scan to
emit report_sarif.json and keep the uploader as-is).
DAST workflow: - Move env file creation before docker compose build (Copilot) - Remove SARIF upload — action v0.10.0 only outputs JSON/MD/HTML (CodeRabbit) - Remove security-events: write (no longer needed without SARIF upload) - Add comment documenting -a flag intent for alpha scan rules (Greptile) Docs: - CLAUDE.md: clarify pre-push hooks "skipped in pre-commit.ci" not "CI" (CodeRabbit) - CLAUDE.md: update DAST description (no SARIF, artifact-only) - SECURITY.md: update DAST section (SARIF planned, not current)
| - uses: ./.github/actions/setup-python-uv | ||
|
|
||
| - name: pip-audit | ||
| run: uv run pip-audit |
There was a problem hiding this comment.
pip-audit blocks CI on any severity CVE
uv run pip-audit exits non-zero on any discovered vulnerability, including low/informational severity and CVEs in dev-only packages (mypy, pytest, ruff, etc.). By contrast, the dashboard audit uses npm audit --audit-level=high, which only fails on high/critical findings. This inconsistency means a low-severity CVE in, say, pytest could block all PRs until the dependency is bumped or the CVE is suppressed.
Consider aligning the threshold to the project's intended security bar:
| run: uv run pip-audit | |
| - name: pip-audit | |
| run: uv run pip-audit --severity medium |
Or, if scanning all severities is intentional (stricter policy for Python than Node), a brief comment documenting that intent would help future contributors understand why the two audits have different thresholds.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/ci.yml
Line: 191
Comment:
**pip-audit blocks CI on any severity CVE**
`uv run pip-audit` exits non-zero on *any* discovered vulnerability, including low/informational severity and CVEs in dev-only packages (mypy, pytest, ruff, etc.). By contrast, the dashboard audit uses `npm audit --audit-level=high`, which only fails on high/critical findings. This inconsistency means a low-severity CVE in, say, `pytest` could block all PRs until the dependency is bumped or the CVE is suppressed.
Consider aligning the threshold to the project's intended security bar:
```suggestion
- name: pip-audit
run: uv run pip-audit --severity medium
```
Or, if scanning all severities is intentional (stricter policy for Python than Node), a brief comment documenting that intent would help future contributors understand why the two audits have different thresholds.
How can I resolve this? If you propose a fix, please make it concise.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!
Pin the non-blocking behavior so it's resilient to action default changes.
There was a problem hiding this comment.
Pull request overview
This PR strengthens the repo’s security posture by adding CI and local hook automation for dependency auditing, Dockerfile linting, supply-chain scoring, and scheduled DAST scanning, plus updating related documentation.
Changes:
- Add
pip-auditandhadolintto CI (and add a weekly scheduledpip-auditworkflow). - Add new security workflows: OSSF Scorecard (SARIF) and ZAP DAST (scheduled + on main).
- Add pre-push hooks (mypy + pytest unit) and update docs/badges to reflect the new tooling and CI gate requirements.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Locks pip-audit and its transitive dependencies. |
pyproject.toml |
Adds pip-audit to the dev dependency group. |
README.md |
Adds an OpenSSF Scorecard badge. |
CLAUDE.md |
Documents new CI jobs, hooks, and security tooling expectations. |
.pre-commit-config.yaml |
Adds hadolint (pre-commit) and mypy/pytest (pre-push) hooks; configures pre-commit.ci skipping appropriately. |
.github/workflows/scorecard.yml |
Adds scheduled + main-branch OSSF Scorecard with SARIF upload. |
.github/workflows/python-audit.yml |
Adds scheduled weekly pip-audit workflow. |
.github/workflows/dast.yml |
Adds scheduled + main-branch ZAP API scan against OpenAPI. |
.github/workflows/ci.yml |
Adds python-audit + dockerfile-lint jobs and updates the ci-pass gate to require them. |
.github/SECURITY.md |
Reorganizes and expands documentation for the new security controls and workflows. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🤖 I have created a release *beep* *boop* --- ## [0.1.3](v0.1.2...v0.1.3) (2026-03-13) ### Features * add Mem0 memory backend adapter ([#345](#345)) ([2788db8](2788db8)), closes [#206](#206) * centralized single-writer TaskEngine with full CRUD API ([#328](#328)) ([9c1a3e1](9c1a3e1)) * incremental AgentEngine → TaskEngine status sync ([#331](#331)) ([7a68d34](7a68d34)), closes [#323](#323) * web dashboard pages — views, components, tests, and review fixes ([#354](#354)) ([b165ec4](b165ec4)) * web dashboard with Vue 3 + PrimeVue + Tailwind CSS ([#347](#347)) ([06416b1](06416b1)) ### Bug Fixes * harden coordination pipeline with validators, logging, and fail-fast ([#333](#333)) ([2f10d49](2f10d49)), closes [#205](#205) * repo-wide security hardening from ZAP, Scorecard, and CodeQL audit ([#357](#357)) ([27eb288](27eb288)) ### CI/CD * add pip-audit, hadolint, OSSF Scorecard, ZAP DAST, and pre-push hooks ([#350](#350)) ([2802d20](2802d20)) * add workflow_dispatch trigger to PR Preview for Dependabot PRs ([#326](#326)) ([4c7b6d9](4c7b6d9)) * bump astral-sh/setup-uv from 7.4.0 to 7.5.0 in the minor-and-patch group ([#335](#335)) ([98dd8ca](98dd8ca)) ### Maintenance * bump the minor-and-patch group across 1 directory with 3 updates ([#352](#352)) ([031b1c9](031b1c9)) * **deps:** bump devalue from 5.6.3 to 5.6.4 in /site in the npm_and_yarn group across 1 directory ([#324](#324)) ([9a9c600](9a9c600)) * migrate docs build from MkDocs to Zensical ([#330](#330)) ([fa8bf1d](fa8bf1d)), closes [#329](#329) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Summary
python-auditjob) and as weekly scheduled workflow for Python dependency vulnerability scanningdockerfile-lintjob) and as pre-commit hook for Dockerfile linting (backend, web, sandbox)ci-passgate updated to requirepython-auditanddockerfile-lintjobsTest plan
python-auditanddockerfile-lintjobs run successfullyci-passgate correctly requires all jobs including new onespre-commit install --hook-type pre-push)Review coverage
Auto-skipped agent review (no Python source code changes — CI/docs/config only).