Skip to content
Merged
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
14 changes: 13 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Integration Tests for Exosphere
name: Integration Tests

on:
push:
Expand All @@ -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:
Expand Down
60 changes: 59 additions & 1 deletion .github/workflows/publish-python-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
69 changes: 68 additions & 1 deletion .github/workflows/release-python-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 <bundle-file> 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
- 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<a href="https://github.com/orgs/exospherehost/packages?repo_name=exospherehost"><img src="https://img.shields.io/badge/Kubernetes-native-326ce5?logo=kubernetes&logoColor=white" alt="Kubernetes"></a>
<a href="https://discord.com/invite/zT92CAgvkj"><img src="https://badgen.net/discord/members/zT92CAgvkj" alt="Discord"></a>
<a href="https://github.com/exospherehost/exospherehost"><img src="https://img.shields.io/github/stars/exospherehost/exospherehost?style=social" alt="Stars"></a>
<a href="https://github.com/exospherehost/exospherehost/actions/workflows/integration-tests.yml?query=branch%3Amain"><img src="https://img.shields.io/github/actions/workflow/status/exospherehost/exospherehost/integration-tests.yml?branch=main" alt="Integration Tests (main)"></a>
</p>

---
Expand Down
44 changes: 44 additions & 0 deletions python-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <bundle-file> 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:
Expand Down
Loading