up
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-03 00:10:19 +02:00
parent ea1d58a89b
commit 37cba83708
158 changed files with 147438 additions and 867 deletions

View File

@@ -0,0 +1,121 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.local/airgap/manifest.schema.json",
"title": "Offline Kit Manifest",
"type": "object",
"additionalProperties": false,
"required": [
"schemaVersion",
"bundleId",
"tenant",
"environment",
"createdAt",
"stalenessWindowHours",
"tools",
"feeds",
"policies",
"chunks",
"hashes"
],
"properties": {
"schemaVersion": { "type": "string", "pattern": "^1\\.\\d+\\.\\d+$" },
"bundleId": { "type": "string", "pattern": "^offline-kit:[A-Za-z0-9._:-]+$" },
"tenant": { "type": "string", "minLength": 1 },
"environment": { "type": "string", "enum": ["prod", "stage", "dev", "test"] },
"createdAt": { "type": "string", "format": "date-time" },
"stalenessWindowHours": { "type": "integer", "minimum": 0 },
"tools": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "version", "sha256"],
"properties": {
"name": { "type": "string" },
"version": { "type": "string" },
"sha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }
}
},
"uniqueItems": true
},
"feeds": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "snapshot", "sha256"],
"properties": {
"name": { "type": "string" },
"snapshot": { "type": "string" },
"sha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" },
"stalenessHours": { "type": "integer", "minimum": 0 }
}
},
"uniqueItems": true
},
"policies": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "version", "sha256"],
"properties": {
"name": { "type": "string" },
"version": { "type": "string" },
"sha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }
}
},
"uniqueItems": true
},
"chunks": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["path", "sha256", "size"],
"properties": {
"path": { "type": "string" },
"sha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" },
"size": { "type": "integer", "minimum": 0 },
"kind": { "type": "string", "enum": ["advisory", "sbom", "vex", "policy", "graph", "tooling", "other"] }
}
},
"uniqueItems": true
},
"avScan": {
"type": "object",
"additionalProperties": false,
"required": ["status"],
"properties": {
"status": { "type": "string", "enum": ["not_run", "clean", "findings"] },
"scanner": { "type": "string" },
"scanAt": { "type": "string", "format": "date-time" },
"reportPath": { "type": "string" },
"reportSha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }
}
},
"hashes": {
"type": "object",
"additionalProperties": false,
"required": ["manifestSha256", "bundleSha256"],
"properties": {
"manifestSha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" },
"bundleSha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }
}
},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["type", "keyId", "signature"],
"properties": {
"type": { "type": "string", "enum": ["dsse", "jws-detached"] },
"keyId": { "type": "string" },
"signature": { "type": "string" },
"envelopeDigest": { "type": "string", "pattern": "^sha256:[A-Fa-f0-9]{64}$" }
}
}
}
}
}

View File

@@ -1,30 +1,40 @@
# AirGap Import & Verify (runbook outline)
# Offline Kit Import Verification Runbook
Related advisory: `docs/product-advisories/25-Nov-2025 - Airgap deployment playbook for StellaOps.md` (AG1AG12). Implements AIRGAP-VERIFY-510-014.
This runbook supports AIRGAP-MANIFEST-510-010/014. It validates bundle integrity before import, fully offline.
## Prerequisites
- `offline-kit/manifest.json` + `manifest.dsse` and `mirror.manifest` present.
- Trust roots: Rekor/TUF roots, Authority signing roots, AV/YARA public keys.
- Tools: `cosign` (or Stella verifier), `sha256sum`, `yara`, `python3`.
## Inputs
- Manifest: `offline-kit/manifest.json`
- Bundle archive: e.g., `offline-kit/bundle.tar.gz`
- Optional DSSE/JWS signature + public key for the manifest.
## Steps
1) Verify manifest signature
- `cosign verify-blob --key trust-roots/manifest.pub --signature manifest.dsse manifest.json`
- Sample helper: `scripts/airgap/verify-offline-kit.sh <kit-root>`
2) Check staleness and policy/graph hashes
- Compare `feeds[*].snapshot` dates to allowed window; ensure `policyHash`/`graphHash` match target site config; fail closed on mismatch unless override signed.
3) Verify chunks and Merkle root
- For each chunk listed in manifest, `sha256sum -c`; recompute Merkle root per manifest recipe; compare to `rootHash` field.
4) AV/YARA validation
- Run `yara -r rules/offline-kit.yar kit/`; confirm `avReport.sha256` matches signed report in manifest; block on any detection.
5) Replay depth selection
- Modes: `hash-only` (default), `full-recompute`, `policy-freeze`. Select via `--replay-mode`; enforce exit codes 0=pass, 3=stale, 4=hash-drift, 5=av-fail.
6) Ingress/egress receipts
- Generate DSSE receipt `{hash, operator, time, decision}`; store in Proof Graph; verify incoming receipts before import.
## Quick steps (offline)
```bash
src/AirGap/scripts/verify-manifest.sh offline-kit/manifest.json offline-kit/bundle.tar.gz \
offline-kit/manifest.sig offline-kit/manifest.pub.pem
```
What it does:
1. Computes SHA-256 of manifest and bundle, compares with `hashes.manifestSha256` and `hashes.bundleSha256`.
2. If signature + pubkey are provided, verifies the manifest signature with OpenSSL.
## Expected manifest fields
- `tools[]`, `feeds[]`, `policies[]` with SHA-256.
- `chunks[]` entries for every payload file (path, sha256, size, kind).
- `stalenessWindowHours` and `avScan` status.
- `hashes.manifestSha256` and `hashes.bundleSha256` must match the files on disk.
- Optional `signatures[]` (dsse/jws-detached) with `envelopeDigest`.
## Failure handling
- Hash mismatch → stop; regenerate bundle.
- Signature failure → stop; re-validate trust roots.
- Missing AV scan → treat as policy violation; rerun scans and update manifest.
## Outputs
- Exit code per replay mode outcome.
- Receipt DSSE stored at `receipts/{tenant}/{timestamp}.dsse`.
- Optional report `verify-report.json` summarizing checks.
- Exit 0 when all checks pass.
- Exit 25 for missing tools/hash/signature verification issues (see script).
> Expand with concrete scripts once tasks 510-010..014 land.
## References
- Schema: `docs/airgap/manifest.schema.json`
- Sample: `docs/airgap/samples/offline-kit-manifest.sample.json`
- Script: `src/AirGap/scripts/verify-manifest.sh`

View File

@@ -0,0 +1,43 @@
{
"$schema": "../manifest.schema.json",
"schemaVersion": "1.0.0",
"bundleId": "offline-kit:concelier:2025-12-02",
"tenant": "default",
"environment": "prod",
"createdAt": "2025-12-02T00:00:00Z",
"stalenessWindowHours": 168,
"tools": [
{ "name": "concelier-exporter", "version": "2.5.0", "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd" },
{ "name": "trivy-db", "version": "0.48.0", "sha256": "89abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567" }
],
"feeds": [
{ "name": "redhat-csaf", "snapshot": "2025-12-01", "sha256": "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210", "stalenessHours": 72 },
{ "name": "osv", "snapshot": "2025-12-01T23:00:00Z", "sha256": "0f0e0d0c0b0a09080706050403020100ffeeddccbbaa99887766554433221100", "stalenessHours": 24 }
],
"policies": [
{ "name": "policy-bundle", "version": "1.4.2", "sha256": "aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55" }
],
"chunks": [
{ "path": "chunks/advisories-0001.tzst", "sha256": "1234123412341234123412341234123412341234123412341234123412341234", "size": 1048576, "kind": "advisory" },
{ "path": "chunks/vex-0001.tzst", "sha256": "4321432143214321432143214321432143214321432143214321432143214321", "size": 524288, "kind": "vex" }
],
"avScan": {
"status": "clean",
"scanner": "clamav 1.4.1",
"scanAt": "2025-12-02T00:05:00Z",
"reportPath": "reports/av-scan.txt",
"reportSha256": "bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66bb66"
},
"hashes": {
"manifestSha256": "29d58b9fdc5c4e65b26c03f3bd9f442ff0c7f8514b8a9225f8b6417ffabc0101",
"bundleSha256": "d3c3f6c75c6a3f0906bcee457cc77a2d6d7c0f9d1a1d7da78c0d2ab8e0dba111"
},
"signatures": [
{
"type": "dsse",
"keyId": "airgap-manifest-dev",
"signature": "MEQCIGVyb3JrZXktc2lnbmF0dXJlLXNob3J0",
"envelopeDigest": "sha256:cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77cc77"
}
]
}