diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000000..7df4acc8e6
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,67 @@
+name: CodeQL
+
+# Static analysis (SAST) for TypeScript/JavaScript and Python sources.
+# Findings upload to the GitHub Security tab as SARIF.
+#
+# Advisory only on first introduction — see docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md.
+# Promote to a required check after baseline triage (operator decision).
+
+on:
+ pull_request:
+ branches: [main]
+ paths-ignore: ['**.md', 'docs/**', 'LICENSE']
+ push:
+ branches: [main]
+ schedule:
+ # Weekly Monday 06:00 UTC — catches advisories newly published against
+ # already-merged code without waiting for the next PR.
+ - cron: '0 6 * * 1'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+ analyze:
+ name: Analyze (${{ matrix.language }})
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ permissions:
+ actions: read
+ contents: read
+ # security-events:write is what enables SARIF upload to the Security tab.
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [javascript-typescript, python]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Don't leave GITHUB_TOKEN in .git/config for downstream steps to read.
+ persist-credentials: false
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
+ with:
+ languages: ${{ matrix.language }}
+ queries: security-and-quality
+ # Exclude generated/vendored code; tune after first-run signal.
+ # gitnexus/vendor/ holds tree-sitter-proto sources (regenerated, not authored).
+ # CodeQL path filters use .gitignore-style globs and do NOT support
+ # brace expansion — list each generated parser file separately.
+ config: |
+ paths-ignore:
+ - '**/dist/**'
+ - '**/node_modules/**'
+ - 'gitnexus/vendor/**'
+ - 'gitnexus/src/core/parsing/**/parser.c'
+ - 'gitnexus/src/core/parsing/**/parser.js'
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
+ with:
+ category: '/language:${{ matrix.language }}'
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
new file mode 100644
index 0000000000..ad06267c21
--- /dev/null
+++ b/.github/workflows/dependency-review.yml
@@ -0,0 +1,36 @@
+name: Dependency Review
+
+# Blocks PRs that introduce dependencies with high/critical known vulnerabilities.
+# Reads the dependency graph diff between PR head and base.
+#
+# This is a required-check candidate after one week of clean runs
+# (operator decision — see docs/plans/2026-05-03-001-feat-automated-security-scans-plan.md).
+
+on:
+ pull_request:
+ branches: [main]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ review:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+ # pull-requests:write enables the inline summary comment on failure.
+ pull-requests: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Dependency Review
+ uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
+ with:
+ fail-on-severity: high
+ comment-summary-in-pr: on-failure
diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml
new file mode 100644
index 0000000000..cfe4d08562
--- /dev/null
+++ b/.github/workflows/gitleaks.yml
@@ -0,0 +1,45 @@
+name: Gitleaks
+
+# Deterministic in-CI secret scanning. Defense-in-depth on top of GitHub's
+# native secret-scanning push protection (which is a repo Settings toggle —
+# see SECURITY.md for the recommended admin action).
+#
+# PR runs scan the diff (fast); main pushes scan full history.
+
+on:
+ pull_request:
+ branches: [main]
+ push:
+ branches: [main]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
+
+jobs:
+ gitleaks:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+ pull-requests: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ # Full history needed for the on-push full-history scan; on PRs the
+ # action diffs against the base ref so the cost is bounded by the PR.
+ fetch-depth: 0
+ # Don't bake the token into the cloned .git/config; downstream
+ # steps (and Gitleaks itself) don't need it for repo operations.
+ persist-credentials: false
+
+ # No GITLEAKS_LICENSE secret is required for OSS / public-repo usage.
+ # If this repo becomes private, the action will require a license key.
+ - name: Gitleaks
+ uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITLEAKS_ENABLE_UPLOAD_ARTIFACT: true
+ GITLEAKS_ENABLE_SUMMARY: true
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 1fc95a13aa..d372c163a1 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -37,8 +37,12 @@ jobs:
with:
node-version: 20
registry-url: https://registry.npmjs.org
- cache: npm
- cache-dependency-path: gitnexus/package-lock.json
+ # Hermetic install for the published artifact — no cache carry-over
+ # from non-tag contexts. setup-node v5+ caches by default when a
+ # packageManager field is present in package.json, so the explicit
+ # opt-out is required to clear the zizmor cache-poisoning audit.
+ # ~30s slower per release; runs rarely.
+ package-manager-cache: false
- name: Build gitnexus-shared
run: npm install && npm run build
working-directory: gitnexus-shared
diff --git a/.github/workflows/release-candidate.yml b/.github/workflows/release-candidate.yml
index 7413a02e14..5b598ee14a 100644
--- a/.github/workflows/release-candidate.yml
+++ b/.github/workflows/release-candidate.yml
@@ -137,8 +137,11 @@ jobs:
with:
node-version: 20
registry-url: https://registry.npmjs.org
- cache: npm
- cache-dependency-path: gitnexus/package-lock.json
+ # Hermetic install — release-candidate produces shipped artifacts.
+ # setup-node v5+ caches by default when a packageManager field is
+ # present in package.json; explicit opt-out is required to clear
+ # the zizmor cache-poisoning audit. See cache-poisoning audit.
+ package-manager-cache: false
- name: Build gitnexus-shared
run: npm install && npm run build
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
new file mode 100644
index 0000000000..b132b7c3f3
--- /dev/null
+++ b/.github/workflows/scorecard.yml
@@ -0,0 +1,58 @@
+name: Scorecard
+
+# OpenSSF Scorecard supply-chain posture check. Runs weekly + on main push +
+# branch_protection_rule changes. SARIF uploads to the Security tab; the public
+# badge URL resolves once the first scheduled run lands (see README badge wiring).
+
+on:
+ branch_protection_rule:
+ schedule:
+ - cron: '0 7 * * 1'
+ push:
+ branches: [main]
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecard analysis
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ permissions:
+ # Needed to upload SARIF results to the Security tab.
+ security-events: write
+ # Needed for the publish_results badge flow (OIDC).
+ id-token: write
+ contents: read
+ actions: read
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Run Scorecard
+ uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # publish_results enables the public Scorecard badge.
+ publish_results: true
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ - name: Upload to Security tab
+ uses: github/codeql-action/upload-sarif@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
+ with:
+ sarif_file: results.sarif
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
new file mode 100644
index 0000000000..5bc5d17a4d
--- /dev/null
+++ b/.github/workflows/trivy.yml
@@ -0,0 +1,73 @@
+name: Trivy Image Scan
+
+# Builds Dockerfile.cli and Dockerfile.web, then scans the resulting images
+# for OS-package and language-package CVEs at HIGH/CRITICAL severity.
+# Findings upload to the Security tab; record-only (does not block merges).
+#
+# NOT triggered on PRs — image builds are slow and base-image CVE churn
+# shouldn't gate feature delivery.
+
+on:
+ push:
+ branches: [main]
+ schedule:
+ - cron: '0 8 * * 1'
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+
+jobs:
+ scan:
+ name: Trivy (${{ matrix.image.name }})
+ runs-on: ubuntu-latest
+ timeout-minutes: 30
+ permissions:
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ image:
+ - { dockerfile: Dockerfile.cli, name: gitnexus-cli }
+ - { dockerfile: Dockerfile.web, name: gitnexus-web }
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Setup Buildx
+ uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
+
+ - name: Build image (load locally for scan)
+ uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
+ with:
+ context: .
+ file: ${{ matrix.image.dockerfile }}
+ load: true
+ push: false
+ tags: scan-target:${{ matrix.image.name }}
+
+ # aquasecurity/trivy-action versions < 0.35.0 are flagged by
+ # GHSA-69fq-xp46-6x23 (briefly compromised supply chain). Pinned to
+ # v0.36.0 (post-incident clean release) by commit SHA.
+ - name: Run Trivy
+ uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
+ with:
+ image-ref: scan-target:${{ matrix.image.name }}
+ format: sarif
+ output: trivy-${{ matrix.image.name }}.sarif
+ severity: HIGH,CRITICAL
+ # Hides CVEs with no available fix in the base image.
+ ignore-unfixed: true
+ exit-code: '0'
+
+ - name: Upload to Security tab
+ uses: github/codeql-action/upload-sarif@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
+ with:
+ sarif_file: trivy-${{ matrix.image.name }}.sarif
+ category: trivy-${{ matrix.image.name }}
diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml
new file mode 100644
index 0000000000..3dd4924069
--- /dev/null
+++ b/.github/workflows/workflow-lint.yml
@@ -0,0 +1,58 @@
+name: Workflow Lint (zizmor)
+
+# Lints .github/workflows/** for known GitHub Actions security misconfigurations:
+# unpinned Actions, dangerous ${{ ... }} interpolation in run: blocks,
+# missing per-job permissions:, etc.
+#
+# Scoped to PRs that touch .github/** only — keeps off the typical PR critical path.
+
+on:
+ pull_request:
+ branches: [main]
+ paths:
+ - '.github/**'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ zizmor:
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+ security-events: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Setup Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
+ with:
+ python-version: '3.12'
+
+ - name: Install zizmor
+ # Pinned — resolves to whatever's latest on PyPI otherwise.
+ # Bump via Dependabot pip ecosystem (see .github/dependabot.yml).
+ run: pipx install zizmor==1.24.1
+
+ # Initial threshold: medium. High+ findings fail the job; medium findings
+ # appear in the Security tab without blocking. Tune after first run.
+ # Per-rule exemptions for pre-existing intentional patterns live in
+ # .github/zizmor.yml (each carries a documented mitigation).
+ - name: Run zizmor
+ run: zizmor --config .github/zizmor.yml --format sarif --min-severity medium . > zizmor.sarif
+ continue-on-error: true
+
+ - name: Upload SARIF
+ uses: github/codeql-action/upload-sarif@0daab03d71ff584ef619d027a3fd9146679c5d84 # v3.35.3
+ with:
+ sarif_file: zizmor.sarif
+ category: zizmor
+
+ - name: Fail on high+ findings
+ run: zizmor --config .github/zizmor.yml --min-severity high .
diff --git a/.github/zizmor.yml b/.github/zizmor.yml
new file mode 100644
index 0000000000..c534679c1a
--- /dev/null
+++ b/.github/zizmor.yml
@@ -0,0 +1,34 @@
+# zizmor config — pre-existing intentional patterns flagged on initial introduction.
+# Each ignore below has a documented mitigation. Re-evaluate when the source workflow changes.
+#
+# To run zizmor locally with this config:
+# zizmor --config .github/zizmor.yml .
+
+rules:
+ dangerous-triggers:
+ ignore:
+ # workflow_run is REQUIRED to post sticky comments on fork PRs — the
+ # default-branch privileged token isn't accessible from `pull_request`
+ # on a fork. Mitigated by: read-only `actions:read` + `contents:read`
+ # for artifact download; `pull-requests:write` is the only write scope;
+ # no checkout of fork code occurs. Header comment in the file documents.
+ - ci-report.yml
+
+ # pull_request_target needed by claude-code-action to access secrets
+ # and post review comments on fork PRs. Mitigated by: PR checkouts pin
+ # the fork's HEAD SHA (not the branch ref) to prevent TOCTOU races,
+ # and claude-code-action sandboxes execution. Header comment documents.
+ - claude.yml
+
+ # pull_request_target on the autolabel job needs `pull-requests:write`
+ # to apply labels. Mitigated by: release-drafter runs with `dry-run:
+ # true`, reads only `.github/release-drafter.yml` from the BASE ref,
+ # and the validate-title job (which runs untrusted `pull_request`
+ # context) holds no write permissions. Header comment documents.
+ - pr-labeler.yml
+
+ # Note: cache-poisoning is NOT exempted. The two prior findings in
+ # publish.yml and release-candidate.yml were fixed structurally by
+ # dropping `cache: npm` from those workflows (matches the pattern used
+ # by PyO3/maturin for the same audit). See the commit that added this
+ # file for the rationale.
diff --git a/README.md b/README.md
index ade7a4879a..2dad7f2efa 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,9 @@
+
+
+
Enterprise (SaaS & Self-hosted) - akonlabs.com
diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..79ef97f6b2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,67 @@ +# Security Policy + +## Supported Versions + +GitNexus is developed on `main`. Security fixes are applied to the latest released minor on npm (`gitnexus`) and to the published Docker images (`Dockerfile.cli`, `Dockerfile.web`). Older minors are not back-patched. + +## Reporting a Vulnerability + +**Please do not open a public GitHub issue for security reports.** + +Use **GitHub Private Vulnerability Reporting** for this repository: + +→ https://github.com/abhigyanpatwari/GitNexus/security/advisories/new + +Please include: + +- A description of the issue and its potential impact +- Steps to reproduce (a minimal repro repo or commit hash if possible) +- The affected version(s) — `npm view gitnexus version`, image digest, or commit SHA +- Any suggested mitigation + +### What to expect + +- **Acknowledgement:** best-effort within 5 business days, subject to maintainer capacity. +- **Triage:** we will confirm whether the report is in scope, request clarifications if needed, and propose a fix timeline. +- **Disclosure:** coordinated. We will agree on a disclosure date with you before publishing an advisory. + +### Scope + +In scope: + +- The `gitnexus` CLI and MCP server (`gitnexus/`) +- The `gitnexus-web` thin client (`gitnexus-web/`) +- The `gitnexus-shared` types package (`gitnexus-shared/`) +- The published Docker images (`Dockerfile.cli`, `Dockerfile.web`) +- GitHub Actions workflows in `.github/workflows/` + +Out of scope: + +- Vulnerabilities in third-party dependencies that we have no influence over (please report upstream; if a viable mitigation exists at the GitNexus layer, that's in scope). +- Issues requiring physical access to a developer machine or a compromised local environment. +- Theoretical attacks without a practical exploit against a default GitNexus deployment. + +## Recommended Hardening for Forks and Self-Hosted Deployments + +If you fork GitNexus or self-host it, we recommend enabling the following in your repository's **Settings → Code security and analysis**: + +- **Private vulnerability reporting** — the channel described above. +- **Dependabot alerts** — alerts on advisories affecting your dependencies. +- **Dependabot security updates** — automated PRs for security patches (this repo's `.github/dependabot.yml` already covers version updates). +- **Secret scanning** and **Push protection** — blocks pushes that introduce known secret patterns. Defense-in-depth on top of the in-CI Gitleaks scan documented below. +- **Code scanning** — surfaces SARIF results from CodeQL, Trivy, Scorecard, and zizmor in one place. + +## Automated Scans Running in CI + +This repository runs the following scans automatically. Findings appear under the repository's **Security → Code scanning** tab. + +| Scan | Tool | Trigger | Action on finding | +|------|------|---------|-------------------| +| Static analysis (JS/TS, Python) | [CodeQL](https://github.com/github/codeql-action) | PR, `main` push, weekly | Advisory (Security tab) | +| Dependency vulnerabilities (PR diff) | [`dependency-review-action`](https://github.com/actions/dependency-review-action) | PR | **Blocks PR** at `high+` severity | +| Secret scanning | [Gitleaks](https://github.com/gitleaks/gitleaks-action) | PR, `main` push | **Blocks PR** on default rules | +| Supply-chain posture | [OpenSSF Scorecard](https://github.com/ossf/scorecard-action) | Weekly, `main` push | Advisory (Security tab + public badge) | +| Workflow lint | [zizmor](https://github.com/woodruffw/zizmor) | PR (touching `.github/**`) | **Blocks PR** at `high+` severity | +| Container image scan | [Trivy](https://github.com/aquasecurity/trivy-action) | Weekly, `main` push | Advisory (Security tab) | + +Dependency version updates are managed separately by Dependabot — see `.github/dependabot.yml`.