Skip to content

ci: add pip-audit, hadolint, OSSF Scorecard, ZAP DAST, and pre-push hooks#350

Merged
Aureliolo merged 6 commits intomainfrom
ci/security-hardening
Mar 13, 2026
Merged

ci: add pip-audit, hadolint, OSSF Scorecard, ZAP DAST, and pre-push hooks#350
Aureliolo merged 6 commits intomainfrom
ci/security-hardening

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • pip-audit added to CI (python-audit job) and as weekly scheduled workflow for Python dependency vulnerability scanning
  • hadolint added to CI (dockerfile-lint job) and as pre-commit hook for Dockerfile linting (backend, web, sandbox)
  • OSSF Scorecard workflow for supply chain maturity scoring (push to main + weekly, SARIF to Security tab)
  • ZAP DAST workflow for API security scanning against backend OpenAPI spec (push to main + weekly, SARIF to Security tab)
  • Pre-push hooks added: mypy type-check + pytest unit tests as fast gate before push (skipped in pre-commit.ci — dedicated CI jobs already run these)
  • Socket.dev documented in CLAUDE.md and SECURITY.md (GitHub App, no config file needed)
  • Signed commits documented in CLAUDE.md (required on main via branch protection)
  • OpenSSF Scorecard badge added to README.md
  • SECURITY.md reorganized into categorized sections (application, dependency/supply chain, container/infra, workflow, DAST)
  • CLAUDE.md updated with all new CI jobs, hooks, and security tooling
  • ci-pass gate updated to require python-audit and dockerfile-lint jobs

Test plan

  • CI passes: new python-audit and dockerfile-lint jobs run successfully
  • Existing CI jobs unaffected (lint, type-check, test, dashboard-*)
  • ci-pass gate correctly requires all jobs including new ones
  • OSSF Scorecard workflow syntax valid (will run on merge to main)
  • DAST workflow syntax valid (will run on merge to main)
  • Pre-push hooks work locally (pre-commit install --hook-type pre-push)
  • OpenSSF Scorecard badge renders in README

Review coverage

Auto-skipped agent review (no Python source code changes — CI/docs/config only).

Copilot AI review requested due to automatic review settings March 13, 2026 14:05
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 13, 2026

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ✅ 0 package(s) with unknown licenses.
  • ⚠️ 1 packages with OpenSSF Scorecard issues.
See the Details below.

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
actions/actions/checkout de0fac2e4500dabe0009e67214ff5f5447ce83dd 🟢 5.9
Details
CheckScoreReason
Maintained⚠️ 23 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Packaging⚠️ -1packaging workflow not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST🟢 8SAST tool detected but not run on all commits
actions/github/codeql-action/upload-sarif 820e3160e279568db735cee8ed8f8e77a6da7818 UnknownUnknown
actions/ossf/scorecard-action 4eaacf0543bb3f2c246792bd56e8cdeffafb205a 🟢 9.1
Details
CheckScoreReason
Dependency-Update-Tool🟢 10update tool detected
Security-Policy🟢 10security policy file detected
Maintained🟢 1017 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Pinned-Dependencies🟢 9dependency not pinned by hash detected -- score normalized to 9
License🟢 10license file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Signed-Releases⚠️ -1no releases found
Packaging🟢 10packaging workflow detected
Vulnerabilities🟢 100 existing vulnerabilities detected
SAST🟢 10SAST tool is run on all commits
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
CI-Tests🟢 1030 out of 30 merged PRs checked by a CI test -- score normalized to 10
Contributors🟢 10project has 16 contributing companies or organizations
pip/boolean-py 5.0 ⚠️ 2.8
Details
CheckScoreReason
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review🟢 3Found 4/11 approved changesets -- score normalized to 3
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/cachecontrol 0.14.4 UnknownUnknown
pip/cyclonedx-python-lib 9.1.0 UnknownUnknown
pip/defusedxml 0.7.1 🟢 5.1
Details
CheckScoreReason
Code-Review⚠️ 0Found 2/24 approved changesets -- score normalized to 0
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy🟢 10security policy file detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing🟢 10project is fuzzed
License🟢 9license file detected
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/license-expression 30.4.4 UnknownUnknown
pip/msgpack 1.1.2 UnknownUnknown
pip/packageurl-python 0.17.6 🟢 3.9
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 6Found 5/8 approved changesets -- score normalized to 6
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 32 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 3
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies🟢 4dependency not pinned by hash detected -- score normalized to 4
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
License🟢 9license file detected
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Security-Policy⚠️ 0security policy file not detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/pip 26.0.1 UnknownUnknown
pip/pip-api 0.0.34 🟢 4.4
Details
CheckScoreReason
Code-Review🟢 8Found 16/19 approved changesets -- score normalized to 8
Maintained⚠️ 23 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 8binaries present in source code
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Packaging⚠️ -1packaging workflow not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases🟢 83 out of the last 3 releases have a total of 3 signed artifacts.
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/pip-audit 2.9.0 UnknownUnknown
pip/pip-requirements-parser 32.0.1 🟢 4.2
Details
CheckScoreReason
Code-Review🟢 3Found 1/3 approved changesets -- score normalized to 3
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 10security policy file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/py-serializable 2.1.0 UnknownUnknown
pip/pyparsing 3.3.2 UnknownUnknown
pip/sortedcontainers 2.4.0 UnknownUnknown
pip/toml 0.10.2 🟢 4.7
Details
CheckScoreReason
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review🟢 7Found 20/26 approved changesets -- score normalized to 7
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Fuzzing🟢 10project is fuzzed
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • .github/workflows/scorecard.yml
  • uv.lock

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 13, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Summary by CodeRabbit

  • Documentation

    • Reorganized SECURITY guidance into clear domains (application, dependencies, containers, workflows) and expanded tooling, cadence, and governance notes.
    • Added an OpenSSF Scorecard badge to the README.
  • New Features

    • Added scheduled and on-demand security workflows: DAST, weekly Python dependency audits, and Scorecard reporting.
  • Chores

    • CI and pre-push updated to include dependency auditing, Dockerfile linting, and enforcement of signed commits on main.

Walkthrough

Adds 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

Cohort / File(s) Summary
Security documentation & badges
/.github/SECURITY.md, CLAUDE.md, README.md
Rewrote SECURITY.md into categorized sections (application, dependencies, containers, workflows, DAST); updated CLAUDE.md to reflect CI/workflow/policy changes; added OpenSSF Scorecard badge to README.
New GitHub Actions workflows
.github/workflows/dast.yml, .github/workflows/python-audit.yml, .github/workflows/scorecard.yml
Added DAST workflow (build/start backend, health-check, ZAP API scan against /docs/openapi.json, cleanup), weekly Python audit workflow running pip-audit, and OSSF Scorecard workflow producing SARIF.
CI pipeline updates
.github/workflows/ci.yml
Added python-audit and dockerfile-lint jobs (pip-audit and hadolint), updated ci-pass to depend on them, exposed their result env vars, and updated failure messaging to include their outputs.
Linting & pre-commit
.pre-commit-config.yaml
Added hadolint hook and local hooks (mypy, pytest-unit) for pre-push; extended skip list and added pre-push install hook type.
Dev dependencies
pyproject.toml
Added pip-audit==2.9.0 to dev dependency group.
Dockerfiles targeted by CI
docker/backend/Dockerfile, docker/web/Dockerfile, docker/sandbox/Dockerfile
Added hadolint linting for these Dockerfiles in CI.`

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)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding pip-audit, hadolint, OSSF Scorecard, ZAP DAST, and pre-push hooks to CI workflows and pre-commit configuration.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing all security enhancements, CI workflow additions, hooks, documentation updates, and a test plan.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ci/security-hardening
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch ci/security-hardening
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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

  • Python Dependency Vulnerability Scanning: Integrated 'pip-audit' into CI as a dedicated job ('python-audit') and as a weekly scheduled workflow to scan Python dependencies for known vulnerabilities.
  • Dockerfile Linting: Added 'hadolint' to CI ('dockerfile-lint' job) and as a pre-commit hook to lint Dockerfiles across backend, web, and sandbox environments.
  • Supply Chain Maturity Scoring: Introduced an 'OSSF Scorecard' workflow to assess supply chain maturity, running on pushes to main and weekly, with SARIF results uploaded to the Security tab.
  • API Security Scanning: Implemented a 'ZAP DAST' workflow for Dynamic Application Security Testing against the backend OpenAPI specification, running on pushes to main and weekly, with SARIF results to the Security tab.
  • Pre-push Hooks: Added local pre-push hooks for 'mypy' type-checking and 'pytest' unit tests to act as a fast gate before pushing, skipping these in pre-commit.ci as dedicated CI jobs already run them.
  • Security Tooling Documentation: Documented 'Socket.dev' (GitHub App for supply chain attack detection) and the requirement for signed commits in CLAUDE.md and SECURITY.md.
  • OpenSSF Scorecard Badge: Added an OpenSSF Scorecard badge to README.md to visually represent supply chain security maturity.
  • SECURITY.md Reorganization: Reorganized SECURITY.md into categorized sections for better clarity on application, dependency/supply chain, container/infra, workflow, and DAST security measures.
  • CLAUDE.md Updates: Updated CLAUDE.md to reflect all new CI jobs, pre-commit/pre-push hooks, and security tooling.
  • CI Gate Requirements: Updated the ci-pass gate to require the successful completion of the new python-audit and dockerfile-lint jobs.
Changelog
  • .github/SECURITY.md
    • Reorganized security features into categorized sections for improved readability.
    • Added detailed descriptions for new security tools including pip-audit, npm audit, Socket.dev, Trivy, Grype, Cosign, Hadolint, Chainguard Python, Zizmor, OSSF Scorecard, ZAP API Scan, and signed commits.
    • Updated the description for Gitleaks to include its weekly CI workflow.
  • .pre-commit-config.yaml
    • Added 'mypy' and 'pytest-unit' to the skip list for pre-commit.ci to avoid redundant runs.
    • Included 'pre-push' in default_install_hook_types to enable pre-push checks.
    • Configured a 'hadolint-docker' hook for Dockerfile linting.
    • Added local 'mypy' type-check and 'pytest' unit test hooks for the 'pre-push' stage.
  • CLAUDE.md
    • Documented the requirement for signed commits on the main branch.
    • Added 'hadolint' to the list of pre-commit hooks.
    • Included 'mypy' type-check and 'pytest' unit tests as pre-push hooks.
    • Updated the list of CI jobs to include 'python-audit', 'dockerfile-lint', and 'dashboard-audit'.
    • Documented new CI workflows for Python auditing, Dockerfile linting, dashboard auditing, OSSF Scorecard, DAST, and Socket.dev integration.
  • README.md
    • Added an OpenSSF Scorecard badge to the project's README.
  • pyproject.toml
    • Added 'pip-audit' version 2.9.0 to the development dependencies.
  • uv.lock
    • Added new Python package dependencies including boolean-py, cachecontrol, cyclonedx-python-lib, defusedxml, license-expression, msgpack, packageurl-python, pip, pip-api, pip-audit, pip-requirements-parser, pyparsing, py-serializable, sortedcontainers, and toml.
    • Updated the dependency lock file to reflect the addition of 'pip-audit' and its transitive dependencies.
Ignored Files
  • Ignored by pattern: .github/workflows/** (4)
    • .github/workflows/ci.yml
    • .github/workflows/dast.yml
    • .github/workflows/python-audit.yml
    • .github/workflows/scorecard.yml
Activity
  • The pull request agent review was auto-skipped as the changes primarily involve CI/CD configurations, documentation, and dependency updates, with no direct modifications to Python source code.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

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-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR adds a comprehensive layer of security tooling to the CI pipeline and developer workflow: pip-audit for Python dependency scanning, hadolint for Dockerfile linting, OSSF Scorecard for supply chain maturity scoring, ZAP DAST for dynamic API security testing, and mypy/pytest pre-push hooks as a fast local gate. Documentation (CLAUDE.md, SECURITY.md, README.md) is updated to reflect all new tooling. The changes fit cleanly into the existing security-first CI philosophy — SHA-pinned actions, permissions: {} at workflow level, least-privilege per job, and persist-credentials: false on all checkouts.

Key observations:

  • The ZAP target: http://localhost:8000/docs/openapi.json is correct — the backend uses Litestar with OpenAPIConfig(path="/docs"), so the schema is served at /docs/openapi.json, not the FastAPI default /openapi.json
  • The DAST workflow correctly starts only the backend service (no external DB dependency — the backend uses SQLite via a named volume)
  • The OSSF Scorecard workflow has all required permissions (security-events: write, id-token: write, contents: read, actions: read) and persist-credentials: false as required by the Scorecard action docs
  • The hadolint-docker pre-commit hook is pinned to v2.12.0 (a 2022 release) while the CI hadolint-action v3.3.0 bundles a likely-newer hadolint binary — if the versions diverge on rule sets, local linting results may not match CI

Confidence Score: 4/5

  • This PR is safe to merge — it adds security tooling without touching any application logic.
  • All workflow changes are additive and well-structured. The only new finding is a minor hadolint version mismatch between the pre-commit hook and CI action that could cause local/CI drift but won't break builds. The remaining open threads (pip-audit severity threshold, ZAP alpha rules, pre-push silent zero-test collection) are pre-existing concerns that the author should address but don't block merging.
  • .pre-commit-config.yaml — hadolint version alignment between pre-commit hook and CI action.

Important Files Changed

Filename Overview
.github/workflows/ci.yml Adds python-audit (pip-audit) and dockerfile-lint (hadolint) jobs, and wires both into the ci-pass gate; logic is correct and permissions are minimal.
.github/workflows/dast.yml New ZAP API scan workflow; fail_action: false is explicitly set, target URL /docs/openapi.json is correct for this Litestar app, and backend-only startup is appropriate since there are no external DB dependencies (SQLite).
.github/workflows/scorecard.yml OSSF Scorecard workflow is correctly configured: all required permissions (security-events: write, id-token: write, contents: read, actions: read) are present, persist-credentials: false matches Scorecard docs, and publish_results: true is appropriate for main-branch runs.
.github/workflows/python-audit.yml Standalone weekly pip-audit workflow; structurally sound, but like the per-PR job it will block on any CVE severity (discussed in existing review threads).
.pre-commit-config.yaml Adds hadolint-docker pre-commit hook and mypy/pytest-unit pre-push hooks; the hadolint version (v2.12.0) may not match the version bundled in hadolint-action v3.3.0 used in CI, risking local/CI linting drift.
pyproject.toml Adds pip-audit==2.9.0 to the dev dependency group; version is pinned with == per project convention.
.github/SECURITY.md Security doc reorganized into clear categorical sections (Application, Dependency/Supply Chain, Container, Workflow, DAST); accurately reflects the new tooling added in this PR.
CLAUDE.md Updated CI section, hooks documentation, and component tree description all appear accurate to the code changes in this PR.
README.md Adds OpenSSF Scorecard badge with correct securityscorecards.dev viewer URL for this repository.

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]
Loading
Prompt To Fix All With AI
This 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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 06416b1 and e2959cd.

⛔ Files ignored due to path filters (1)
  • uv.lock is 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.yaml
  • CLAUDE.md
  • README.md
  • pyproject.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 in docs/design/ with 7 pages: index, agents, organization, communication, engine, memory, operations

Files:

  • README.md
  • CLAUDE.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. Use uv sync to 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.yml
  • CLAUDE.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.yml
  • CLAUDE.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.yml
  • 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: 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.yml
  • CLAUDE.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.yml
  • CLAUDE.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.yml
  • 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: 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.yml
  • CLAUDE.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.yml
  • 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.md
  • .pre-commit-config.yaml
  • pyproject.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: Pinned pip-audit dependency is correctly added to dev.

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-push by default plus local mypy/pytest hooks 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-audit and dockerfile-lint are properly added and enforced through ci-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/checkout steps include persist-credentials: false, and all workflows define permissions: {} 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
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.

- name: ZAP API Scan
uses: zaproxy/action-api-scan@5158fe4d9d8fcc75ea204db81317cce7f9e5453d # v0.10.0
with:
target: http://localhost:8000/openapi.json
permissions: {}

concurrency:
group: ${{ github.workflow }}-${{ github.sha }}
Comment on lines +39 to +40
- name: Start backend
run: docker compose -f docker/compose.yml up -d backend
Comment on lines +34 to +43
# 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
@Aureliolo Aureliolo force-pushed the ci/security-hardening branch from e2959cd to 50ad823 Compare March 13, 2026 14:30
CodeQL is working fine — the PR #290 cache issue was already resolved.
Copilot AI review requested due to automatic review settings March 13, 2026 14:31
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 13, 2026 14:32 — with GitHub Actions Inactive
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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-pass gate).
  • 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.

Comment on lines +28 to +35
# 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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between e2959cd and 5dbb991.

⛔ Files ignored due to path filters (1)
  • uv.lock is 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.yaml
  • CLAUDE.md
  • README.md
  • pyproject.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 in docs/design/ with 7 pages: index, agents, organization, communication, engine, memory, operations

Files:

  • README.md
  • CLAUDE.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. Use uv sync to 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.yml
  • CLAUDE.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.yml
  • 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 .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.yml
  • CLAUDE.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.yml
  • CLAUDE.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.yml
  • 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: 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.yml
  • CLAUDE.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.yml
  • 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/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.md
  • pyproject.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: Pinned pip-audit in dev group 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-audit job correctly follows security best practices:

  • Minimal permissions (contents: read)
  • Checkout action pinned to SHA with persist-credentials: false
  • Uses the shared setup-python-uv composite action for consistency

241-268: LGTM!

The ci-pass gate correctly:

  • Includes python-audit and dockerfile-lint in the needs array
  • 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-lint job 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

Comment on lines +60 to +64
- name: Upload SARIF
if: ${{ !cancelled() }}
uses: github/codeql-action/upload-sarif@820e3160e279568db735cee8ed8f8e77a6da7818 # v3.32.6
with:
sarif_file: report_sarif.json
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 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.yml

Repository: 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)
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 13, 2026 14:50 — with GitHub Actions Inactive
- uses: ./.github/actions/setup-python-uv

- name: pip-audit
run: uv run pip-audit
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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:

Suggested change
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.
Copilot AI review requested due to automatic review settings March 13, 2026 17:11
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 13, 2026 17:12 — with GitHub Actions Inactive
@Aureliolo Aureliolo merged commit 2802d20 into main Mar 13, 2026
15 of 16 checks passed
@Aureliolo Aureliolo deleted the ci/security-hardening branch March 13, 2026 17:13
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 13, 2026 17:13 — with GitHub Actions Inactive
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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-audit and hadolint to CI (and add a weekly scheduled pip-audit workflow).
  • 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.

Aureliolo added a commit that referenced this pull request Mar 13, 2026
🤖 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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants