up the blokcing tasks
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Risk Bundle CI / risk-bundle-build (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Risk Bundle CI / risk-bundle-offline-kit (push) Has been cancelled
Risk Bundle CI / publish-checksums (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-11 02:32:18 +02:00
parent 92bc4d3a07
commit 49922dff5a
474 changed files with 76071 additions and 12411 deletions

View File

@@ -1,17 +1,389 @@
# Risk Bundles (Airgap) — outline
# Risk Bundles (Airgap)
- TBD pending export bundle shapes + hashing inputs.
Risk bundles package vulnerability intelligence data for offline/air-gapped environments. They provide deterministic, signed archives containing provider datasets (CISA KEV, FIRST EPSS, OSV) that can be verified and imported without network connectivity.
## Pending Inputs
- See sprint SPRINT_0309_0001_0009_docs_tasks_md_ix action tracker; inputs due 2025-12-09..12 from owning guilds.
## Bundle Structure
A risk bundle is a gzip-compressed tar archive (`risk-bundle.tar.gz`) with the following structure:
```
risk-bundle.tar.gz
├── manifests/
│ └── provider-manifest.json # Bundle metadata and provider entries
├── providers/
│ ├── cisa-kev/
│ │ └── snapshot # CISA Known Exploited Vulnerabilities JSON
│ ├── first-epss/
│ │ └── snapshot # FIRST EPSS scores CSV/JSON
│ └── osv/ # (optional) OpenSSF OSV bulk JSON
│ └── snapshot
└── signatures/
└── provider-manifest.dsse # DSSE envelope for manifest
```
## Provider Manifest
The `provider-manifest.json` contains bundle metadata and per-provider entries:
```json
{
"version": "1.0.0",
"bundleId": "risk-bundle-20241211-120000",
"createdAt": "2024-12-11T12:00:00Z",
"inputsHash": "sha256:abc123...",
"providers": [
{
"providerId": "cisa-kev",
"digest": "sha256:def456...",
"snapshotDate": "2024-12-11T00:00:00Z",
"optional": false
},
{
"providerId": "first-epss",
"digest": "sha256:789abc...",
"snapshotDate": "2024-12-11T00:00:00Z",
"optional": true
}
]
}
```
| Field | Description |
|-------|-------------|
| `version` | Manifest schema version (currently `1.0.0`) |
| `bundleId` | Unique identifier for this bundle |
| `createdAt` | ISO-8601 UTC timestamp of bundle creation |
| `inputsHash` | SHA-256 hash of concatenated provider digests (deterministic ordering) |
| `providers[]` | Array of provider entries sorted by `providerId` |
### Provider Entry Fields
| Field | Description |
|-------|-------------|
| `providerId` | Provider identifier (`cisa-kev`, `first-epss`, `osv`) |
| `digest` | SHA-256 hash of snapshot file (`sha256:<hex>`) |
| `snapshotDate` | ISO-8601 timestamp of provider data snapshot |
| `optional` | Whether provider is required for bundle validity |
## Provider Catalog
| Provider | Source | Coverage | Refresh | Required |
|----------|--------|----------|---------|----------|
| `cisa-kev` | CISA Known Exploited Vulnerabilities | Exploited CVEs with KEV flag | Daily | Yes |
| `first-epss` | FIRST EPSS scores | Exploitation probability per CVE | Daily | No |
| `osv` | OpenSSF OSV | OSS advisories with affected ranges | Weekly | No (opt-in) |
## Building Risk Bundles
### Using the Export Worker
The ExportCenter worker can build risk bundles via the `stella export risk-bundle` job:
```bash
# Build bundle with default providers (CISA KEV + EPSS)
stella export risk-bundle --output /path/to/output
# Include OSV providers (larger bundle)
stella export risk-bundle --output /path/to/output --include-osv
# Build with specific bundle ID
stella export risk-bundle --output /path/to/output --bundle-id "custom-bundle-id"
```
### Using the CI Build Script
For CI pipelines and deterministic testing, use the shell scripts:
```bash
# Build fixture bundle for CI testing (deterministic)
ops/devops/risk-bundle/build-bundle.sh --output /tmp/bundle --fixtures-only
# Build with OSV
ops/devops/risk-bundle/build-bundle.sh --output /tmp/bundle --fixtures-only --include-osv
# Build with custom bundle ID
ops/devops/risk-bundle/build-bundle.sh --output /tmp/bundle --fixtures-only --bundle-id "ci-test-bundle"
```
### Build Script Options
| Option | Description |
|--------|-------------|
| `--output <dir>` | Output directory for bundle artifacts (required) |
| `--fixtures-only` | Use fixture data instead of live provider downloads |
| `--include-osv` | Include OSV providers (increases bundle size) |
| `--bundle-id <id>` | Custom bundle ID (default: auto-generated with timestamp) |
### Build Outputs
After building, the output directory contains:
```
output/
├── risk-bundle.tar.gz # The bundle archive
├── risk-bundle.tar.gz.sha256 # SHA-256 checksum
└── manifest.json # Copy of provider-manifest.json
```
## Verifying Risk Bundles
### Using the CLI
```bash
# Basic verification
stella risk bundle verify --bundle-path ./risk-bundle.tar.gz
# With detached signature
stella risk bundle verify --bundle-path ./risk-bundle.tar.gz --signature-path ./bundle.sig
# Check Sigstore Rekor transparency log
stella risk bundle verify --bundle-path ./risk-bundle.tar.gz --check-rekor
# JSON output for automation
stella risk bundle verify --bundle-path ./risk-bundle.tar.gz --json
# Verbose output with warnings
stella risk bundle verify --bundle-path ./risk-bundle.tar.gz --verbose
```
### CLI Options
| Option | Description |
|--------|-------------|
| `--bundle-path, -b` | Path to risk bundle file (required) |
| `--signature-path, -s` | Path to detached signature file |
| `--check-rekor` | Verify transparency log entry in Sigstore Rekor |
| `--json` | Output results as JSON |
| `--tenant` | Tenant context for verification |
| `--verbose` | Show detailed output including warnings |
### Using the Verification Script
For offline/air-gap verification without the CLI:
```bash
# Basic verification
ops/devops/risk-bundle/verify-bundle.sh /path/to/risk-bundle.tar.gz
# With detached signature
ops/devops/risk-bundle/verify-bundle.sh /path/to/risk-bundle.tar.gz --signature /path/to/bundle.sig
# Strict mode (warnings are errors)
ops/devops/risk-bundle/verify-bundle.sh /path/to/risk-bundle.tar.gz --strict
# JSON output
ops/devops/risk-bundle/verify-bundle.sh /path/to/risk-bundle.tar.gz --json
```
### Verification Steps
The verification process performs these checks:
1. **Archive integrity** - Bundle is a valid tar.gz archive
2. **Structure validation** - Required files present (`manifests/provider-manifest.json`)
3. **Manifest parsing** - Valid JSON with required fields (`bundleId`, `version`, `providers`)
4. **Provider hash verification** - Each provider snapshot matches its declared digest
5. **Mandatory provider check** - `cisa-kev` must be present and valid
6. **DSSE signature validation** - Manifest signature verified (if present)
7. **Detached signature** - Bundle archive signature verified (if provided)
### Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Bundle is valid |
| 1 | Bundle is invalid or verification failed |
| 2 | Input error (missing file, bad arguments) |
### JSON Output Format
```json
{
"valid": true,
"bundleId": "risk-bundle-20241211-120000",
"version": "1.0.0",
"providerCount": 2,
"mandatoryProviderFound": true,
"errorCount": 0,
"warningCount": 1,
"errors": [],
"warnings": ["Optional provider not found: osv"]
}
```
## Importing Risk Bundles
### Prerequisites
1. Verify the bundle before import (see above)
2. Ensure the target system has sufficient storage
3. Back up existing provider data if replacing
### Import Steps
1. **Transfer the bundle** to the air-gapped environment via approved media
2. **Verify the bundle** using the CLI or verification script
3. **Extract to staging**:
```bash
mkdir -p /staging/risk-bundle
tar -xzf risk-bundle.tar.gz -C /staging/risk-bundle
```
4. **Validate provider data**:
```bash
# Verify individual provider hashes
sha256sum /staging/risk-bundle/providers/cisa-kev/snapshot
sha256sum /staging/risk-bundle/providers/first-epss/snapshot
```
5. **Import into Concelier**:
```bash
stella concelier import-risk-bundle --path /staging/risk-bundle
```
### Error Handling
| Error | Cause | Resolution |
|-------|-------|------------|
| "Bundle is not a valid tar.gz archive" | Corrupted download/transfer | Re-download and verify checksum |
| "Missing required file: manifests/provider-manifest.json" | Incomplete bundle | Rebuild bundle |
| "Missing mandatory provider: cisa-kev" | KEV snapshot missing | Rebuild with valid provider data |
| "Hash mismatch: cisa-kev" | Corrupted provider data | Re-download provider snapshot |
| "DSSE signature validation failed" | Tampered manifest | Investigate chain of custody |
## CI/CD Integration
### GitHub Actions / Gitea Workflow
The `.gitea/workflows/risk-bundle-ci.yml` workflow:
1. **Build job**: Compiles RiskBundles library, runs tests, builds fixture bundle
2. **Offline kit job**: Packages bundle for offline kit distribution
3. **Publish checksums job**: Publishes checksums to artifact store (main branch only)
```yaml
# Trigger manually or on push to relevant paths
on:
push:
paths:
- 'src/ExportCenter/StellaOps.ExportCenter.RiskBundles/**'
- 'ops/devops/risk-bundle/**'
workflow_dispatch:
inputs:
include_osv:
type: boolean
default: false
```
### Offline Kit Integration
Risk bundles are included in the Offline Update Kit:
```
offline-kit/
└── risk-bundles/
├── risk-bundle.tar.gz
├── risk-bundle.tar.gz.sha256
├── manifest.json
├── checksums.txt
└── kit-manifest.json
```
The `kit-manifest.json` provides metadata for offline kit consumers:
```json
{
"component": "risk-bundle",
"version": "20241211-120000",
"files": [
{"path": "risk-bundle.tar.gz", "checksum_file": "risk-bundle.tar.gz.sha256"},
{"path": "manifest.json", "checksum_file": "manifest.json.sha256"}
],
"verification": {
"checksums": "checksums.txt",
"signature": "risk-bundle.tar.gz.sig"
}
}
```
## Signing and Trust
### DSSE Manifest Signature
The `signatures/provider-manifest.dsse` file contains a Dead Simple Signing Envelope:
```json
{
"payloadType": "application/vnd.stellaops.risk-bundle.manifest+json",
"payload": "<base64-encoded-manifest>",
"signatures": [
{
"keyid": "risk-bundle-signing-key",
"sig": "<signature>"
}
]
}
```
### Offline Trust Roots
For air-gapped verification, include public keys in the bundle:
```
signatures/
├── provider-manifest.dsse
└── pubkeys/
└── <tenant>.pem
```
### Sigstore/Rekor Integration
When `--check-rekor` is specified, verification queries the Sigstore Rekor transparency log to confirm the bundle was published to the public ledger.
## Determinism Checklist
- [ ] Hash any inbound assets/payloads; place sums alongside artifacts (e.g., SHA256SUMS in this folder).
- [ ] Keep examples offline-friendly and deterministic (fixed seeds, pinned versions, stable ordering).
- [ ] Note source/approver for any provided captures or schemas.
## Sections to fill (once inputs arrive)
- Bundle structure and manifest fields.
- Build workflow (offline).
- Verification workflow with hash list.
- Import/consumption steps and error handling.
Risk bundles are designed for reproducible builds:
- [x] Fixed timestamps for tar entries (`--mtime="@<epoch>"`)
- [x] Sorted file ordering (`--sort=name`)
- [x] Numeric owner/group (`--owner=0 --group=0 --numeric-owner`)
- [x] Deterministic gzip compression (`gzip -n`)
- [x] Providers sorted by `providerId` in manifest
- [x] Files sorted lexicographically in bundle
- [x] UTF-8 canonical paths
- [x] ISO-8601 UTC timestamps
## Troubleshooting
### Common Issues
**Q: Bundle verification fails with "jq not available"**
A: The verification script uses `jq` for JSON parsing. Install it or use the CLI (`stella risk bundle verify`) which has built-in JSON support.
**Q: Hash mismatch after transfer**
A: Binary transfers can corrupt files. Use checksums:
```bash
# On source system
sha256sum risk-bundle.tar.gz > checksum.txt
# On target system
sha256sum -c checksum.txt
```
**Q: "Optional provider not found" warning**
A: This is informational. Optional providers (EPSS, OSV) enhance risk analysis but aren't required. Use `--strict` if you want to enforce their presence.
**Q: DSSE signature validation fails in air-gap**
A: Ensure the offline trust root is configured:
```bash
stella config set risk-bundle.trust-root /path/to/pubkey.pem
```
## Related Documentation
- [Offline Update Kit](../24_OFFLINE_KIT.md) - Complete offline kit documentation
- [Mirror Bundles](./mirror-bundles.md) - OCI artifact bundles for air-gap
- [Provider Matrix](../modules/export-center/operations/risk-bundle-provider-matrix.md) - Detailed provider specifications
- [ExportCenter Architecture](../modules/export-center/architecture.md) - Export service design