up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
sdk-generator-smoke / sdk-smoke (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
sdk-generator-smoke / sdk-smoke (push) Has been cancelled
This commit is contained in:
@@ -13,23 +13,23 @@ 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, `advisory-ai-web`, and `advisory-ai-worker` (x86‑64 & arm64) |
|
||||
| **Container images** | `stella-ops`, *Zastava* sidecar, `advisory-ai-web`, and `advisory-ai-worker` (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, Python, and Rust language analyzers packaged under `plugins/scanner/analyzers/**` with manifests so Workers load deterministically offline. |
|
||||
| **Debug store** | `.debug` artefacts laid out under `debug/.build-id/<aa>/<rest>.debug` with `debug/debug-manifest.json` mapping build-ids to originating images for symbol retrieval. |
|
||||
| **Telemetry collector bundle** | `telemetry/telemetry-offline-bundle.tar.gz` plus `.sha256`, containing OTLP collector config, Helm/Compose overlays, and operator instructions. |
|
||||
| **CLI + Task Packs** | `cli/` binaries from `release/cli`, Task Runner bootstrap (`bootstrap/task-runner/task-runner.yaml.sample`), and task-pack docs under `docs/task-packs/**` + `docs/modules/taskrunner/**`. |
|
||||
| **Orchestrator/Export/Notifier kits** | Orchestrator service, worker SDK, Postgres snapshot, dashboards (`orchestrator/**`), Export Center bundles (`export-center/**`), Notifier offline packs (`notifier/**`). |
|
||||
| **Container air-gap bundles** | Any tar/tgz under `containers/` or `images/` (mirrored registries) plus `docs/airgap/mirror-bundles.md`. |
|
||||
| **Surface.Secrets** | Encrypted secrets bundles and manifests (`surface-secrets/**`) for sealed-mode bootstrap. |
|
||||
| **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, Python, Ruby, and Rust language analyzers packaged under `plugins/scanner/analyzers/**` with manifests so Workers load deterministically offline. |
|
||||
| **Debug store** | `.debug` artefacts laid out under `debug/.build-id/<aa>/<rest>.debug` with `debug/debug-manifest.json` mapping build-ids to originating images for symbol retrieval. |
|
||||
| **Telemetry collector bundle** | `telemetry/telemetry-offline-bundle.tar.gz` plus `.sha256`, containing OTLP collector config, Helm/Compose overlays, and operator instructions. |
|
||||
| **CLI + Task Packs** | `cli/` binaries from `release/cli`, Task Runner bootstrap (`bootstrap/task-runner/task-runner.yaml.sample`), and task-pack docs under `docs/task-packs/**` + `docs/modules/taskrunner/**`. |
|
||||
| **Orchestrator/Export/Notifier kits** | Orchestrator service, worker SDK, Postgres snapshot, dashboards (`orchestrator/**`), Export Center bundles (`export-center/**`), Notifier offline packs (`notifier/**`). |
|
||||
| **Container air-gap bundles** | Any tar/tgz under `containers/` or `images/` (mirrored registries) plus `docs/airgap/mirror-bundles.md`. |
|
||||
| **Surface.Secrets** | Encrypted secrets bundles and manifests (`surface-secrets/**`) for sealed-mode bootstrap. |
|
||||
|
||||
**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, Python, and Rust plug-ins (`plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Node/`, `...Lang.Go/`, `...Lang.DotNet/`, `...Lang.Python/`, `...Lang.Rust/`). Drop the directories alongside Worker binaries so the unified plug-in catalog can load them without outbound fetches.
|
||||
|
||||
**Advisory AI volume primer:** ship a tarball containing empty `queue/`, `plans/`, and `outputs/` directories plus their ownership metadata. During import, extract it onto the RWX volume used by `advisory-ai-web` and `advisory-ai-worker` so pods start with the expected directory tree even on air-gapped nodes.
|
||||
**Language analyzers:** the kit now carries the restart-only Node.js, Go, .NET, Python, Ruby, and Rust plug-ins (`plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Node/`, `...Lang.Go/`, `...Lang.DotNet/`, `...Lang.Python/`, `...Lang.Ruby/`, `...Lang.Rust/`). Drop the directories alongside Worker binaries so the unified plug-in catalog can load them without outbound fetches. The Ruby analyzer includes optional runtime capture via TracePoint; set `STELLA_RUBY_ENTRYPOINT` to enable runtime evidence collection.
|
||||
|
||||
**Advisory AI volume primer:** ship a tarball containing empty `queue/`, `plans/`, and `outputs/` directories plus their ownership metadata. During import, extract it onto the RWX volume used by `advisory-ai-web` and `advisory-ai-worker` so pods start with the expected directory tree even on air-gapped nodes.
|
||||
|
||||
*Scanner core:* C# 12 on **.NET {{ dotnet }}**.
|
||||
*Imports are idempotent and atomic — no service downtime.*
|
||||
@@ -50,15 +50,15 @@ The helper copies `debug/.build-id/**`, validates `debug/debug-manifest.json` ag
|
||||
|
||||
## 0.1 · Automated packaging
|
||||
|
||||
The packaging workflow is scripted via `ops/offline-kit/build_offline_kit.py`.
|
||||
It verifies the release artefacts, runs the Python analyzer smoke suite, mirrors the debug store, and emits a deterministic tarball + manifest set.
|
||||
|
||||
What it picks up automatically (if present under `--release-dir`):
|
||||
- `cli/**` → CLI binaries and installers.
|
||||
- `containers/**` or `images/**` → air-gap container bundles.
|
||||
- `orchestrator/{service,worker-sdk,postgres,dashboards}/**`.
|
||||
- `export-center/**`, `notifier/**`, `surface-secrets/**`.
|
||||
- Docs: `docs/task-packs/**`, `docs/modules/taskrunner/**`, `docs/airgap/mirror-bundles.md`.
|
||||
The packaging workflow is scripted via `ops/offline-kit/build_offline_kit.py`.
|
||||
It verifies the release artefacts, runs the Python analyzer smoke suite, mirrors the debug store, and emits a deterministic tarball + manifest set.
|
||||
|
||||
What it picks up automatically (if present under `--release-dir`):
|
||||
- `cli/**` → CLI binaries and installers.
|
||||
- `containers/**` or `images/**` → air-gap container bundles.
|
||||
- `orchestrator/{service,worker-sdk,postgres,dashboards}/**`.
|
||||
- `export-center/**`, `notifier/**`, `surface-secrets/**`.
|
||||
- Docs: `docs/task-packs/**`, `docs/modules/taskrunner/**`, `docs/airgap/mirror-bundles.md`.
|
||||
|
||||
```bash
|
||||
python ops/offline-kit/build_offline_kit.py \
|
||||
@@ -72,13 +72,13 @@ python ops/offline-kit/build_offline_kit.py \
|
||||
python ops/devops/telemetry/package_offline_bundle.py --output out/telemetry/telemetry-offline-bundle.tar.gz
|
||||
```
|
||||
|
||||
Outputs:
|
||||
|
||||
- `stella-ops-offline-kit-<version>-<channel>.tar.gz` — bundle (mtime/uid/gid forced to zero for reproducibility)
|
||||
- `stella-ops-offline-kit-<version>-<channel>.tar.gz.sha256` — bundle digest
|
||||
- `manifest/offline-manifest.json` + `.sha256` — inventories every file in the bundle
|
||||
- `<bundle>.metadata.json` — descriptor consumed by the CLI/Console import tooling; includes `counts` for `cli`, `taskPacksDocs`, `containers`, `orchestrator`, `exportCenter`, `notifier`, `surfaceSecrets` so operators can sanity-check bundle composition without unpacking
|
||||
- `telemetry/telemetry-offline-bundle.tar.gz` + `.sha256` — packaged OTLP collector assets for environments without upstream access
|
||||
Outputs:
|
||||
|
||||
- `stella-ops-offline-kit-<version>-<channel>.tar.gz` — bundle (mtime/uid/gid forced to zero for reproducibility)
|
||||
- `stella-ops-offline-kit-<version>-<channel>.tar.gz.sha256` — bundle digest
|
||||
- `manifest/offline-manifest.json` + `.sha256` — inventories every file in the bundle
|
||||
- `<bundle>.metadata.json` — descriptor consumed by the CLI/Console import tooling; includes `counts` for `cli`, `taskPacksDocs`, `containers`, `orchestrator`, `exportCenter`, `notifier`, `surfaceSecrets` so operators can sanity-check bundle composition without unpacking
|
||||
- `telemetry/telemetry-offline-bundle.tar.gz` + `.sha256` — packaged OTLP collector assets for environments without upstream access
|
||||
- `plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/*.sig` (+ `.sha256`) — Cosign signatures for the Python analyzer DLL and manifest
|
||||
|
||||
### Policy Gateway configuration bundle
|
||||
@@ -175,31 +175,49 @@ Example excerpt (2025-10-23 kit) showing the Go and .NET analyzer plug-in payloa
|
||||
"size": 31896,
|
||||
"capturedAt": "2025-10-26T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/manifest.json",
|
||||
"sha256": "668ad9a1a35485628677b639db4d996d1e25f62021680a81a22482483800e557",
|
||||
"size": 648,
|
||||
"capturedAt": "2025-10-26T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.dll",
|
||||
"sha256": "d90ba8b6ace7d98db563b1dec178d57ac09df474e1342fa1daa38bd55e17b185",
|
||||
"size": 54784,
|
||||
"capturedAt": "2025-11-01T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.pdb",
|
||||
"sha256": "6fac88640a4980d2bb8f7ea2dd2f3d0a521b90fd30ae3a84981575d5f76fa3df",
|
||||
"size": 36636,
|
||||
"capturedAt": "2025-11-01T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Rust/manifest.json",
|
||||
"sha256": "1ec47d1a2103ad5eff23e903532cb76b1ed7ded85d301c1a6631ff21aa966ed4",
|
||||
"size": 658,
|
||||
"capturedAt": "2025-11-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/manifest.json",
|
||||
"sha256": "668ad9a1a35485628677b639db4d996d1e25f62021680a81a22482483800e557",
|
||||
"size": 648,
|
||||
"capturedAt": "2025-10-26T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Ruby/StellaOps.Scanner.Analyzers.Lang.Ruby.dll",
|
||||
"sha256": "<computed-at-release>",
|
||||
"size": 0,
|
||||
"capturedAt": "2025-11-27T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Ruby/StellaOps.Scanner.Analyzers.Lang.Ruby.pdb",
|
||||
"sha256": "<computed-at-release>",
|
||||
"size": 0,
|
||||
"capturedAt": "2025-11-27T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Ruby/manifest.json",
|
||||
"sha256": "<computed-at-release>",
|
||||
"size": 0,
|
||||
"capturedAt": "2025-11-27T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.dll",
|
||||
"sha256": "d90ba8b6ace7d98db563b1dec178d57ac09df474e1342fa1daa38bd55e17b185",
|
||||
"size": 54784,
|
||||
"capturedAt": "2025-11-01T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.pdb",
|
||||
"sha256": "6fac88640a4980d2bb8f7ea2dd2f3d0a521b90fd30ae3a84981575d5f76fa3df",
|
||||
"size": 36636,
|
||||
"capturedAt": "2025-11-01T00:00:00Z"
|
||||
}
|
||||
{
|
||||
"name": "plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Rust/manifest.json",
|
||||
"sha256": "1ec47d1a2103ad5eff23e903532cb76b1ed7ded85d301c1a6631ff21aa966ed4",
|
||||
"size": 658,
|
||||
"capturedAt": "2025-11-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -245,25 +263,25 @@ The Offline Kit carries the same helper scripts under `scripts/`:
|
||||
### Authority scope sanity check
|
||||
|
||||
Offline installs rely on the bundled `etc/authority.yaml.sample`. Before promoting the kit, confirm the sample clients keep the Aggregation-Only guardrails:
|
||||
|
||||
- `aoc-verifier` requests `aoc:verify`, `advisory:read`, and `vex:read`.
|
||||
- `signals-uploader` requests `signals:write`, `signals:read`, and `aoc:verify`.
|
||||
- `airgap-operator` requests `airgap:status:read`, `airgap:import`, and `airgap:seal`.
|
||||
- `task-runner` requests `packs.run` and `packs.read` for execution flows.
|
||||
- `pack-approver` requests `packs.approve` (plus `packs.read`) for automation that resumes runs after approvals.
|
||||
- `packs-registry` requests `packs.write` and `packs.read` for publishing bundles.
|
||||
|
||||
Authority now rejects tokens that request `advisory:read`, `vex:read`, or any `signals:*` scope without `aoc:verify`; the sample has been updated to match. Air-gap scopes (`airgap:*`) also require an explicit tenant assignment—match the updated roles (`airgap-viewer`, `airgap-operator`, `airgap-admin`) so automation fails closed when misconfigured.
|
||||
|
||||
- `aoc-verifier` requests `aoc:verify`, `advisory:read`, and `vex:read`.
|
||||
- `signals-uploader` requests `signals:write`, `signals:read`, and `aoc:verify`.
|
||||
- `airgap-operator` requests `airgap:status:read`, `airgap:import`, and `airgap:seal`.
|
||||
- `task-runner` requests `packs.run` and `packs.read` for execution flows.
|
||||
- `pack-approver` requests `packs.approve` (plus `packs.read`) for automation that resumes runs after approvals.
|
||||
- `packs-registry` requests `packs.write` and `packs.read` for publishing bundles.
|
||||
|
||||
Authority now rejects tokens that request `advisory:read`, `vex:read`, or any `signals:*` scope without `aoc:verify`; the sample has been updated to match. Air-gap scopes (`airgap:*`) also require an explicit tenant assignment—match the updated roles (`airgap-viewer`, `airgap-operator`, `airgap-admin`) so automation fails closed when misconfigured.
|
||||
|
||||
**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/*'
|
||||
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/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Ruby/*'
|
||||
```
|
||||
|
||||
The manifest lookup above and this `tar` listing should both surface the Go analyzer DLL, PDB, and manifest entries before the kit is promoted.
|
||||
|
||||
> **Release guardrail.** The automated release pipeline now publishes the Python and Rust plug-ins from source and executes `dotnet run --project src/Tools/LanguageAnalyzerSmoke --configuration Release -- --repo-root <checkout> --analyzer <id>` to validate manifest integrity and cold/warm determinism within the < 30 s / < 5 s budgets (differences versus repository goldens are logged for triage). Run `ops/offline-kit/run-python-analyzer-smoke.sh` and `ops/offline-kit/run-rust-analyzer-smoke.sh` locally before shipping a refreshed kit if you rebuild artefacts outside CI or when preparing the air-gap bundle.
|
||||
> **Release guardrail.** The automated release pipeline now publishes the Python, Ruby, and Rust plug-ins from source and executes `dotnet run --project src/Tools/LanguageAnalyzerSmoke --configuration Release -- --repo-root <checkout> --analyzer <id>` to validate manifest integrity and cold/warm determinism within the < 30 s / < 5 s budgets (differences versus repository goldens are logged for triage). Run `ops/offline-kit/run-python-analyzer-smoke.sh` and `ops/offline-kit/run-ruby-analyzer-smoke.sh`, and `ops/offline-kit/run-rust-analyzer-smoke.sh` locally before shipping a refreshed kit if you rebuild artefacts outside CI or when preparing the air-gap bundle.
|
||||
|
||||
### Debug store mirror
|
||||
|
||||
|
||||
Reference in New Issue
Block a user