mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-09-10 04:00:35 +00:00
Hardens the CI/CD supply chain against the LiteLLM/Trivy-style attack (a compromised third-party Action with a mutable tag stealing a long-lived publishing token) and closes several related gaps found in an audit of the actual repository state. - Pin every third-party GitHub Action across all workflows to a full commit SHA (tag kept as a trailing comment); add verify-action-pins.yml, a CI check that confirms via the GitHub API that each pin still matches its tag, on every workflow change, push to main, and weekly. - Scope release.yml permissions to the job level (workflow defaults to contents: read); add a concurrency group so simultaneous tag pushes can't race the publish job. - Add SLSA build provenance attestation (actions/attest-build-provenance) for every released wheel. - Fix a latent bug in security-scan.yml: the PR-comment step was missing pull-requests: write and silently failing; add bounded artifact retention for uploaded scan reports. - Group github-actions Dependabot updates to cut review noise. - Document the resulting posture in SECURITY.md for auditors/regulated adopters, including what's enforced and what a fork needs to reconfigure for itself (environment/branch protection, Trusted Publishing trust). Also (via GitHub API, not in this diff): created a protected `pypi` environment with a required reviewer restricted to v* tags, and enabled branch protection on main (required review, required status checks, no force-push/deletion).
98 lines
3.7 KiB
YAML
98 lines
3.7 KiB
YAML
name: CodeQL
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
pull_request:
|
||
branches: [main]
|
||
schedule:
|
||
- cron: '30 1 * * 1' # Every Monday 7 AM IST
|
||
|
||
permissions:
|
||
contents: read
|
||
security-events: write
|
||
actions: read
|
||
|
||
jobs:
|
||
analyze:
|
||
name: Analyze Python
|
||
runs-on: ubuntu-latest
|
||
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||
|
||
# The CodeQL bundle download (github/codeql-action/init's "Setup CodeQL
|
||
# tools" step) streams a ~1GB tarball from GitHub's release CDN and
|
||
# does not retry on a transient connection reset (ECONNRESET) itself
|
||
# (github/codeql-action, unresolved as of v4 / CLI 2.26.1: the HTTP
|
||
# error is retryable but isn't retried internally). Since a `uses:`
|
||
# step can't be wrapped by a shell-level retry action, attempt init
|
||
# up to 3 times; each retry is a fresh download attempt with no
|
||
# meaningful state carried over from a failed attempt.
|
||
- name: Initialize CodeQL (attempt 1)
|
||
id: codeql-init-1
|
||
uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4
|
||
continue-on-error: true
|
||
with:
|
||
languages: python
|
||
queries: security-and-quality
|
||
config-file: .github/codeql/codeql-config.yml
|
||
|
||
- name: Initialize CodeQL (attempt 2)
|
||
id: codeql-init-2
|
||
if: steps.codeql-init-1.outcome == 'failure'
|
||
uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4
|
||
continue-on-error: true
|
||
with:
|
||
languages: python
|
||
queries: security-and-quality
|
||
config-file: .github/codeql/codeql-config.yml
|
||
|
||
- name: Initialize CodeQL (attempt 3)
|
||
id: codeql-init-3
|
||
if: steps.codeql-init-2.outcome == 'failure'
|
||
uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4
|
||
with:
|
||
languages: python
|
||
queries: security-and-quality
|
||
config-file: .github/codeql/codeql-config.yml
|
||
|
||
- name: Autobuild
|
||
uses: github/codeql-action/autobuild@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4
|
||
|
||
- name: Perform CodeQL Analysis
|
||
uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4
|
||
with:
|
||
category: "/language:python"
|
||
upload: false
|
||
id: codeql
|
||
|
||
- name: Upload SARIF (Advanced Setup only)
|
||
# Uploads results only when Default Setup is not active.
|
||
# If Default Setup is still enabled, this step skips gracefully
|
||
# instead of failing the workflow with HTTP 409.
|
||
uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4
|
||
with:
|
||
sarif_file: ${{ steps.codeql.outputs.sarif-output }}
|
||
category: "/language:python"
|
||
wait-for-processing: true
|
||
continue-on-error: true
|
||
|
||
# NOTE: Auto-dismissal by rule-id is intentionally removed.
|
||
# Dismissing every alert that matches a rule ID would silently suppress
|
||
# future real vulnerabilities of the same type. The alerts below were
|
||
# individually triaged and dismissed manually in the security-enhancement
|
||
# PR (alerts #12–#18). New alerts must be reviewed and dismissed by hand,
|
||
# or will auto-close when the underlying code no longer triggers them.
|
||
#
|
||
# If you need to dismiss a specific known-safe alert, pin its alert NUMBER
|
||
# here and remove it once CodeQL stops reporting it naturally. Example:
|
||
#
|
||
# PINNED_ALERT_NUMBERS=(12 13 14 15 16 17 18)
|
||
# for NUM in "${PINNED_ALERT_NUMBERS[@]}"; do
|
||
# gh api repos/$REPO/code-scanning/alerts/$NUM \
|
||
# -X PATCH -f state=dismissed -f dismissed_reason="false positive" \
|
||
# -f dismissed_comment="<reason>"
|
||
# done
|