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
390 lines
12 KiB
Markdown
390 lines
12 KiB
Markdown
# Risk Bundles (Airgap)
|
|
|
|
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.
|
|
|
|
## 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
|
|
|
|
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
|