Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
[run]
source = enterprise/src
branch = True
source = .

[paths]
source =
enterprise/src
fixops-blended-enterprise/src

[report]
include =
*/services/provenance/*
*/services/graph/*
*/services/repro/*
*/lib4sbom/*
*/risk/*
*/backend/api/provenance/*
*/backend/api/risk/*
*/backend/api/graph/*
*/backend/api/evidence/*
*/evidence/*
*/telemetry/*
*/scripts/graph_worker.py
exclude_lines =
pragma: no cover
if __name__ == "__main__":
55 changes: 55 additions & 0 deletions .github/workflows/provenance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Provenance

on:
push:
tags:
- '*'
release:
types: [published]

permissions:
contents: read
actions: read
id-token: write

jobs:
attest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
if [ -f requirements.dev.txt ]; then pip install -r requirements.dev.txt; fi
- name: Build release artefact
run: |
mkdir -p artifacts
git archive --format=tar.gz -o artifacts/fixops-${{ github.sha }}.tar.gz HEAD
- name: Generate provenance attestation
run: |
mkdir -p artifacts/attestations
cli/fixops-provenance attest \
--artifact artifacts/fixops-${{ github.sha }}.tar.gz \
--out artifacts/attestations/fixops-${{ github.sha }}.json \
--builder-id "https://github.com/${{ github.repository }}/actions" \
--source-uri "${{ github.server_url }}/${{ github.repository }}@${{ github.sha }}" \
--build-type "https://github.com/actions/runner"
- name: Verify provenance attestation
run: |
cli/fixops-provenance verify \
--artifact artifacts/fixops-${{ github.sha }}.tar.gz \
--attestation artifacts/attestations/fixops-${{ github.sha }}.json \
--builder-id "https://github.com/${{ github.repository }}/actions" \
--source-uri "${{ github.server_url }}/${{ github.repository }}@${{ github.sha }}" \
--build-type "https://github.com/actions/runner"
- name: Upload provenance attestation
uses: actions/upload-artifact@v4
with:
name: provenance-attestations
path: artifacts/attestations/
if-no-files-found: error
72 changes: 72 additions & 0 deletions .github/workflows/qa.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: qa

on:
push:
branches:
- main
- work
pull_request:

permissions:
contents: read

jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
if [ -f requirements.dev.txt ]; then pip install -r requirements.dev.txt; fi
if [ -f apps/api/requirements-optional.txt ]; then pip install -r apps/api/requirements-optional.txt; fi
- name: Formatting checks
run: |
black --check .
isort --check-only .
- name: Lint
run: flake8
- name: Type check
run: mypy .
- name: Tests with coverage
env:
PYTHONPATH: .
run: |
mkdir -p reports/coverage
pytest \
services/provenance/tests/test_attestation.py \
services/graph/tests/test_graph.py \
services/repro/tests/test_verifier.py \
tests/test_sbom_quality.py \
tests/test_risk_scoring.py \
tests/test_evidence_bundle.py \
tests/test_graph_worker.py \
tests/test_telemetry_runtime.py \
-q --override-ini testpaths='' \
--override-ini "addopts=--cov=services.provenance --cov=services.graph --cov=services.repro --cov=lib4sbom --cov=risk --cov=evidence --cov=telemetry --cov=scripts.graph_worker --cov-report=term-missing --cov-report=xml:reports/coverage/coverage.xml --cov-fail-under=70"
- name: Coverage summary
run: |
python - <<'PY'
from pathlib import Path
import xml.etree.ElementTree as ET

xml_path = Path("reports/coverage/coverage.xml")
root = ET.parse(xml_path).getroot()
rate = float(root.attrib.get("line-rate", 0.0))
summary = f"Total coverage: {rate * 100:.2f}%\n"
Path("reports/coverage/summary.txt").write_text(summary, encoding="utf-8")
print(summary.strip())
PY
- name: Upload coverage artefacts
uses: actions/upload-artifact@v4
with:
name: coverage
path: |
reports/coverage/coverage.xml
reports/coverage/summary.txt
if-no-files-found: error
105 changes: 105 additions & 0 deletions .github/workflows/release-sign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Release Signing

on:
push:
tags:
- '*'
release:
types: [published]

permissions:
contents: write
actions: read
id-token: write

jobs:
sign-artifacts:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
if [ -f requirements.dev.txt ]; then pip install -r requirements.dev.txt; fi

- name: Prepare release artifacts
run: |
mkdir -p artifacts/attestations
git archive --format=tar.gz -o artifacts/fixops-${{ github.sha }}.tar.gz HEAD

- name: Generate provenance predicate
run: |
cli/fixops-provenance attest \
--artifact artifacts/fixops-${{ github.sha }}.tar.gz \
--out artifacts/attestations/fixops-${{ github.sha }}.json \
--builder-id "https://github.com/${{ github.repository }}/actions" \
--source-uri "${{ github.server_url }}/${{ github.repository }}@${{ github.sha }}" \
--build-type "https://github.com/actions/runner"

- name: Install Cosign
uses: sigstore/cosign-installer@v3

- name: Write signing key
run: |
printf '%s' "${{ secrets.COSIGN_PRIVATE_KEY }}" > cosign.key
shell: bash

- name: Sign release artifact
env:
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
run: |
scripts/signing/sign-artifact.sh \
--artifact artifacts/fixops-${{ github.sha }}.tar.gz \
--key cosign.key \
--signature artifacts/fixops-${{ github.sha }}.tar.gz.sig \
--predicate artifacts/attestations/fixops-${{ github.sha }}.json \
--attestation-out artifacts/attestations/fixops-${{ github.sha }}.dsse \
--bundle-out artifacts/attestations/fixops-${{ github.sha }}.bundle

- name: Write verification key
run: |
printf '%s' "${{ secrets.COSIGN_PUBLIC_KEY }}" > cosign.pub
shell: bash

- name: Verify signatures
run: |
cosign verify-blob \
--key cosign.pub \
--signature artifacts/fixops-${{ github.sha }}.tar.gz.sig \
artifacts/fixops-${{ github.sha }}.tar.gz
cosign verify-blob \
--key cosign.pub \
--bundle artifacts/attestations/fixops-${{ github.sha }}.bundle \
artifacts/fixops-${{ github.sha }}.tar.gz
shell: bash

- name: Upload signed artifacts
uses: actions/upload-artifact@v4
with:
name: signed-release-${{ github.sha }}
path: |
artifacts/fixops-${{ github.sha }}.tar.gz
artifacts/fixops-${{ github.sha }}.tar.gz.sig
artifacts/attestations/fixops-${{ github.sha }}.json
artifacts/attestations/fixops-${{ github.sha }}.dsse
artifacts/attestations/fixops-${{ github.sha }}.bundle
if-no-files-found: error

- name: Attach assets to release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v1
with:
files: |
artifacts/fixops-${{ github.sha }}.tar.gz
artifacts/fixops-${{ github.sha }}.tar.gz.sig
artifacts/attestations/fixops-${{ github.sha }}.json
artifacts/attestations/fixops-${{ github.sha }}.dsse
artifacts/attestations/fixops-${{ github.sha }}.bundle
42 changes: 42 additions & 0 deletions .github/workflows/repro-verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: reproducible-build-verify

on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:

permissions:
contents: read
actions: read
id-token: write

jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
if [ -f requirements.dev.txt ]; then pip install -r requirements.dev.txt; fi
- name: Verify reproducible build
env:
FIXOPS_TAG: ${{ github.ref_name }}
run: |
TAG=${FIXOPS_TAG:-nightly}
cli/fixops-repro verify \
--tag "$TAG" \
--plan build/plan.yaml \
--out artifacts/repro/attestations \
--repo .
- name: Upload reproducibility attestations
uses: actions/upload-artifact@v4
with:
name: repro-attestations
path: artifacts/repro/attestations/
if-no-files-found: warn
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ next-env.d.ts

# Production builds
/build
!build/
!build/plan.yaml
dist/
dist

Expand Down Expand Up @@ -91,3 +93,4 @@ frontend/node_modules/.cache/default-development/0.pack
!/enterprise/.env.example

coverage.xml
!reports/coverage/coverage.xml
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Changelog

All notable changes to the FixOps investor demo branch are documented here. The project followed a ten-phase roadmap focused on
provenance, signing, SBOM normalisation, risk scoring, evidence, observability, and hardening.

## Phase 10 – Hardening & Coverage (2024-09-XX)
- Added developer, security, and audit playbooks plus the overarching security posture guide.
- Introduced the `qa` workflow enforcing lint, type-check, tests, and coverage ≥70% before merge.
- Captured coverage artefacts (`reports/coverage/coverage.xml`, `reports/coverage/summary.txt`) and tightened release
expectations.

## Phase 9 – Observability & Demo Stack
- Instrumented provenance, risk, graph, and repro services with OpenTelemetry fallbacks for offline environments.
- Added `docker-compose.demo.yml`, the OTEL collector config, and a dashboard UI surface for investor-ready demos.
- Introduced the graph worker to keep the provenance database fresh for the dashboard queries.

## Phase 8 – CI Agent & Evidence Bundles
- Delivered the `cli/fixops-ci` orchestrator that chains SBOM, risk, provenance, and repro actions.
- Packaged signed evidence bundles and manifests, exposed via the `backend/api/evidence` endpoints.
- Documented bundle structure, policy thresholds, and added tests for manifest integrity.

## Phase 7 – Reproducible Builds Verifier
- Created the hermetic rebuild service, CLI wrapper, and GitHub Actions workflow to confirm source/binary equivalence.
- Stored reproducibility attestations under `artifacts/repro/attestations/` and published operator documentation.
- Added targeted tests covering success and failure scenarios for the verifier.

## Phase 6 – Provenance Graph MVP
- Built the SQLite + NetworkX graph service ingesting git commits, attestations, SBOMs, risk outputs, and releases.
- Exposed lineage, KEV component, and anomaly queries through `backend/api/graph/*` and documented usage patterns.
- Added fixtures and tests to validate ingestion edge cases and query accuracy.

## Phase 5 – Risk Scoring
- Fetched EPSS and CISA KEV feeds, fused them with version lag/exposure hints, and stored the composite FixOpsRisk score.
- Delivered CLI/API surfaces plus documentation for the scoring formula and validation steps.
- Added regression tests for feed parsing and risk scoring heuristics.

## Phase 4 – SBOM Normalisation & Quality
- Normalised CycloneDX/SPDX inputs, deduplicated components, computed quality metrics, and rendered JSON/HTML reports.
- Shipped the `cli/fixops-sbom` command and documentation describing normalization and scoring outputs.
- Added deterministic tests to guarantee reproducible SBOM processing.

## Phase 3 – Cosign-based Signing
- Wrapped cosign in helper scripts, added the signing workflow, and documented verification procedures.
- Ensured release artefacts ship with detached signatures or bundles alongside the provenance attestations.

## Phase 2 – Provenance & SLSA Attestations
- Implemented attestation generation/verification helpers, CLI commands, API endpoints, and release automation.
- Captured the provenance schema, CLI/API usage, and tests covering digest validation flows.

## Phase 1 – Architecture Inventory & Roadmap
- Produced the authoritative architecture inventory (`docs/ARCH-INVENTORY.md`) and the detailed phase plan
(`docs/TASK-PLAN.md`).
- Updated project documentation to link the new references for reviewer onboarding.

Loading
Loading