diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index c08a32ff..00aa7835 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -1,4 +1,4 @@ -name: Integration Tests for Exosphere +name: Integration Tests on: push: @@ -8,9 +8,21 @@ on: - 'state-manager/**' - 'python-sdk/**' - '.github/workflows/integration-tests.yml' + pull_request: + branches: [main] + paths: + - 'integration-tests/**' + - 'state-manager/**' + - 'python-sdk/**' + - '.github/workflows/integration-tests.yml' + jobs: test: + defaults: + run: + working-directory: integration-tests + if: github.repository == 'exospherehost/exospherehost' runs-on: ubuntu-latest services: mongodb: diff --git a/.github/workflows/publish-python-sdk.yml b/.github/workflows/publish-python-sdk.yml index ea08fe12..1c5a891c 100644 --- a/.github/workflows/publish-python-sdk.yml +++ b/.github/workflows/publish-python-sdk.yml @@ -90,6 +90,64 @@ jobs: print(f'Version {version} is valid for PyPI publishing (contains beta indicator)') " + - name: Generate requirements file for SBOM + run: | + uv export --locked --format=requirements-txt --output-file=requirements.txt + echo "Generated requirements.txt for SBOM creation from lockfile" + + - name: Install SBOM generation tools + run: | + uv tool install cyclonedx-bom + echo "Installed cyclonedx-bom version:" + uv tool run cyclonedx-bom --version + uv tool install pip-audit + echo "Installed pip-audit version:" + uv tool run pip-audit --version + + - name: Generate SBOM with CycloneDX + run: | + uv tool run cyclonedx-py requirements --format json --output-file sbom-cyclonedx.json requirements.txt + echo "Generated CycloneDX SBOM in JSON format" + + - name: Generate vulnerability report with pip-audit + run: | + uv tool run pip-audit --format json --output vulnerability-report.json --requirement requirements.txt || true + echo "Generated vulnerability report (non-blocking)" + - run: uv build - - run: uv publish + - name: Publish to PyPI with provenance + run: | + # Get the current version + VERSION=$(uv run python -c " + import sys + sys.path.append('.') + from exospherehost._version import version + print(version) + ") + + echo "Checking if exospherehost version $VERSION already exists on PyPI..." + + # Query PyPI JSON API to check if version exists + HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/exospherehost/$VERSION/json") + + if [ "$HTTP_STATUS" = "200" ]; then + echo "Version $VERSION already exists on PyPI. Skipping publish." + exit 0 + elif [ "$HTTP_STATUS" = "404" ]; then + echo "Version $VERSION not found on PyPI. Proceeding with publish." + uv publish --provenance + else + echo "Unexpected HTTP status $HTTP_STATUS when checking PyPI. Proceeding with publish." + uv publish --provenance + fi + + - name: Upload SBOM artifacts + uses: actions/upload-artifact@v4 + with: + name: sbom-artifacts-beta-${{ github.sha }} + path: | + python-sdk/sbom-cyclonedx.json + python-sdk/requirements.txt + python-sdk/vulnerability-report.json + retention-days: 30 diff --git a/.github/workflows/release-python-sdk.yml b/.github/workflows/release-python-sdk.yml index b62061cc..eac8025f 100644 --- a/.github/workflows/release-python-sdk.yml +++ b/.github/workflows/release-python-sdk.yml @@ -122,6 +122,73 @@ jobs: print(f'Version {version} is valid for release publishing') " + - name: Generate requirements file for SBOM + run: | + uv export --locked --format=requirements-txt --output-file=requirements.txt + echo "Generated requirements.txt for SBOM creation from lockfile" + + - name: Install SBOM generation tools + run: | + uv tool install cyclonedx-bom + uv tool install pip-audit + + - name: Generate SBOM with CycloneDX + run: | + uv tool run cyclonedx-py requirements --format json --output-file sbom-cyclonedx.json requirements.txt + uv tool run cyclonedx-py requirements --format xml --output-file sbom-cyclonedx.xml requirements.txt + echo "Generated CycloneDX SBOM in JSON and XML formats" + + - name: Generate vulnerability report with pip-audit + run: | + uv tool run pip-audit --format json --output vulnerability-report.json --requirement requirements.txt || true + echo "Generated vulnerability report (non-blocking)" + + - name: Create SBOM summary + run: | + echo "## Software Bill of Materials (SBOM)" > sbom-summary.md + echo "" >> sbom-summary.md + echo "This release includes the following supply chain security artifacts:" >> sbom-summary.md + echo "" >> sbom-summary.md + echo "- **Provenance**: Cryptographic proof of build integrity using GitHub's OIDC tokens" >> sbom-summary.md + echo "- **SBOM**: Complete dependency inventory in CycloneDX format" >> sbom-summary.md + echo "- **Vulnerability Report**: Security scan results for all dependencies" >> sbom-summary.md + echo "" >> sbom-summary.md + echo "### Dependencies Count:" >> sbom-summary.md + echo "- Direct dependencies: $(grep -c '^[^#]' requirements.txt || echo '0')" >> sbom-summary.md + echo "- Total dependencies (including transitive): $(wc -l < requirements.txt)" >> sbom-summary.md + echo "" >> sbom-summary.md + echo "### Verification:" >> sbom-summary.md + echo "You can verify this package's provenance on PyPI using:" >> sbom-summary.md + echo '```bash' >> sbom-summary.md + echo 'pip install sigstore' >> sbom-summary.md + echo 'python -m sigstore verify --bundle exospherehost==${{ startsWith(github.ref_name, 'v') && substring(github.ref_name, 1) || github.ref_name }}' >> sbom-summary.md + echo '```' >> sbom-summary.md + - run: uv build - - run: uv publish \ No newline at end of file + - name: Publish to PyPI with provenance + run: uv publish --provenance + + - name: Upload SBOM artifacts + uses: actions/upload-artifact@v4 + with: + name: sbom-artifacts-${{ github.ref_name }} + path: | + python-sdk/sbom-cyclonedx.json + python-sdk/sbom-cyclonedx.xml + python-sdk/requirements.txt + python-sdk/vulnerability-report.json + python-sdk/sbom-summary.md + retention-days: 90 + + - name: Add SBOM to release assets + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + python-sdk/sbom-cyclonedx.json + python-sdk/sbom-cyclonedx.xml + python-sdk/sbom-summary.md + python-sdk/vulnerability-report.json + body_path: python-sdk/sbom-summary.md + append_body: true \ No newline at end of file diff --git a/README.md b/README.md index ee013ec1..b0704ffa 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Kubernetes Discord Stars + Integration Tests (main)

--- diff --git a/python-sdk/README.md b/python-sdk/README.md index fcfbb8f6..43719f3b 100644 --- a/python-sdk/README.md +++ b/python-sdk/README.md @@ -79,6 +79,50 @@ export EXOSPHERE_API_KEY="your-api-key" - **Scalability**: Designed for high-volume batch processing and workflows - **Graph Store (beta)**: Strings-only key-value store with per-run scope for sharing data across nodes (not durable across separate runs or clusters) +## Supply Chain Security + +The ExosphereHost Python SDK includes comprehensive supply chain security features to ensure package integrity and transparency: + +### Package Provenance + +All releases are published with cryptographic provenance using GitHub's OIDC tokens and the Sigstore ecosystem. This provides: + +- **Cryptographic proof** that packages were built by the official ExosphereHost repository +- **Tamper detection** to verify packages haven't been modified after publication +- **Build transparency** showing exactly how and where packages were created + +### Software Bill of Materials (SBOM) + +Each release includes a complete Software Bill of Materials in industry-standard CycloneDX format: + +- **Complete dependency inventory** listing all direct and transitive dependencies +- **Vulnerability scanning** results for all dependencies +- **License compliance** information for enterprise environments +- **Version tracking** for security auditing and compliance + +### Verification + +You can verify the authenticity of any ExosphereHost package: + +```bash +# Install verification tools +pip install sigstore + +# Verify package provenance (replace X.Y.Z with actual version) +python -m sigstore verify --bundle exospherehost==X.Y.Z +``` + +### Security Artifacts + +For each release, you can find the following security artifacts: + +- **SBOM files** (JSON and XML formats) attached to GitHub releases +- **Vulnerability reports** showing security scan results +- **Provenance attestations** available on PyPI +- **Build logs** publicly available in GitHub Actions + +These features align with modern software supply chain security best practices and help meet enterprise security requirements. + ## Architecture The SDK is built around two core concepts: