nsauditor-ai 0.2.49 → 0.2.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ A modular, AI-assisted network security audit platform that scans, understands,
7
7
  [![npm](https://img.shields.io/npm/v/nsauditor-ai.svg)](https://www.npmjs.com/package/nsauditor-ai)
8
8
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
9
  [![Node.js 20+](https://img.shields.io/badge/node-20%2B-green.svg)](https://nodejs.org)
10
- [![Tests](https://img.shields.io/badge/tests-1308%20passing-brightgreen.svg)](#tests)
10
+ [![Tests](https://img.shields.io/badge/tests-1582%20passing-brightgreen.svg)](#tests)
11
11
 
12
12
  ---
13
13
 
@@ -17,6 +17,40 @@ NSAuditor AI is the open-source core of a privacy-first security intelligence pl
17
17
 
18
18
  ## What's New
19
19
 
20
+ **The Pro `report` subcommand, over a run record that states its own coverage (CE 0.2.51 / Enterprise 0.44.0).**
21
+ `nsauditor-ai report --from <dir> --format executive|jira` turns a completed scan run into a
22
+ client-facing deliverable — a self-contained, print-ready HTML report a consultant sends to their
23
+ customer, or a Jira-importer CSV. Beneath it is a **per-run scan record**: written at run start,
24
+ appended per host, finalized at the end, so the report's cover **states** what was covered — hosts
25
+ requested, written and reachable, and the exploit-intelligence as-of dates read from the store's own
26
+ metadata — instead of implying completeness. An incomplete run says so on the cover; `--allow-partial`
27
+ renders it anyway with the caveat visible, never hidden. Two limits are shipped as text rather than
28
+ left to be discovered: the **Jira import mapping has not been verified against a live Jira instance**,
29
+ and a value-less `--from`/`--brand`/`--run`/`--out` is a **fatal error, not a silent default**. On the
30
+ Enterprise side the same cycle stops reporting an S3 audit-trail gap on a bucket whose object-level
31
+ reads and writes a CloudTrail data-event trail already records. See the
32
+ [`report` command section](#report-command-pro) and the [CHANGELOG](./CHANGELOG.md).
33
+ ⚠️ **The Enterprise peer floor stays `>=0.2.49` — it is NOT raised to 0.2.51.** Raising it would charge
34
+ every Enterprise operator an upgrade for a Community feature they may not want. The consequence is
35
+ worth stating rather than discovering: an Enterprise 0.44.0 install resolves cleanly against Community
36
+ 0.2.49 or 0.2.50 and simply has **no `report` command**. Install Community 0.2.51 to get it.
37
+ Every scan now also writes `scan_run_<runId>.json` at the root of `--out` — the record the report is
38
+ built from. On the free tier these are pruned after a retention window; on Pro they are kept.
39
+
40
+ **A provider badge you can trust, and an evidence gap that never tells an auditor what to type (CE 0.2.50 / Enterprise 0.43.0).**
41
+ **No Community behaviour changed this cycle** — the version moves so the trio stays in lockstep, and **the Enterprise peer floor stays `>=0.2.49`** rather than being raised reflexively, because the
42
+ one Community behaviour the Enterprise fix depends on already shipped there. What changed is on the
43
+ Enterprise side and shows up in output a Community user also reads: an Enterprise scan whose cloud
44
+ SDK failed to load used to report that provider as **audited**, because a plugin result carrying
45
+ neither an error nor a skip flag falls through to `ran` in this package's plugin manager, and
46
+ `auditedProviders` is derived from `ran`. Eighteen refusals across seventeen AWS and GCP plugins now
47
+ carry their cause, so such a provider appears as `errored` and drops out of `auditedProviders`.
48
+ Second: the compliance engine quotes a plugin's reason into the *"could not run"* sentence of every
49
+ control that plugin evidences, and it used to quote the whole thrown message — so the SDK loaders'
50
+ own `Install: npm install <pkg>@latest` reached the evidence-gap text of 7 SOC 2, 2 GDPR and 12 NIST
51
+ SP 800-171 controls. **The report now states what was not evidenced; the operator channel states how
52
+ to change it** — which matters most for air-gapped installs, where that instruction cannot be run.
53
+
20
54
  **Sovereign and air-gapped AWS partitions stop being mistaken for commercial (CE 0.2.49 / Enterprise 0.42.0).**
21
55
  This one DOES change CE behaviour, and Enterprise now requires it (`>=0.2.49`). `detectPartition`
22
56
  tested only `cn-` and `us-gov-` before falling through to `'aws'`, so every ISO and European
@@ -158,11 +192,12 @@ How Marketplace fulfillment works (ZDE and air-gap preserved — no runtime AWS
158
192
  | AI analysis (OpenAI, Claude, Ollama — your keys) | ✅ basic | ✅ enriched | ✅ enriched |
159
193
  | Structured findings + SARIF + CSV export | ✅ | ✅ | ✅ |
160
194
  | CTEM watch mode | ✅ basic | ✅ advanced | ✅ advanced |
161
- | **Pro features (vulnerability assessment)** | | | |
195
+ | **Pro features** | | | |
162
196
  | CVE matching + MITRE ATT&CK mapping | — | ✅ | ✅ |
163
197
  | Risk scoring + prioritization | — | ✅ | ✅ |
164
198
  | Exploit intelligence — **CISA KEV** + **FIRST EPSS** joined onto the CVE matches, exploit-first ordering (a KEV-listed MEDIUM outranks an unexploited CRITICAL); stores are operator-populated — no feed data ships | — | ✅ | ✅ |
165
199
  | Parallel analysis agents | — | ✅ | ✅ |
200
+ | **Client reporting** — `report --format executive` renders a completed run as a self-contained, print-ready HTML report with optional cover-page branding (`--brand`); `--format jira` writes a Jira-importer CSV. ⚠️ The Jira import mapping is done in Jira and has **not been verified against a live Jira instance**. | — | ✅ | ✅ |
166
201
  | **Enterprise — cloud scanning** | | | |
167
202
  | 29 enterprise plugins — 28 cloud (AWS / Azure / GCP) + 1 network-scan zero-trust check | — | — | ✅ |
168
203
  | Zero Trust assessment | — | — | ✅ |
@@ -747,6 +782,7 @@ nsauditor-ai validate
747
782
  nsauditor-ai feed bundle --from <dir-of-NVD-feeds> --out <bundle.json.gz> [--kev <f>] [--epss <f>]
748
783
  nsauditor-ai feed import --file <feed-or-bundle> [--cache-dir <d>] [--extras-dir <d>] [--append] # the feeds you downloaded
749
784
  nsauditor-ai compliance <attest|suppress|review|renew|keygen|sign-pack|verify-pack> (Enterprise)
785
+ nsauditor-ai report --from <dir> --format executive|jira [--run <id>] [--brand <brand.json>] [--out <path>] [--allow-partial] (Pro)
750
786
  nsauditor-ai mcp
751
787
  nsauditor-ai --help (or -h, or `help`)
752
788
  nsauditor-ai --version (or -v, or `version`)
@@ -840,6 +876,37 @@ HEALTHCHECK --interval=60s --timeout=5s --start-period=10s --retries=3 \
840
876
  CMD nsauditor-ai validate --json | grep -q '"overall": "ok"' || exit 1
841
877
  ```
842
878
 
879
+ ### `report` command (Pro)
880
+
881
+ `nsauditor-ai report --from <dir> --format executive|jira` turns a completed scan run under `--from` into a client-facing deliverable — an HTML report a consultant sends to their customer, or a Jira-importer CSV.
882
+
883
+ **What it reads.** A scan record keeps findings in more than one place, and the report reads all of them: each plugin's `result.findings` (an array, or a dict of categories as the DNS auditor emits), zero-trust dimension findings, per-port TLS issues, and the **finding queue** (`scan_finding_queue.json`) that carries the CVE/KEV/EPSS-enriched entries. `result.data` is deliberately NOT read — on a network scan it holds probe telemetry, not findings. The container inventory is enforced by a census: a container holding findings that no reader opens fails the build rather than rendering as a clean report.
884
+
885
+ | Flag | Description | Default |
886
+ |---|---|---|
887
+ | `--from <dir>` | The scan `--out` directory holding the run's record and per-host evidence | *required* |
888
+ | `--format executive` | Self-contained, print-ready HTML report; no external network reference other than an `http(s)`/`mailto` `<a href>` | — |
889
+ | `--format jira` | Jira-importer CSV (`Summary`/`Description`/`Priority`/`Labels`/`External ID`); the import mapping is done in Jira and has not been verified against a live Jira instance. **`pass`-tier records are EXCLUDED** — a Jira issue is a work item and a passing check is not work; every other tier is kept, INFO included, because INFO carries the evidence gaps and scope boundaries. Passing checks appear in the `executive` report under their own **PASS** tier. | — |
890
+ | `--run <id>` | Report a specific run id instead of the newest one under `--from` | newest run |
891
+ | `--brand <brand.json>` | Cover-page branding (company name, prepared-by, contact, logo) — `--format executive` only | unbranded |
892
+ | `--out <path>` | Write to this path instead of `report_<runId>.<ext>` beside the run record | `report_<runId>.<ext>` |
893
+ | `--allow-partial` | Render even if some requested hosts were never written, or the run never recorded completion — the caveat is stated on the cover, never hidden | `false` |
894
+
895
+ A value-less `--from`/`--brand`/`--run`/`--out` (nothing after the flag, or a shell glob that swallowed the argument) is a fatal error, not a silent default.
896
+
897
+ **Exit contract** — `0` a report was rendered · `1` fix the RUN (no run record under `--from`, or an
898
+ incomplete run without `--allow-partial`) · `2` fix the REQUEST or its environment (an unknown or
899
+ missing flag value, an unwritable `--out`, a `--brand` file that is refused).
900
+
901
+ ⚠️ `--brand` with `--format jira` is **refused**, not ignored: a Jira CSV has nowhere to put branding,
902
+ and silently dropping a flag the caller passed is how a report goes out unbranded without anyone
903
+ noticing.
904
+
905
+ ```bash
906
+ nsauditor-ai report --from out/2026-08-26 --format executive --brand brand.json --out report.html
907
+ nsauditor-ai report --from out/2026-08-26 --format jira
908
+ ```
909
+
843
910
  ---
844
911
 
845
912
  ## Configuration
@@ -1124,7 +1191,7 @@ No license key? Everything in this repository works perfectly without one. The C
1124
1191
 
1125
1192
  ## Tests
1126
1193
 
1127
- Run all 1308 tests:
1194
+ Run all 1582 tests:
1128
1195
 
1129
1196
  ```bash
1130
1197
  npm test