diff --git a/.github/workflows/gitgalaxy-artifacts.yml b/.github/workflows/gitgalaxy-artifacts.yml deleted file mode 100644 index 994b96a4..00000000 --- a/.github/workflows/gitgalaxy-artifacts.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Generate GitGalaxy Artifacts (Post-Gate) - -on: - push: - branches: - - main - pull_request: - branches: - - main - -permissions: - contents: write - security-events: write - -jobs: - generate-compliance-artifacts: - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: "3.12" - cache: "pip" - - - name: Install GitGalaxy & Dependencies - run: | - python -m pip install --upgrade pip - pip install . networkx tiktoken xgboost pandas numpy - - - name: Generate SARIF, SBOM, and LLM Brief - env: - GITGALAXY_LICENSE_KEY: "COMMUNITY_FREE_TIER" - run: | - # Execute galaxyscope - galaxyscope . --config .galaxyscope.yaml --sarif-only - galaxyscope . --config .galaxyscope.yaml --sbom-only - galaxyscope . --config .galaxyscope.yaml --llm-only - - # Debug: Print the exact files generated - echo "=== FILES GENERATED BY GALAXYSC ===" - ls -la *_sarif* *.sarif *_sbom* *.json *_llm* || true - - # Force rename them so the next steps can find them reliably - mv *_sarif* gitgalaxy-results_sarif.json 2>/dev/null || mv *.sarif gitgalaxy-results_sarif.json 2>/dev/null || true - mv *_sbom* gitgalaxy-sbom.json 2>/dev/null || true - mv *_llm.md gitgalaxy_architecture_brief.md 2>/dev/null || true - - - name: Upload SARIF to GitHub Security Tab - uses: github/codeql-action/upload-sarif@v4.37.0 - with: - sarif_file: gitgalaxy-results_sarif.json - - - name: Upload SBOM as Build Artifact - uses: actions/upload-artifact@v7 - with: - name: gitgalaxy-sbom - path: gitgalaxy-sbom.json - - - name: Commit LLM Brief to Docs - if: github.event_name == 'push' - run: | - mkdir -p docs - mv gitgalaxy_architecture_brief.md docs/ || true - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git add docs/gitgalaxy_architecture_brief.md - git diff --quiet && git diff --staged --quiet || (git commit -m "docs: auto-update LLM architectural brief" && git push) diff --git a/.github/workflows/gitgalaxy-audit.yml b/.github/workflows/gitgalaxy-audit.yml deleted file mode 100644 index d8039b04..00000000 --- a/.github/workflows/gitgalaxy-audit.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: GitGalaxy Zero-Trust Audit - -on: - push: - branches: [ "feature/*" ] - pull_request: - branches: [ "main" ] - -# REQUIRED: Grants the action permission to post to the Security tab -permissions: - contents: read - security-events: write - -jobs: - spectral-audit: - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - cache: "pip" - - - name: Install GitGalaxy & Dependencies - run: | - python -m pip install --upgrade pip - pip install . networkx tiktoken xgboost pandas numpy - - - name: Execute Spectral Audit - run: | - # Relaxed thresholds until --incremental or --ignore are implemented - galaxyscope . --config .galaxyscope.yaml --max-risk-exposure 120 --fail-on-malware --sarif-only --output gitgalaxy-results.json - - - name: Upload SARIF to GitHub Security Tab - if: always() - uses: github/codeql-action/upload-sarif@v4.37.0 - with: - sarif_file: gitgalaxy-results_sarif.json - - - name: Upload SARIF as Build Artifact (Backup) - if: always() - uses: actions/upload-artifact@v7 - with: - name: gitgalaxy-sarif-report - path: gitgalaxy-results_sarif.json \ No newline at end of file diff --git a/.github/workflows/gitgalaxy.yml b/.github/workflows/gitgalaxy.yml index 666f91f9..baedb86c 100644 --- a/.github/workflows/gitgalaxy.yml +++ b/.github/workflows/gitgalaxy.yml @@ -1,23 +1,27 @@ name: GitGalaxy Zero-Trust Pipeline on: - push: - branches: [main] pull_request: branches: [main] + push: + branches: [main] permissions: contents: read jobs: + # ============================================================ + # PRE-GATE — runs on every PR, blocks the merge on failure. + # Fast; no heavy ML/graph dependencies installed. + # ============================================================ vault-sentinel: + if: github.event_name == 'pull_request' name: Vault Sentinel runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: ./ with: tool: vault-sentinel @@ -25,13 +29,13 @@ jobs: version: local xray-inspector: + if: github.event_name == 'pull_request' name: X-Ray Inspector runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: ./ with: tool: xray-inspector @@ -39,15 +43,74 @@ jobs: version: local supply-chain-firewall: + if: github.event_name == 'pull_request' name: Supply Chain Firewall runs-on: ubuntu-latest steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: ./ with: tool: supply-chain-firewall target: . - version: local \ No newline at end of file + version: local + + # ============================================================ + # POST-GATE — runs only once code is on main (merge or direct + # push). One galaxyscope pass produces all 6 outputs; we route + # 3 of them and let the rest live only in the ephemeral runner. + # --fail-on-malware stays on here too, as a safety net in case + # branch protection is ever bypassed. + # ============================================================ + full-report: + if: github.event_name == 'push' + name: Full Report (SARIF, SBOM, LLM Brief) + runs-on: ubuntu-latest + permissions: + contents: write # commits the LLM brief back to docs/ + security-events: write # uploads SARIF to the Security tab + steps: + - name: Checkout Repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 + persist-credentials: true + + - name: Setup Python + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + with: + python-version: "3.12" + cache: "pip" + + - name: Install GitGalaxy & Full Precision Engines + run: | + python -m pip install --upgrade pip + pip install gitgalaxy networkx tiktoken xgboost pandas numpy + + - name: Run GalaxyScope (single pass — all 6 outputs) + env: + GITGALAXY_LICENSE_KEY: "COMMUNITY_FREE_TIER" + run: | + galaxyscope . --config .galaxyscope.yaml --fail-on-malware --output gitgalaxy-results + + - name: Upload SARIF to GitHub Security Tab + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4 + with: + sarif_file: gitgalaxy-results_sarif.json + + - name: Upload SBOM as Build Artifact + uses: actions/upload-artifact@v7 + with: + name: gitgalaxy-sbom + path: gitgalaxy-results_sbom.json + + - name: Commit LLM Brief to Docs + run: | + mkdir -p docs + mv *_galaxy_llm.md docs/gitgalaxy_architecture_brief.md + + git config --global user.name "github-actions[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add docs/gitgalaxy_architecture_brief.md + git diff --quiet && git diff --staged --quiet || (git commit -m "docs: auto-update LLM architectural brief" && git push) diff --git a/action.yml b/action.yml index 7b9dd67a..de48cf6b 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ name: 'GitGalaxy Scanner' -description: 'High-velocity, AST-free DevSecOps scanner for zero-trust CI/CD, SBOMs, secret detection, and supply chain security.' +description: 'Repo intelligence for humans and AI, without compilation: architecture mapping, risk scoring, and SBOM/SARIF generation for zero-trust CI/CD — SARIF output is ready for upload to security dashboard.' branding: icon: 'shield' color: 'purple' diff --git a/templates/azure/azure-pipelines.yml b/templates/azure/azure-pipelines.yml index 1568805f..b89dba4d 100644 --- a/templates/azure/azure-pipelines.yml +++ b/templates/azure/azure-pipelines.yml @@ -10,9 +10,6 @@ trigger: - v* variables: - GG_TOOL: 'galaxyscope' - GG_TARGET: '.' - GG_ARGS: '--config .galaxyscope.yaml --max-risk-exposure 120 --fail-on-malware --sarif-only --output $(Build.ArtifactStagingDirectory)/gitgalaxy-results.json' PIP_CACHE_DIR: '$(Pipeline.Workspace)/.pip-cache' GITGALAXY_LICENSE_KEY: 'COMMUNITY_FREE_TIER' @@ -20,41 +17,85 @@ stages: - stage: SecurityScan displayName: 'GitGalaxy Zero-Trust Audit' jobs: - - job: RunGalaxyScope - displayName: 'GalaxyScope Static Analysis' + + - job: VaultSentinel + displayName: 'Vault Sentinel' pool: vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.12' - displayName: 'Initialize Python Environment' + - script: | + python -m pip install --upgrade pip + pip install gitgalaxy + displayName: 'Install GitGalaxy' + - checkout: self + fetchDepth: 0 + - script: vault-sentinel . + displayName: 'Run Vault Sentinel' + - job: XrayInspector + displayName: 'X-Ray Inspector' + pool: + vmImage: 'ubuntu-latest' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.12' + - script: | + python -m pip install --upgrade pip + pip install gitgalaxy + displayName: 'Install GitGalaxy' + - checkout: self + fetchDepth: 0 + - script: xray-inspector . + displayName: 'Run X-Ray Inspector' + + - job: SupplyChainFirewall + displayName: 'Supply Chain Firewall' + pool: + vmImage: 'ubuntu-latest' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.12' + - script: | + python -m pip install --upgrade pip + pip install gitgalaxy + displayName: 'Install GitGalaxy' + - checkout: self + fetchDepth: 0 + - script: supply-chain-firewall . + displayName: 'Run Supply Chain Firewall' + + - job: GalaxyScopeReport + displayName: 'GalaxyScope Reporting (SARIF + ML Malware Gate)' + pool: + vmImage: 'ubuntu-latest' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.12' - task: Cache@2 inputs: key: 'pip | "$(Agent.OS)"' path: $(PIP_CACHE_DIR) cacheHitVar: PIP_CACHE_RESTORED displayName: 'Configure Dependency Caching' - - script: | python -m pip install --upgrade pip pip install gitgalaxy networkx tiktoken xgboost pandas numpy displayName: 'Install GitGalaxy & Heavy Physics Engines' - - checkout: self fetchDepth: 0 - displayName: 'Checkout Repository (Full Depth)' - - script: | - echo "Running: $(GG_TOOL) $(GG_TARGET)$(GG_ARGS)" - $(GG_TOOL) $(GG_TARGET)$(GG_ARGS) + galaxyscope . --config .galaxyscope.yaml --fail-on-malware --sarif-only --output $(Build.ArtifactStagingDirectory)/gitgalaxy-results.json displayName: 'Execute Zero-Trust Spectral Audit' - - task: PublishPipelineArtifact@1 inputs: targetPath: '$(Build.ArtifactStagingDirectory)/gitgalaxy-results_sarif.json' artifact: 'GitGalaxySecurityLogs' publishLocation: 'pipeline' displayName: 'Upload SARIF Security Metrics' - condition: always() \ No newline at end of file + condition: always() diff --git a/templates/bitbucket/bitbucket-pipelines.yml b/templates/bitbucket/bitbucket-pipelines.yml index 6aa191bf..28ea510d 100644 --- a/templates/bitbucket/bitbucket-pipelines.yml +++ b/templates/bitbucket/bitbucket-pipelines.yml @@ -13,44 +13,49 @@ clone: pipelines: default: - - step: - name: 'GitGalaxy Zero-Trust Spectral Audit' - caches: - - pip - script: - - export GG_TOOL="galaxyscope" - - export GG_TARGET="." - - export GG_ARGS="--config .galaxyscope.yaml --max-risk-exposure 120 --fail-on-malware --sarif-only --output gitgalaxy-results.json" - - export GG_VERSION="latest" - - export GG_FULL_PRECISION="true" - - export GITGALAXY_LICENSE_KEY="COMMUNITY_FREE_TIER" + - parallel: + - step: + name: 'Vault Sentinel' + caches: + - pip + script: + - export GITGALAXY_LICENSE_KEY="COMMUNITY_FREE_TIER" + - pip install --upgrade pip + - pip install gitgalaxy + - vault-sentinel . - - pip install --upgrade pip - - | - if [ "$GG_VERSION" = "local" ]; then - echo "Dogfooding local GitGalaxy source..." - pip install -e . - elif [ "$GG_VERSION" = "latest" ]; then - echo "Installing latest GitGalaxy from PyPI..." - pip install gitgalaxy - else - echo "Installing GitGalaxy version ${GG_VERSION}..." - pip install "gitgalaxy==${GG_VERSION}" - fi - - | - if [ "$GG_FULL_PRECISION" = "true" ]; then - echo "Unlocking Full Precision Mode..." - pip install networkx tiktoken xgboost pandas numpy - else - echo "Running in ultra-fast Zero-Dependency Mode." - fi + - step: + name: 'X-Ray Inspector' + caches: + - pip + script: + - export GITGALAXY_LICENSE_KEY="COMMUNITY_FREE_TIER" + - pip install --upgrade pip + - pip install gitgalaxy + - xray-inspector . - - | - echo "Running: ${GG_TOOL} ${GG_TARGET} ${GG_ARGS}" - ${GG_TOOL} ${GG_TARGET} ${GG_ARGS} - # Publishes SARIF results as native Bitbucket Code Insights PR - # annotations. Requires bitbucket_insights.py (see header note). - - python bitbucket_insights.py gitgalaxy-results_sarif.json - - artifacts: - - gitgalaxy-results_sarif.json + - step: + name: 'Supply Chain Firewall' + caches: + - pip + script: + - export GITGALAXY_LICENSE_KEY="COMMUNITY_FREE_TIER" + - pip install --upgrade pip + - pip install gitgalaxy + - supply-chain-firewall . + + - step: + name: 'GalaxyScope Reporting (SARIF + ML Malware Gate)' + caches: + - pip + script: + - export GITGALAXY_LICENSE_KEY="COMMUNITY_FREE_TIER" + - pip install --upgrade pip + - pip install gitgalaxy networkx tiktoken xgboost pandas numpy + - | + galaxyscope . --config .galaxyscope.yaml --fail-on-malware --sarif-only --output gitgalaxy-results.json + # Publishes SARIF results as native Bitbucket Code Insights PR + # annotations. Requires bitbucket_insights.py (see header note). + - python bitbucket_insights.py gitgalaxy-results_sarif.json + artifacts: + - gitgalaxy-results_sarif.json diff --git a/templates/github/gitgalaxy-pipeline.yml b/templates/github/gitgalaxy-pipeline.yml index b340c00d..e566115a 100644 --- a/templates/github/gitgalaxy-pipeline.yml +++ b/templates/github/gitgalaxy-pipeline.yml @@ -35,3 +35,35 @@ jobs: with: tool: 'supply-chain-firewall' target: '.' + + galaxyscope-report: + name: GalaxyScope Reporting (SARIF + ML Malware Gate) + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write # required to upload SARIF to the Security tab + env: + GITGALAXY_LICENSE_KEY: 'COMMUNITY_FREE_TIER' + steps: + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + + - name: Install GitGalaxy & Full Precision Engines + run: | + python -m pip install --upgrade pip + pip install gitgalaxy networkx tiktoken xgboost pandas numpy + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Execute Zero-Trust Spectral Audit + run: | + galaxyscope . --config .galaxyscope.yaml --fail-on-malware --sarif-only --output gitgalaxy-results.json + + - name: Upload SARIF to GitHub Security Tab + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: gitgalaxy-results_sarif.json diff --git a/templates/gitlab/scan.yml b/templates/gitlab/scan.yml index 4dd53362..d0164e4b 100644 --- a/templates/gitlab/scan.yml +++ b/templates/gitlab/scan.yml @@ -1,23 +1,30 @@ # GitGalaxy Enterprise Security Scanner # Integration: GitLab CI/CD Component +# +# This is a generic, single-tool component — call it once per tool to build +# the 4-check Golden Path (vault-sentinel, xray-inspector, +# supply-chain-firewall, galaxyscope). See github-action-readme.md for the +# full tool directory. Only 'galaxyscope' accepts the args in the example +# below (--config, --fail-on-malware, --sarif-only, --output); the three +# sentinel tools take no flags beyond the target path. spec: inputs: tool: - description: "The GitGalaxy command to execute." + description: "The GitGalaxy command to execute (galaxyscope, vault-sentinel, xray-inspector, or supply-chain-firewall)." default: "galaxyscope" target: description: "The directory or file path to scan." default: "." args: - description: "Additional CLI arguments to pass to the tool." - default: "--config .galaxyscope.yaml --max-risk-exposure 120 --fail-on-malware --sarif-only --output gitgalaxy-results.json" + description: "Additional CLI arguments. Only meaningful for 'galaxyscope' — the sentinel tools accept no flags." + default: "" version: description: "The version of GitGalaxy to install from PyPI. Defaults to latest." default: "latest" full_precision: - description: "Opt-in to install heavy physics engines for Blast Radius and ML Threat Inference." - default: "true" + description: "Opt-in to install heavy physics engines for Blast Radius and ML Threat Inference. Only relevant when tool: galaxyscope." + default: "false" --- @@ -38,7 +45,7 @@ gitgalaxy_scan: - export GG_VERSION="$[[ inputs.version ]]" - export GG_FULL_PRECISION="$[[ inputs.full_precision ]]" - export GITGALAXY_LICENSE_KEY="COMMUNITY_FREE_TIER" - + - pip install --upgrade pip - | if [ "$GG_VERSION" = "local" ]; then @@ -64,5 +71,7 @@ gitgalaxy_scan: artifacts: when: always reports: + # Only populated when tool: galaxyscope --sarif-only is used. + # Harmless no-op (GitLab just won't find the file) for the sentinel tools. sast: gitgalaxy-results_sarif.json allow_failure: false