feat: Add DigestUpsertRequest and LockEntity models
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
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled

- Introduced DigestUpsertRequest for handling digest upsert requests with properties like ChannelId, Recipient, DigestKey, Events, and CollectUntil.
- Created LockEntity to represent a lightweight distributed lock entry with properties such as Id, TenantId, Resource, Owner, ExpiresAt, and CreatedAt.

feat: Implement ILockRepository interface and LockRepository class

- Defined ILockRepository interface with methods for acquiring and releasing locks.
- Implemented LockRepository class with methods to try acquiring a lock and releasing it, using SQL for upsert operations.

feat: Add SurfaceManifestPointer record for manifest pointers

- Introduced SurfaceManifestPointer to represent a minimal pointer to a Surface.FS manifest associated with an image digest.

feat: Create PolicySimulationInputLock and related validation logic

- Added PolicySimulationInputLock record to describe policy simulation inputs and expected digests.
- Implemented validation logic for policy simulation inputs, including checks for digest drift and shadow mode requirements.

test: Add unit tests for ReplayVerificationService and ReplayVerifier

- Created ReplayVerificationServiceTests to validate the behavior of the ReplayVerificationService under various scenarios.
- Developed ReplayVerifierTests to ensure the correctness of the ReplayVerifier logic.

test: Implement PolicySimulationInputLockValidatorTests

- Added tests for PolicySimulationInputLockValidator to verify the validation logic against expected inputs and conditions.

chore: Add cosign key example and signing scripts

- Included a placeholder cosign key example for development purposes.
- Added a script for signing Signals artifacts using cosign with support for both v2 and v3.

chore: Create script for uploading evidence to the evidence locker

- Developed a script to upload evidence to the evidence locker, ensuring required environment variables are set.
This commit is contained in:
StellaOps Bot
2025-12-03 07:51:50 +02:00
parent 37cba83708
commit e923880694
171 changed files with 6567 additions and 2952 deletions

View File

@@ -0,0 +1,60 @@
# AV/YARA Scan Runbook (AIRGAP-AV-510-011)
Purpose: ensure every offline-kit bundle is scanned pre-publish and post-ingest, with deterministic reports and optional signatures.
## Inputs
- Bundle directory containing `manifest.json` and payload files.
- AV scanner (e.g., ClamAV) and optional YARA rule set available locally (no network).
## Steps (offline)
1. Scan all bundle files:
```bash
clamscan -r --max-filesize=2G --max-scansize=4G --no-summary bundle/ > reports/av-scan.txt
```
2. Convert to structured report:
```bash
python - <<'PY'
import hashlib, json, pathlib, sys
root = pathlib.Path("bundle")
report = {
"scanner": "clamav",
"scannerVersion": "1.4.1",
"startedAt": "2025-12-02T00:02:00Z",
"completedAt": "2025-12-02T00:04:30Z",
"status": "clean",
"artifacts": [],
"errors": []
}
for path in root.glob("**/*"):
if path.is_file():
h = hashlib.sha256(path.read_bytes()).hexdigest()
report["artifacts"].append({
"path": str(path.relative_to(root)),
"sha256": h,
"result": "clean",
"yaraRules": []
})
json.dump(report, sys.stdout, indent=2)
PY
```
3. Validate report against schema:
```bash
jq empty --argfile schema docs/airgap/av-report.schema.json 'input' < docs/airgap/samples/av-report.sample.json >/dev/null
```
4. Optionally sign report (detached):
```bash
openssl dgst -sha256 -sign airgap-av-key.pem reports/av-report.json > reports/av-report.sig
```
5. Update `manifest.json`:
- Set `avScan.status` to `clean` or `findings`.
- `avScan.reportPath` and `avScan.reportSha256` must match the generated report.
## Acceptance checks
- Report validates against `docs/airgap/av-report.schema.json`.
- `manifest.json` hashes updated and verified via `src/AirGap/scripts/verify-manifest.sh`.
- If any artifact result is `malicious`/`suspicious`, bundle must be rejected and re-scanned after remediation.
## References
- Manifest schema: `docs/airgap/manifest.schema.json`
- Sample report: `docs/airgap/samples/av-report.sample.json`
- Manifest verifier: `src/AirGap/scripts/verify-manifest.sh`

View File

@@ -1,40 +1,57 @@
# Offline Kit Import Verification Runbook
This runbook supports AIRGAP-MANIFEST-510-010/014. It validates bundle integrity before import, fully offline.
This runbook supports AIRGAP-MANIFEST-510-010, AIRGAP-REPLAY-510-013, and AIRGAP-VERIFY-510-014. It validates bundles fully offline and enforces replay depth.
## Inputs
- Manifest: `offline-kit/manifest.json`
- Bundle archive: e.g., `offline-kit/bundle.tar.gz`
- Optional DSSE/JWS signature + public key for the manifest.
## Replay depth levels (manifest `replayPolicy`)
- `hash-only`: verify manifest/bundle digests, staleness window, optional signature.
- `full-recompute`: hash-only + every chunk hash + AV report hash.
- `policy-freeze`: full-recompute + manifest policies must include the sealed policy hash (prevents imports with drifting policy/graph material).
## Quick steps (offline)
## Quick steps
```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
src/AirGap/scripts/verify-kit.sh \
--manifest offline-kit/manifest.json \
--bundle offline-kit/bundle.tar.gz \
--signature offline-kit/manifest.sig --pubkey offline-kit/manifest.pub.pem \
--av-report offline-kit/reports/av-report.json \
--receipt offline-kit/receipts/ingress.json \
--sealed-policy-hash "aa55..." \
--depth policy-freeze
```
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.
## What the script enforces
1) Manifest & bundle digests match (`hashes.*`).
2) Optional manifest signature is valid (OpenSSL).
3) Staleness: `createdAt` must be within `stalenessWindowHours` of `--now` (defaults to UTC now).
4) AV: `avScan.status` must not be `findings`; if `reportSha256` is present, the provided report hash must match.
5) Chunks (full-recompute/policy-freeze): every `chunks[].path` exists relative to the manifest and matches its recorded SHA-256.
6) Policy-freeze: `--sealed-policy-hash` must appear in `policies[].sha256`.
7) Optional: `--expected-graph-sha` checks the graph chunk hash; `--receipt` reuses `verify-receipt.sh` to bind the receipt to the manifest/bundle hashes.
## 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`.
Exit codes: hash mismatch (3/4), staleness (5), AV issues (68), chunk drift (910), graph mismatch (11), policy drift (1213), bad depth (14).
## 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.
## Controller verify endpoint (server-side guard)
## Outputs
- Exit 0 when all checks pass.
- Exit 25 for missing tools/hash/signature verification issues (see script).
`POST /system/airgap/verify` (scope `airgap:verify`) expects `VerifyRequest`:
```jsonc
{
"depth": "PolicyFreeze",
"manifestSha256": "...",
"bundleSha256": "...",
"computedManifestSha256": "...", // from offline verifier
"computedBundleSha256": "...",
"manifestCreatedAt": "2025-12-02T00:00:00Z",
"stalenessWindowHours": 168,
"bundlePolicyHash": "aa55...",
"sealedPolicyHash": "aa55..." // optional, controller fills from state if omitted
}
```
The controller applies the same replay rules and returns `{ "valid": true|false, "reason": "..." }`.
## References
- Schema: `docs/airgap/manifest.schema.json`
- Sample: `docs/airgap/samples/offline-kit-manifest.sample.json`
- Script: `src/AirGap/scripts/verify-manifest.sh`
- Samples: `docs/airgap/samples/offline-kit-manifest.sample.json`, `docs/airgap/samples/av-report.sample.json`, `docs/airgap/samples/receipt.sample.json`
- Scripts: `src/AirGap/scripts/verify-kit.sh`, `src/AirGap/scripts/verify-manifest.sh`, `src/AirGap/scripts/verify-receipt.sh`