Files
git.stella-ops.org/docs/24_OFFLINE_KIT.md
Vladimir Moushkov f4d7a15a00
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
feat: Add RustFS artifact object store and migration tool
- 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.
2025-10-23 18:53:18 +03:00

8.6 KiB
Executable File
Raw Blame History

Offline Update Kit (OUK) — AirGap Bundle

The Offline Update Kit packages everything StellaOps 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 (x8664 &arm64)
Provenance Cosign signature, SPDX 2.3 SBOM, intoto SLSA attestation
Attested manifest offline-manifest.json + detached JWS covering bundle metadata, signed during export.
Delta patches Daily diff bundles keep size <350MB
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 airgapped 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 Wave4 roadmap.

Scanner core: C# 12 on .NET{{ dotnet }}.
Imports are idempotent and atomic — no service downtime.


1·Download & verify

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 SHA256 digest; crosscheck against the changelog.

Validate the attested manifest before distribution:

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:

{
  "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 airgapped host

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

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: ≈25s for a 300MB kit.

Quick smoke test: before import, verify the tarball carries the Go analyzer plug-in:

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-YYYYMMDD.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 <30MB; weekly rollup produces a fresh full kit.


4·Quota behaviour offline

The scanner enforces the same fairuse 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.


5·Troubleshooting

Symptom Explanation Fix
could not verify SBOM hash Bundle corrupted in transit Redownload / recopy
Import hangs at Applying feeds… Low disk space in /var/lib/stella Free ≥2GiB 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

  • 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)