Some checks failed
		
		
	
	Docs CI / lint-and-preview (push) Has been cancelled
				
			- Implemented RustFsArtifactObjectStore for managing artifacts in RustFS. - Added unit tests for RustFsArtifactObjectStore functionality. - Created a RustFS migrator tool to transfer objects from S3 to RustFS. - Introduced policy preview and report models for API integration. - Added fixtures and tests for policy preview and report functionality. - Included necessary metadata and scripts for cache_pkg package.
		
			
				
	
	
		
			197 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Markdown
		
	
	
		
			Executable File
		
	
	
	
	
| # Offline Update Kit (OUK) — Air‑Gap Bundle
 | ||
| 
 | ||
| <!--
 | ||
|   Build‑time variable injection:
 | ||
|     {{ quota_anon }}   = 33
 | ||
|     {{ quota_token }}  = 333
 | ||
|     {{ dotnet }}       = "10 LTS"
 | ||
| -->
 | ||
| 
 | ||
| The **Offline Update Kit** packages everything Stella Ops needs to run on a
 | ||
| completely isolated network:
 | ||
| 
 | ||
| | Component | Contents |
 | ||
| |-----------|----------|
 | ||
| | **Merged vulnerability feeds** | OSV, GHSA plus optional NVD 2.0, CNNVD, CNVD, ENISA, JVN and BDU |
 | ||
| | **Container images** | `stella-ops`, *Zastava* sidecar (x86‑64 & arm64) |
 | ||
| | **Provenance** | Cosign signature, SPDX 2.3 SBOM, in‑toto SLSA attestation |
 | ||
| | **Attested manifest** | `offline-manifest.json` + detached JWS covering bundle metadata, signed during export. |
 | ||
| | **Delta patches** | Daily diff bundles keep size \< 350 MB |
 | ||
| | **Scanner plug-ins** | OS analyzers plus the Node.js, Go, .NET, and Python language analyzers packaged under `plugins/scanner/analyzers/**` with manifests so Workers load deterministically offline. |
 | ||
| 
 | ||
| **RU BDU note:** ship the official Russian Trusted Root/Sub CA bundle (`certificates/russian_trusted_bundle.pem`) inside the kit so `concelier:httpClients:source.bdu:trustedRootPaths` can resolve it when the service runs in an air‑gapped network. Drop the most recent `vulxml.zip` alongside the kit if operators need a cold-start cache.
 | ||
| 
 | ||
| **Language analyzers:** the kit now carries the restart-only Node.js, Go, .NET, and Python analyzer plug-ins (`plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Node/`, `...Lang.Go/`, `...Lang.DotNet/`, `...Lang.Python/`). Drop the directories alongside Worker binaries so the unified plug-in catalog can load them without outbound fetches; Rust remains on the Wave 4 roadmap.
 | ||
| 
 | ||
| *Scanner core:* C# 12 on **.NET {{ dotnet }}**.  
 | ||
| *Imports are idempotent and atomic — no service downtime.*
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 1 · Download & verify
 | ||
| 
 | ||
| ```bash
 | ||
| curl -LO https://get.stella-ops.org/ouk/stella-ops-offline-kit-<DATE>.tgz
 | ||
| curl -LO https://get.stella-ops.org/ouk/stella-ops-offline-kit-<DATE>.tgz.sig
 | ||
| curl -LO https://get.stella-ops.org/ouk/offline-manifest-<DATE>.json
 | ||
| curl -LO https://get.stella-ops.org/ouk/offline-manifest-<DATE>.json.jws
 | ||
| 
 | ||
| cosign verify-blob \
 | ||
|   --key https://stella-ops.org/keys/cosign.pub \
 | ||
|   --signature stella-ops-offline-kit-<DATE>.tgz.sig \
 | ||
|   stella-ops-offline-kit-<DATE>.tgz
 | ||
| ````
 | ||
| 
 | ||
| **CLI shortcut.** `stellaops-cli offline kit pull --destination ./offline-kit` downloads the bundle, manifest, and detached signatures in one step, resumes partial transfers, and writes a `.metadata.json` summary for later import.
 | ||
| 
 | ||
| Verification prints **OK** and the SHA‑256 digest; cross‑check against the
 | ||
| [changelog](https://git.stella-ops.org/stella-ops/offline-kit/-/releases).
 | ||
| 
 | ||
| Validate the attested manifest before distribution:
 | ||
| 
 | ||
| ```bash
 | ||
| cosign verify-blob \
 | ||
|   --key https://stella-ops.org/keys/cosign.pub \
 | ||
|   --signature offline-manifest-<DATE>.json.jws \
 | ||
|   offline-manifest-<DATE>.json
 | ||
| 
 | ||
| jq '.artifacts[] | {name, sha256, size, capturedAt}' offline-manifest-<DATE>.json
 | ||
| ```
 | ||
| 
 | ||
| The manifest enumerates every artefact (`name`, `sha256`, `size`, `capturedAt`) and is signed with the same key registry as Authority revocation bundles. Operators can ship the manifest alongside the tarball so downstream mirrors can re-verify without unpacking the kit.
 | ||
| 
 | ||
| Example excerpt (2025-10-23 kit) showing the Go and .NET analyzer plug-in payloads:
 | ||
| 
 | ||
| ```json
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Go/StellaOps.Scanner.Analyzers.Lang.Go.dll",
 | ||
|   "sha256": "a6dc850fc51151c8967ef46a3c4730f08b549667e041079431f39a8a72d0b641",
 | ||
|   "size": 33792,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Go/StellaOps.Scanner.Analyzers.Lang.Go.pdb",
 | ||
|   "sha256": "6cbdabf155282f458b89edf267e7f6bb2441a93029aad7aad45c8a9ec58b1b3b",
 | ||
|   "size": 32152,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Go/manifest.json",
 | ||
|   "sha256": "c19bfca2fcbb7cb18f1082b5d0d5a8f15fc799c648b50e95fce8d8b109ce48c9",
 | ||
|   "size": 622,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.dll",
 | ||
|   "sha256": "0734d23e33277ce2ccb596782d2d42cfe394b3d372dc34da9cb28b59df9b9d22",
 | ||
|   "size": 70144,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.pdb",
 | ||
|   "sha256": "b853c1ff4b196715f5bd1447e1a13edeb4940917527ec9bf153b5048da49abaf",
 | ||
|   "size": 40400,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.DotNet/manifest.json",
 | ||
|   "sha256": "5d483885f825f01bfd9943dcf2889ec2e0beba38ede92ecfe67d4f506cf14e37",
 | ||
|   "size": 647,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/StellaOps.Scanner.Analyzers.Lang.Python.dll",
 | ||
|   "sha256": "28b6e06c7cabf3b78f13f801cbb14962093f3d42c4ae9ec01babbcd14cda4644",
 | ||
|   "size": 53760,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/StellaOps.Scanner.Analyzers.Lang.Python.pdb",
 | ||
|   "sha256": "be4e34b4dc9a790fe1299e84213343b7c8ea90a2d22e5d7d1aa7585b8fedc946",
 | ||
|   "size": 34516,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| {
 | ||
|   "name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/manifest.json",
 | ||
|   "sha256": "bceea1e7542aae860b0ec5ba7b8b3aa960b21edc4d1efe60afc98ce289341ac3",
 | ||
|   "size": 671,
 | ||
|   "capturedAt": "2025-10-23T00:00:00Z"
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 2 · Import on the air‑gapped host
 | ||
| 
 | ||
| ```bash
 | ||
| docker compose --env-file .env \
 | ||
|   -f docker-compose.stella-ops.yml \
 | ||
|   exec stella-ops \
 | ||
|   stella admin import-offline-usage-kit stella-ops-offline-kit-<DATE>.tgz
 | ||
| ```
 | ||
| 
 | ||
| Alternatively, run
 | ||
| 
 | ||
| ```bash
 | ||
| stellaops-cli offline kit import stella-ops-offline-kit-<DATE>.tgz \
 | ||
|   --manifest offline-manifest-<DATE>.json \
 | ||
|   --bundle-signature stella-ops-offline-kit-<DATE>.tgz.sig \
 | ||
|   --manifest-signature offline-manifest-<DATE>.json.jws
 | ||
| ```
 | ||
| 
 | ||
| The CLI validates recorded digests (when `.metadata.json` is present) before streaming the multipart payload to `/api/offline-kit/import`.
 | ||
| 
 | ||
| * The CLI validates the Cosign signature **before** activation.
 | ||
| * Old feeds are kept until the new bundle is fully verified.
 | ||
| * Import time on a SATA SSD: ≈ 25 s for a 300 MB kit.
 | ||
| 
 | ||
| **Quick smoke test:** before import, verify the tarball carries the Go analyzer plug-in:
 | ||
| 
 | ||
| ```bash
 | ||
| tar -tzf stella-ops-offline-kit-<DATE>.tgz 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Go/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.DotNet/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/*'
 | ||
| ```
 | ||
| 
 | ||
| The manifest lookup above and this `tar` listing should both surface the Go analyzer DLL, PDB, and manifest entries before the kit is promoted.
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 3 · Delta patch workflow
 | ||
| 
 | ||
| 1. **Connected site** fetches `stella-ouk-YYYY‑MM‑DD.delta.tgz`.
 | ||
| 2. Transfer via any medium (USB, portable disk).
 | ||
| 3. `stella admin import-offline-usage-kit <delta>` applies only changed CVE rows & images.
 | ||
| 
 | ||
| Daily deltas are **< 30 MB**; weekly roll‑up produces a fresh full kit.
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 4 · Quota behaviour offline
 | ||
| 
 | ||
| The scanner enforces the same fair‑use limits offline:
 | ||
| 
 | ||
| * **Anonymous:** {{ quota\_anon }} scans per UTC day
 | ||
| * **Free JWT:** {{ quota\_token }} scans per UTC day
 | ||
| 
 | ||
| Soft reminder at 200 scans; throttle above the ceiling but **never block**.
 | ||
| See the detailed rules in
 | ||
| [`33_333_QUOTA_OVERVIEW.md`](33_333_QUOTA_OVERVIEW.md).
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 5 · Troubleshooting
 | ||
| 
 | ||
| | Symptom                                | Explanation                              | Fix                                   |
 | ||
| | -------------------------------------- | ---------------------------------------- | ------------------------------------- |
 | ||
| | `could not verify SBOM hash`           | Bundle corrupted in transit              | Re‑download / re‑copy                 |
 | ||
| | Import hangs at `Applying feeds…`      | Low disk space in `/var/lib/stella`      | Free ≥ 2 GiB before retry             |
 | ||
| | `quota exceeded` same day after import | Import resets counters at UTC 00:00 only | Wait until next UTC day or load a JWT |
 | ||
| 
 | ||
| ---
 | ||
| 
 | ||
| ## 6 · Related documentation
 | ||
| 
 | ||
| * **Install guide:** `/install/#air-gapped`
 | ||
| * **Sovereign mode rationale:** `/sovereign/`
 | ||
| * **Security policy:** `/security/#reporting-a-vulnerability`
 | ||
| * **CERT-Bund snapshots:** `python tools/certbund_offline_snapshot.py --help` (see `docs/ops/concelier-certbund-operations.md`)
 |