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
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user