Generate hash-chained, auditor-ready evidence for SOC 2, HIPAA, NIST CSF 2.0, PCI DSS, ISO 27001, CIS Controls v8, GDPR Article 32, and NIST SP 800-171 Rev 2 — across AWS, Azure, and GCP. Zero Data Exfiltration. Runs entirely inside your infrastructure.
NSAuditor AI Enterprise is the enterprise edition of the Nsauditor network security auditor — the same read-only scanning discipline, extended to AWS, Azure and GCP and mapped to eight compliance frameworks. New to the practice? Start with the network security audit checklist.
EE 2.0.0 (2026-10-15) — Node.js 24, the resolved-address pin, the drift file and its notification, an AI payload with no AWS account ID; paired with Community 1.0.0. Coverage: all eight coverage matrices unchanged since EE 1.3.0. Paired with CE 1.0.0 + agent-skill 1.0.0; floor CE ≥ 1.0.0. Release notes live in the package CHANGELOG.md.
Your compliance posture moves between audits — 2.0.0 shows you what moved. Node.js 24 is the supported runtime. Every one-shot compliance scan writes what changed since the previous scan beside its pack — controls to fail or to pass, controls that lost measurement, violations new or cleared, and what could not be measured, never read as cleared — and can notify a webhook, Slack or Teams when a control goes to fail or loses measurement, when a new violation reaches a severity you set, or when the drift could not be compared. A scan connects only to the addresses its host check resolved (Community 1.0.0), the AI payload carries no AWS account ID, and plugin 040’s weak-key and weak-signature findings fail the certificate control in six of the eight frameworks. What 2.0.0 brings ↓ · Where it stops ↓ · Upgrading: Node.js 24 and Community 1.0.0 ↓
Prior: EE 1.3.0 (2026-10-07) keyed a finding on its prose with every framework’s ids removed, so a pack that rewrote its text no longer reset its SLA age, and stopped a narrower scan from reading as a fix; EE 1.1.0 (2026-09-28) introduced the Pro delta / trend report — what is new, resolved or changed severity since the last scan, with the reason on every not-comparable row; EE 1.0.0 (2026-09-15) made the contract freeze binding — eight integration surfaces semver-governed, a stability promise rather than a certification. Release history: Full changelog →
SOC 2 auditors don't accept "we configured it that way once" — they need contemporaneous, attested evidence that your AWS, Azure, and GCP environments actually enforce the controls you claim. Most teams gather this manually: screenshots, CSV exports, IAM JSON pasted into a shared drive. It takes weeks, and the evidence is rejected the first time half the time.
scan_compliance_soc2.json + .html + .md, mapped directly to AICPA Trust Services Criteria controls. Hand it to your auditor.
shasum -a 256 -c. Proves the report bytes have not changed since the scan wrote them. (The chain itself is SHA-256 and nothing more. RFC 3161 trusted timestamping has been available since Enterprise 0.33.0 and is opt-in with no default, ever, because the request is an outbound call to the authority you name; Ed25519 evidence-pack signing ships as of Enterprise 0.38.0, and a verified signature covers one framework’s chain-of-custody envelope plus the artifacts that envelope enumerates — never the output directory, never the pack as a whole, and never a vendor attestation, because the key is operator-held.)
COMPLIANCE_GRC_PROVIDER=vanta (or drata / secureframe) + COMPLIANCE_GRC_TOKEN and the compliance phase maps each finding to your GRC platform’s evidence/test records and pushes them — opt-in, ZDE-redacted egress, token never serialized. The Vanta, Drata and Secureframe connectors carry audit-grade transport with rate-limit backoff, a circuit breaker, response-body capping, suppression-aware outcomes, deterministic framework-dimensioned idempotency, and a per-attempt audit log for chain-of-custody. All three are shipped, opt-in and early-access. Live validation against production Vanta/Drata/Secureframe tenants is in progress; the integration is single-workspace and operator-configured (not a multi-tenant sync); Secureframe’s API shape is published-assumed with live-tenant validation deferred to partner intake. Full setup & details in the GRC Connectors guide →
A complete sample scan against a fictional Acme Corp AWS account + home-office router. See the transitive SG chain reachability finding, the multi-region GuardDuty audit, the dnsmasq CVE detection, and the evidence pack. No signup required.
A control that fails on a Tuesday should not wait for the audit three months later to be found, and a violation that vanished because the scanner never looked is not a fix. Here is what ships in Enterprise 2.0.0 and Community 1.0.0 — each item scoped to the case it names, with where it stops printed right below it.
scan_drift_<fw>.json sits beside each compliance pack: the controls that went to fail or to pass, the controls that lost measurement, and the violations that are new or cleared. A violation is cleared only when this scan looked for it and it was gone; one whose scanner did not run or reported itself down, or whose port or region was not measured, is listed as could-not-measure with its reason. Enterprise, on the one-shot compliance scan.
Opt-in: --notify-webhook (public https only), --notify-format generic|slack|teams and --notify-severity send the drift when it crosses the trigger — a control gone to fail or that lost measurement, or a new violation at or above the severity you set. A drift that could not be compared with a previous run always notifies; the first scan, with no previous run, is the baseline and sends nothing. The payload is minimal by default; Teams is reached through a Workflows webhook. CLI only — not --watch, not the MCP server. Enterprise, on the one-shot compliance scan.
Community 1.0.0. The host check resolves the target and checks every answer; the scan’s connections to the target then go only to those answers, and a redirect hop to another host only to the answers its own check approved — on the CLI and through the MCP server. The pin covers the names those checks looked at, not every connection the scanner makes. Its two limits are stated below.
Community 1.0.0. An account ID in an ARN or an AWS URL becomes [ACCOUNT_ID] everywhere it occurs, and any other 12-digit number standing on its own [REDACTED_ID]. The system prompt is written beside the payload before the request, so the two files are what left the machine.
Plugin 040’s weak-key and weak-signature findings now fail the certificate control in SOC 2, HIPAA, NIST CSF 2.0, PCI DSS v4.0.1, ISO/IEC 27001:2022 and CIS v8. GDPR Article 32 and NIST SP 800-171 stay held for review. Enterprise, compliance mapping.
Community 1.0.0. On TCP, a row from a port’s authoritative probe that did not identify its service is evidence with a reason, not a service row, so the CSV, SARIF, the Markdown report and the AI payload no longer list it.
Where it stops — stated, not hidden: a notification retried after a timeout or a server error can arrive twice, and a hanging endpoint can cost about 32 seconds per framework. A scan that found its ports with the Nmap plugin (024) alone has no port oracle, so a violation on a port that scan did not measure can be listed as cleared; include the port scanner (003) in the scans you compare. On a host where another port completed a TLS handshake, a port whose TLS probe failed in transport is not read, so an earlier TLS finding there can be listed as cleared; and a previous pack that recorded neither a scanned host nor a single scope target (a pack records its host since Enterprise 1.1.0) cannot be re-keyed, so its agent findings are listed as cleared and new once. The pin does not hold through an HTTP proxy set with NODE_USE_ENV_PROXY, which resolves the name itself, or over an idle connection opened earlier to the same name, for as long as the target keeps it open. UDP non-answers stay in the service list: a UDP silence is open-or-filtered, and the delta reads those rows. A probe with no adapter of its own can still list a port it did not identify, with a status other than open: on a router scan, the SUN RPC plugin listed port 111, which the port scanner had measured closed.
Upgrade: Enterprise 2.0.0 runs on Node.js 24 and installs with Community 1.0.0 — npm i -g nsauditor-ai@1.0.0 @nsasoft/nsauditor-ai-ee@2.0.0 (what to know first ↓).
Enterprise from $2,000/yr — eight compliance frameworks from one read-only scan, drift alerts to your webhook, Slack or Teams — see tiers ↓
Any tool can diff two scans. The hard part is refusing to call something fixed when all the scanner knows is that it stopped looking. nsauditor-ai report --from <dir> --format executive --since <runId|prior> — <dir> is the directory you gave the scan as --out — compares two scan runs and renders what is new, what is resolved and what changed severity into the self-contained HTML report you already send. When the report can see that a finding was not measured the same way twice, it files it under NOT-COMPARABLE, with the reason on the row, instead of calling it fixed — including an analysis agent whose input plugin was left out of the scan or did not complete, a TCP port that answered without its service being identified (for a CVE or end-of-life row), a UDP service that stopped answering, a CVE lookup that failed, an analysis agent that did not run, an Enterprise package that failed to load, and vulnerability data that changed while your software did not. Every new, resolved and changed row carries a Basis cell that says what was checked for that row. We state the two places NSAuditor still cannot be sure, rather than leave you to find them: a comparison with an older scan that cannot say which plugins it left out (only scans made since Enterprise 1.3.0 can), and a scan that found its ports with the Nmap plugin alone (both below ↓). That is what makes the delta something a consultant can put in front of a client, and, for a compliance team, movement between two points in time you can show an assessor, across AWS, Azure and GCP.
When the report can see that a finding was not measured the same way twice, it files it under NOT-COMPARABLE, with the reason on the row, instead of calling it resolved — among the reasons: a host that was not scanned; a finding that carries no producer identity; a plugin that did not run, errored or timed out; an analysis agent that did not run, or whose input plugin was left out of the scan or did not complete; an Enterprise package that failed to load; an evidence gap, including a CVE lookup that failed; a narrower scope; a port whose check could not complete; a TCP port the port scanner saw open that stopped answering between the two scans, or that answered without its service being identified (for a CVE or end-of-life row); a UDP port the other scan did not record as closed or answering; a producer whose identity basis changed across an upgrade; and a CVE the vulnerability data stopped attributing while the same program and version still answer. A finding that could not be compared is not a finding that was fixed. Two measured limits remain: only a scan made since Enterprise 1.3.0 records a plugin left out of it, so in a comparison with an older scan, an agent’s row that scan lacks is not refused — the report’s Basis cell says so on the row; and a scan that discovered ports with the Nmap plugin (024) alone records no port oracle, so an analysis agent’s or the CVE mapper’s row on a port it did not measure can read RESOLVED and count as closed in MTTR, and the control it failed can read PASS — include the port scanner (003) in scans you compare.
Two runs at different licence tiers are refused outright, and so are two runs straddling a release where a reported number changed meaning. Beside every comparison the report states that framework-enumeration movement is NOT EVALUATED in this release — stated, never implied to be ruled out — and what it could establish about the baseline’s integrity. Where either run holds analysis-agent findings, it adds how their scope is derived — the run’s licence tier, plus the records a run writes when Enterprise failed on a host, an agent did not run, or a plugin it reads was left out of the scan or did not complete — and that only a run made since Enterprise 1.3.0 records a plugin left out of it, so in a comparison with an older run, an agent’s row that run lacks is not refused; the row’s Basis cell says so.
The run record and each host’s findings files are sealed with SHA-256 digests and chained to the previous run. Both runs are verified; an altered findings file is named and the comparison is refused. Only scans run since Enterprise 1.1.0 are sealed: a baseline scanned before the upgrade is still compared, and the report says it carries no integrity digest, so alteration of that baseline could not be ruled out. Tamper-evident against accidental corruption, partial restores and unsophisticated edits — not tamper-proof against an attacker with host-level access, and not non-repudiation: nothing in the chain is signed, and nothing names an author.
The delta renders into the client-facing HTML report you already send, with the reason printed on every not-comparable row. It runs where your scans run: read-only credentials, and no scan data leaves your machine for Nsasoft.
Who gets it: licence-gated to Pro and Enterprise; the code ships in the Community package because Community holds the CLI. The last-vs-current webhook alert in watch mode stays free, and since Community 0.2.57 it fires: it alerts each host whose scan changed and that carries a finding at or above --alert-severity — not on the first cycle, nor for a host whose scan failed.
Baseline older than 1.1.0? Since Enterprise 1.1.0, fourteen producers identify a finding differently, so the first delta report against a baseline scanned before that release shows a large NOT-COMPARABLE list (which ones ↓) — that is the declaration working, not a broken report.
Two measured limits of the delta report — printed here, not buried: only a scan made since Enterprise 1.3.0 records a plugin left out of it, so in a comparison with an older scan, an agent’s row that scan lacks is not refused — the report’s Basis cell says so on the row, so rescan after upgrading before you compare; and a scan that discovered ports with the Nmap plugin (024) alone records no port oracle, so an analysis agent’s or the CVE mapper’s row on a port it did not measure can read RESOLVED and count as closed in MTTR, and the control it failed can read PASS — include the port scanner (003) in scans you compare or track. (That second case was already true in Enterprise 1.2.0, whose release notes did not state it.)
Prior: Enterprise 1.3.0 (2026-10-07) closed one and narrowed the other of the two limits Enterprise 1.2.0 printed here. The first is closed: with SLA tracking on, the controls behind a failed CVE lookup are now held FAILED with a [COVERAGE GAP] LOOKUP NOT MEASURED record (the hold does not name which lookup failed), and the CVE mapper’s record of a lookup that itself failed fails, as an evidence gap, the controls its CVE rows map to (14 controls in seven frameworks). The second is narrowed: an analysis agent now records a plugin left out of the scan as an input gap, so between two scans made with 1.3.0 or later its earlier rows are refused in the delta and withheld in MTTR rather than read as fixed. What remains of it is the first limit above.
See the delta report on the Pro page → · See the sample scan →
Pro from $39/mo billed annually ($49 month to month) · Enterprise from $2,000/yr — see tiers ↓
Security isn't enough — you have to prove it. Every audit asks for evidence that your cloud actually enforces the controls you claim. NSAuditor generates eight hash-chained evidence packs from one read-only scan.
The same proof is demanded by your SOC 2, HIPAA, and PCI DSS QSA auditors, your ISO/IEC 17021-1 certification-body assessors, and your CIS Controls v8 self-attestation (CSAT / CIS-CAT Pro) — plus the IG1 baseline your cyber-insurance underwriter wants.
One scan. Eight evidence packs. Hash-chained and auditor-ready. Replace weeks of manual screenshots and spreadsheet evidence with a single read-only command your assessors can verify.
Runs inside your infrastructure with Zero Data Exfiltration: no scan data or evidence artifact is sent to Nsasoft, your cloud credentials go only to your own cloud providers, and the one default path that carries scan content (the CVE lookup to NIST’s NVD) can be switched off for offline operation. Air-gapped operation and offline licensing. No BAA with Nsasoft required.
Deep cloud auditing across 28 cloud auditors: cross-account exposure, backup and snapshot exposure, transitive security-group reachability paths, IAM shadow-admin chains, and exploit-first, risk-scored findings — not just a checklist.
NSAuditor AI Enterprise turns one read-only cloud scan into eight hash-chained, auditor-ready evidence packs — without sending your cloud configuration outside your infrastructure.
SOC 2, HIPAA, NIST CSF 2.0, PCI DSS, ISO 27001, CIS v8, GDPR Article 32, and NIST SP 800-171 Rev 2 evidence generated in parallel from a single run.
Your cloud data, credentials and findings are not sent to us — by architecture, not policy.
Scanners are restricted to read-only cloud APIs — enforced in code, not policy: a build-breaking test in our mandatory pre-publish suite fails if any plugin imports a mutating SDK call. NSAuditor never modifies your resources — safe for production.
Every artifact carries a SHA-256 chain-of-custody sidecar your auditor can verify offline — integrity proof, not screenshots.
Audit AWS, Azure, and GCP from one tool, with per-account and per-region scoping built in.
Offline JWT licensing and air-gapped operation for PCI CDE-isolation and ISO 27001 scope-controlled environments, plus the evidence layer that feeds a DFARS / CMMC programme.
Unlike SaaS scanners that pull your cloud inventory into their platform, NSAuditor runs entirely inside your environment. License validation is offline. Nothing about your cloud is transmitted to us — this is Zero Data Exfiltration by architecture, not policy. The product’s egress register enumerates 21 outbound paths, each with what turns it on and whether it is on by default. Of the paths on by default, the one that carries scan content is the CVE lookup: it sends each identified service’s vendor, product and version to NIST’s NVD unless you set NSAUDITOR_OFFLINE_ONLY=1 with a local NVD store. The rest reach your own cloud accounts, DNS, your local network segment, the hosts you scan and, when a scanned web server redirects, the address it redirects to.
Your infrastructure. Your evidence. Your control.
Under nine minutes, regenerated as of EE 1.0.0 — it opens on the Friday before the audit, shows the same week after one read-only scan, walks six problems before and after, says what 1.0 means to a buyer, and ends on why an auditor can check every integrity claim with standard openssl without trusting the vendor or the customer. Here is what you will see:
No screenshots. No mockups. A complete report generated by NSAuditor AI Enterprise — synthetic data, real engine output. Walk through the transitive security-group reachability finding, the multi-region GuardDuty audit, the dnsmasq CVE detection, and the evidence pack. No signup required.
AWS security groups + IAM, GCP firewall rules + IAM bindings, Azure NSGs + RBAC. Uses your own credentials — nothing touches Nsasoft.
Map findings to NIST CSF, CIS Controls, HIPAA Security Rule, GDPR Art. 32, and PCI DSS. Gap reports with evidence references.
Opt-in scan-time push to Vanta, Drata, and Secureframe — findings mapped to the platform's evidence/test records, with retry/backoff, framework-dimensioned idempotency, and ZDE-redacted egress. Early-access, single-workspace.
Evaluate segmentation boundaries, encryption-in-transit, identity posture, and lateral movement risk. Composite readiness score.
Delivery vehicle, not a security boundary: a linux/amd64 container image or an npm host install. Offline license verification (ES256 against an embedded public key, no phone-home, no heartbeat, tcpdump-verifiable) and offline CVE matching under NSAUDITOR_OFFLINE_ONLY=1. Runs a full scan-to-evidence-pack workflow in an isolated network once configured for it — a default scan attempts NVD egress unless that flag is set. Air-gapped delivery ships since Enterprise 0.37.0: a dependency-complete bundle carrying both editions, its own install script and SHA-256 checksums, restricted distribution — verified on native aarch64 as well as amd64, so an arm64 enclave is covered. The bundle is integrity-checked, not authenticated. Deliberately not claimed: no arm64 container image, and no recurring feed-data delivery service.
Read-only-credential enforcement — cloud plugins are gated by a build-breaking test to use only read-only SDK verbs — plus egress redaction on two outbound paths — on by default for AI prompts (OPENAI_REDACT=false turns it off, and hostnames and email addresses are not masked), and off by default for GRC pushes until you set COMPLIANCE_GRC_REDACTION. Nothing goes to Nsasoft — zero data exfiltration by architecture, not by policy.
Unlimited scan-history retention (the Community 7-day prune is lifted; history persists as JSONL for cross-scan comparison), delta detection, and severity-thresholded webhook alerting — since Community 0.2.57 the webhook alerts each host whose scan changed and that carries a finding at or above --alert-severity — not on the first cycle, nor for a host whose scan failed, which is reported as not compared rather than as no change; --alert-every-cycle alerts every such host on every cycle, the first included.
The foundational S3 bucket-security auditor. The effective-public-exposure model: missing or partial PublicAccessBlock now escalates to MEDIUM (a guardrail gap, not current exposure), and top severity is reserved for confirmed-public via bucket policy OR a new GetBucketAcl check that completes the ACL × policy × PAB join. A public AllUsers / AuthenticatedUsers grant is top-severity unless the PAB IgnorePublicAcls neutralizes it (then LOW). Closes a public-via-ACL false-negative class while fixing the false-positive class — live-revalidated against a real prod account (12 top-severity findings → 11 verified not-public + 1 genuinely-public policy). Maps to CC6.6 + C1.1.
Third leg of the cloud-storage audit triad, completing the multi-cloud picture alongside plugin 1020 (AWS S3) and plugin 1022 (Azure Storage). Audits across 6 SOC 2 substrate-evidence dimensions: Bucket-level IAM public bindings (CC6.6 — allUsers = CRITICAL zero-trust bypass; allAuthenticatedUsers = HIGH Google-account-trust bypass; co-existence surfaces both findings with merged evidence), Uniform Bucket-Level Access (CC6.6 + C1.1 — enforces IAM as single source of truth, no legacy ACL surface; disabled = MEDIUM), Object Versioning (C1.1 + A1.2 — accidental object deletion reversibility; disabled = MEDIUM), Retention Policy / Bucket Lock (C1.1 + C1.2 — three-tier: missing = MEDIUM, unlocked = MEDIUM, locked = PASS; SEC 17a-4 / FINRA 4511 WORM alignment), CMEK via Cloud KMS (CC6.1 — four-tier key-custody ladder matching plugin 1140 RDS pattern; full-format 6-segment Cloud KMS resource-path regex gates PASS tier; malformed reference = LOW + evidenceGap per conservative_classifier_principle), and Bucket-level access logging (CC7.1 — missing = MEDIUM; separate destination bucket = PASS; self-logging = INFO + walkthroughRequired). _callGcsWithInstrumentation wraps GCS API calls with AccessDenied counter + throttle-retry + wall-budget (Thread H equivalent). ZDE — only GCS-public-namespace identifiers (bucket names, KMS paths) propagate to findings; operator labels never read. 20 new soc2.json titlePattern entries (5 CC6.6 + 3 CC6.1 + 2 CC7.1 + 5 C1.1 + 3 C1.2 + 2 A1.2). 101 new tests across 17 suites. Maps to CC6.1 + CC6.6 + CC7.1 + C1.1 + C1.2 + A1.2.
GCP counterpart to plugin 1030 AWS IAM Deep Auditor at the project boundary — audits the full GCP project IAM policy surface across 7 SOC 2 substrate-evidence dimensions (v2 scope). v1 dims (3): Project IAM public-member bindings (CC6.1 — allUsers CRITICAL / allAuthenticatedUsers HIGH); Sensitive-role inventory of 12 predefined roles (CC6.1 + CC6.6 MEDIUM); IAM Conditions classifier (CC6.1 — restrictive CEL = PASS; absent = MEDIUM; vacuous = LOW + evidenceGap). v2 dims (4): Custom-role permission audit (CC6.1 — wildcard * sentinel = CRITICAL; 16-entry admin-equiv allowlist intersection = HIGH); Service-account key custody (CC6.1 + C1.1 — user-managed long-lived keys = HIGH; per-SA keysFetchError propagation for audit-principal partial-permission scenarios); Service-account impersonation graph BFS (CC6.1 — 4-hop cycle-safe traversal of 3 canonical impersonation roles; 2-hop = HIGH, 3+ hop = CRITICAL; project-scope fan-out bindings classified as CRITICAL _CAT_SA_IMPERSONATION_PROJECT_SCOPE — a real GCP privesc class missed by per-SA-only inventory); Org Policy constraint enumeration (CC6.6 + C1.1 — 4 sensitive constraints incl. iam.disableServiceAccountKeyCreation; explicit reset detection). NEW utils/gcp_auth.mjs shared helper for GOOGLE_IMPERSONATE_SERVICE_ACCOUNT credential chain (keyFile / ADC / ADC+impersonation). 33 soc2.json titlePattern entries total (11 v1 + 22 v2 across CC6.1 + CC6.6 + C1.1). +180 new tests this cycle (5715/5715). Maps to CC6.1 + CC6.6 + C1.1.
Transitive shadow-admin path detection — including PassRole privesc and group-inherited cross-principal chains. Every finding carries a verifiable [via policy: ARN] evidence trail with partialProvenance / provenanceComplete completeness signals for SOC 2 Type-II auditors.
Audits CloudTrail trail health (multi-region default-ON across 36 canonical AWS regions, log-file validation, KMS-CMK, IsLogging), CloudWatch alarm coverage against CIS AWS Foundations Benchmark v1.5 §3.1–3.14 via the v2 metric-filter audit, AWS Config recorder + Organizations ConfigurationAggregator detection with deterministic STS account-coverage cross-reference, and cross-account S3 trail-destination WORM verification (Object Lock + Versioning + MFADelete per trail bucket) for SEC 17a-4 / FINRA 4511 retention evidence. Closes SOC 2 CC7.2 + CC7.3.
First entry-point evidence plugin for AWS Serverless-Framework deployments. Audits REST APIs (v1) + HTTP APIs (v2): per-method/route authorization classifier (NONE = CRITICAL, AWS_IAM / Cognito / JWT = PASS, JWT-with-wildcard-audience = INFO with IdP issuer/audience evidence, Lambda authorizer = INFO with manual-verification prompt), TLS policy with worst-policy tracking across mixed-config v2 domains (TLS_1_0 = HIGH), stage-level access logging, throttling (A1.2), and WAF association. SOC 2 mapping: CC6.1 + CC6.6 + CC6.7 + CC7.1 + A1.2.
The "audit-the-auditor" plugin — answers the question every Type-II auditor asks after the entry-point one: can the audit record itself be tampered with? Per-table PITR + deletion protection (worst-case CRITICAL "audit record itself not survivable" when both missing). KMS-CMK classifier with conservative LOW-unverifiable posture on :key/UUID ARN shapes (a deterministic PASS/MEDIUM when plugin 1070 is in the same scan). Resource-policy presence audit via the 2024 GetResourcePolicy API with soft-degrade. CloudTrail DynamoDB data-event coverage cross-reference (orthogonal composition with plugin 1040). Matrix shift: PI1.5 (Stored items) moves out-of-scope → partial. Mapping: CC6.6 + CC7.1 + C1.1 + PI1.5.
Validates cryptographic boundary integrity and key governance. Per-key rotation status (customer-managed CMKs flagged MEDIUM when rotation disabled; AWS-managed keys correctly identified as not-applicable). Wildcard-principal classifier across 5 severity tiers: CRITICAL unconditional kms:* takeover; HIGH for sensitive actions; INFO read-only-only; PASS no-wildcard. Coverage spans Principal.AWS / Federated / Service / CanonicalUser shapes + case-insensitive AWS/action matching + NotPrincipal-Allow + NotAction-Allow + glob-action coverage. Exports _describeKeyManager() helper consumed by plugin 1060. Maps to CC6.3 + C1.1. 77 new tests.
Runtime EOL detection (institutional-CRITICAL when Lambda returns EOL runtime like nodejs16.x / python3.7; case-normalized at the SDK boundary), public function-URL exposure, resource-policy permissive principals, environment-variable secret-suggestive name detection (ZDE-safe: secret VALUES never inspected — only names + presence), VPC configuration, KMS-CMK vs AWS-managed key custody, dead-letter queue + reserved concurrency posture. Maps to CC6.1 / CC6.6 / CC7.1 / C1.1.
Secrets Manager ListSecrets + DescribeSecret (rotation enabled/disabled, last-rotated cadence, KMS-CMK vs AWS-managed key custody, tag-driven prod-tier classification). SSM Parameter Store DescribeParameters (String vs SecureString classification with secret-suggestive name detection, KmsKeyId presence on SecureStrings). ZDE-critical: scanner NEVER calls GetSecretValue / GetParameter — only Describe* / List* metadata APIs; verb-prefix denylist regex enforces this at SDK boundary. Maps to CC6.1 / CC6.6 / C1.1.
Pipeline source-stage encryption (KMS-CMK presence), CodeBuild privilegedMode detection (HIGH for non-Docker-image builds), buildspec inlined-vs-S3 (configuration drift surface), secrets passed via environment variables vs Secrets Manager reference, IAM role least-privilege via wildcard-Action detection, S3 artifact-store encryption. Runtime-state audit: stale-execution detection — pipeline's latest execution older than configured cadence isn't actively defending the build path. Maps to CC6.1 / CC7.1 / CC8.1 / C1.1.
Cross-plugin reconciler: walks IAM policies for kms:Decrypt / kms:ReEncrypt* / kms:GenerateDataKey grants then cross-references against destination KMS key policies (plugin 1070) to compute the effective decrypt path. Closes the institutional NotAction-implicit-decrypt false-PASS class (Allow + NotAction:[...] + Resource:* over-grants decrypt implicitly). A cross-plugin sister-fix in plugin 1030 case-normalizes Effect+Action discriminators. Maps to CC6.1 / CC6.6 / C1.1 / C1.2.
S3 lifecycle policy enumeration (CC7.1 retention-cadence evidence) + cross-region replication topology (A1.2 disaster-recovery substrate). Destination-bucket reachability verification adds a cross-region check (closes silent-PASS class where replication source FAILED but emitted clean — destination IAM denial or missing bucket now surfaces explicitly). Maps to C1.1 / C1.2 / A1.2.
The largest single-plugin institutional-hardening arc in the EE codebase: ~7800 lines across 18 sessions / 25 commits / 545 plugin tests, with 19 R2-strict recurrence-class same-session closures catalogued in 4 institutional-memory artifacts. Audits the AWS Backup substrate end-to-end: Plans + Vaults + Recovery Points + Selections + Frameworks + Restore Testing + ReportPlans + Legal Holds + VaultType + Vault Tags + Vault Access Policy. Headline capability: 12-dimension air-gapped vault attestation arc for LogicallyAirGappedBackupVault resources — 6 cryptographic-isolation mechanisms (vault TYPE air-gapped + ARN account-segment-separation + destination KMS key-policy clean + destination KMS Grants clean + MRK-replica topology clean + source-account VPC-endpoint policy clean) PLUS 6 substrate dimensions (PITR / retention / encryption / RestoreTesting / Legal Holds / vault Access Policy). Cross-service SDK integration (KMS / EC2 / Config / Backup). 74 new soc2.json titlePatterns across CC6.3 + CC6.6 + CC7.1 + CC8.1 + C1.1 + C1.2 + A1.2. Substantially closes the previously-documented A1.2 "Backup/recovery posture itself" ransomware-defense gap (SEC Rule 17a-4 / FINRA 4511).
The single most-asked-about audit substrate after S3, with 7 SOC 2 substrate-evidence dimensions. Multi-AZ deployment (A1.2 availability), storage encryption at rest with KMS-key custody classification (C1.1 confidentiality — four-tier severity ladder), parameter-group SSL enforcement (C1.1 transit encryption — detects both postgres rds.force_ssl and mysql require_secure_transport), backup retention period (A1.2 cadence — operator-tunable 1–35 days; default ≥7 institutional baseline), public accessibility (CC6.6 perimeter — cross-plugin sister to plugin 1170), IAM database authentication (CC6.1 password-less auth on mysql/postgres/mariadb/aurora-variants), and snapshot encryption via DescribeDBSnapshots with explicit IncludeShared=false + IncludePublic=false (C1.1 cross-cycle). Headline v2 capability: kms:DescribeKey cross-reference promotes UNVERIFIABLE :key/UUID ARN shapes to deterministic PASS (KeyManager=CUSTOMER) or MEDIUM (KeyManager=AWS) — closes the v1 fixture-design gap without compromising the conservative_classifier_principle (AccessDenied / NotFound / unknown KeyManager still leaves at LOW). 18 new soc2.json titlePattern entries across A1.2 + C1.1 + CC6.1 + CC6.6. 103 tests total (51 v1 + 52 v2). Maps to A1.2 + C1.1 + CC6.1 + CC6.6.
First multi-service plugin in the EE codebase — SQS + SNS bundled because they share the same auth surface, region scoping, and SOC 2 control coverage. Audits queues + topics across 5 SOC 2 substrate-evidence dimensions: SQS encryption at rest (C1.1 — four-tier severity ladder matching plugin 1140's structure with conservative LOW+evidenceGap on :key/UUID ARN form), SQS transit-encryption policy (CC6.6 — analyzes Policy for aws:SecureTransport=false Deny defense-in-depth), SNS topic encryption at rest (C1.1 — SNS has no managed-SSE equivalent so absent = HIGH), SNS topic-policy permissive-Principal classifier (CC6.6 — full institutional posture with NotAction-Allow + NotPrincipal-Allow + Resource-scope filtering; severity CRITICAL unconditional-wildcard → HIGH conditional-wildcard → PASS no-wildcard), and SQS dead-letter queue presence (A1.2 availability + CC7.1 anomaly-detection, dual-mapped — missing DLQ is the canonical silent-message-loss class for event-driven architectures). 11 new soc2.json titlePattern entries. 95 new tests. First EE plugin to ship without a smoke-time SDK hotfix — institutionalized pre-implementation checklist now adds optionalDependencies entries preemptively. Maps to C1.1 + CC6.6 + A1.2 + CC7.1.
Audits VPC endpoint coverage for AWS-service traffic kept off the public internet. Enumerates interface endpoints (com.amazonaws.region.svc) and gateway endpoints (S3 + DynamoDB) across the audited regions. Endpoint-policy permissive-Principal classifier (wildcard "*" / {"AWS":"*"} / NotPrincipal-Allow shapes), private-DNS posture for interface endpoints (private resolution prevents accidental public-DNS fallback), and route-table attachment verification for gateway endpoints. Closes the silent class where data-plane traffic to AWS services is routed via the public internet despite a hardened SG perimeter. Maps to CC6.6.
Orthogonal evidence to plugin 1023 zero-trust-checker: 1023 reads OBSERVED open ports from prior network probes; 1170 reads DECLARED SG policy via DescribeSecurityGroups. The pair gives Type-II auditors complete coverage of "is this port reachable, and is it supposed to be?" RESTRICTED_PORTS spans 23 ports per CIS AWS Foundations Benchmark v3.0 — including Redshift (5439), Kubernetes API server (6443), etcd (2379-2380), Kibana (5601), InfluxDB (8086), Kafka (9092), Consul (8500), ZooKeeper (2181), HashiCorp Vault (8200). New opts.additionalRestrictedPorts operator-config (integer-validated 0-65535 + deduped) lets tenants extend the list with custom ports. Per-SG cardinality cap (_USER_GROUP_DISPLAY_CAP=10) with rollup trailer defends against finding-size DoS on 1000+ SG accounts. System-managed-SG name-prefix exclusion list (ElasticMapReduce-, eks-cluster-sg-, AWSServiceRole, awseb-) excludes AWS-service-controlled non-deletable SGs from orphan-detection. 6 audit dimensions: IPv4 0.0.0.0/0 ingress to RESTRICTED_PORTS (CC6.6, CRITICAL), IPv6 ::/0 sibling (CC6.6, CRITICAL), all-protocol (-1) ingress (CC6.6, CRITICAL with SG-scope suppression), public ingress to non-restricted ports (INFO + walkthroughRequired), egress 0.0.0.0/0 (INFO substrate), orphan SGs (CC6.2 governance). 10 new soc2.json titlePattern entries total (v1+v2). 110 tests total (54 v1 + 56 v2). Maps to CC6.2 + CC6.6.
First plugin in the 1170-1180 ID range. Closes the canonical cache-tier SOC 2 evidence gap — sister plugin to 1140 RDS for the database tier. Audits Redis clusters across 6 SOC 2 substrate-evidence dimensions: transit encryption (C1.1 — TransitEncryptionEnabled wraps RESP in TLS for client → cluster + primary → replica; cannot be toggled in place), at-rest encryption with KMS key custody (C1.1 four-tier ladder: HIGH unencrypted → MEDIUM AWS-owned-default → MEDIUM alias/aws/elasticache → PASS customer-managed CMK + LOW+evidenceGap on :key/UUID ARN form per conservative_classifier_principle), Redis AUTH / IAM-auth user groups (CC6.1 + CC6.2 — UserGroupIds for Redis 7+ ACL replace long-lived AUTH passwords; cross-plugin sister with plugin 1170 SG-perimeter audit), Multi-AZ deployment (A1.2 availability), SnapshotRetentionLimit cadence (A1.2 — ≥7 days default, operator-tunable 1-35), and subnet placement (CC6.6 perimeter — INFO+walkthroughRequired on default subnet group per conservative-classifier discipline). Dual-API enumeration with inter-API dedup: DescribeReplicationGroups + DescribeCacheClusters covers both replication-group + standalone surfaces; CacheClusters with ReplicationGroupId set are skipped. _ELASTICACHE_SUPPORTED_ENGINES = Object.freeze(new Set(["redis"])) — Memcached out-of-scope by design (no native AUTH; no transit encryption substrate). 16 new soc2.json titlePattern entries (4 CC6.1 + 1 CC6.6 + 5 A1.2 + 8 C1.1). 41 new tests. Third EE plugin to ship without a smoke-time SDK hotfix — preemptive @aws-sdk/client-elasticache (1150 + 1170 + 1180 all shipped without hotfix; now institutional discipline). Maps to C1.1 + CC6.1 + CC6.2 + CC6.6 + A1.2.
First plugin in the 1190-1199 ID range. Closes the canonical email-integrity SOC 2 evidence gap — AWS SES is the dominant transactional + marketing + bulk-email substrate for B2B SaaS workloads. Sister plugin to 1180 ElastiCache Redis (cache tier) + 1140 RDS (database tier) + 1170 SG Perimeter (network tier). Audits SES across 6 SOC 2 substrate-evidence dimensions: DKIM enablement + signing status (CC6.1 / Privacy — HIGH on SigningEnabled=false breaks SPF/DKIM/DMARC trust-chain; 5-enum classifier with PENDING/TEMPORARY_FAILURE/NOT_STARTED → INFO+walkthroughRequired, FAILED → MEDIUM DNS drift, unknown → LOW+evidenceGap per conservative_classifier_principle), custom MailFrom domain alignment (Privacy substrate — INFO+walkthroughRequired on default amazonses.com because DMARC strict alignment impossible without custom MailFrom; PASS on custom + Status=SUCCESS), configuration set TLS enforcement (C1.1 — REQUIRE=PASS (messages REJECTED if no STARTTLS), OPTIONAL=HIGH (silent SMTP-downgrade-attack window — network-layer adversary strips STARTTLS from EHLO, forcing cleartext delivery of message body + headers)), identity sending authorization policy permissive principals (CC6.6 — multi-class wildcard detector covers "*" + {AWS:"*"} + {Service:"*"} + {Federated:"*"} + {CanonicalUser:"*"} + array forms; distinct HIGH category ses-sending-auth-notprincipal-allow catches NotPrincipal+Effect=Allow wildcard-EQUIVALENT class per R-CRITICAL-1 fold; LOW+evidenceGap on malformed statements missing Effect field per R-HIGH-2 fold), dedicated IP pool sending posture (CC7.1 substrate, account-level), and suppression list state (CC7.1 deliverability substrate — INFO on count + reason distribution only). ZDE-CRITICAL invariant: NEVER reads suppressed-destination email addresses — count + reason only; verified at run() envelope boundary via sentinel-string assertion per R-LOW-8 fold. 8 new soc2.json titlePattern entries (3 CC6.1 + 3 CC6.6 + 2 C1.1). 116 tests across 29 suites. 11 same-session reviewer folds — ties the single-cycle record. Fourth EE plugin to ship without a smoke-time SDK hotfix (preemptive @aws-sdk/client-ses + @aws-sdk/client-sesv2 in optionalDependencies — plugins 1150, 1170, 1180, 1190 all shipped without hotfix). Maps to CC6.1 + CC6.6 + C1.1.
First EE plugin to audit AWS managed-threat-detection substrates. Produces the foundation-layer evidence SOC 2 auditors expect under CC7.1 (detection procedures) and CC7.2 (monitoring of system components for anomalies). A SOC 2 evidence pack without GuardDuty signal has no AWS-native anomaly-detection stream — credential-exfiltration attempts, cryptocurrency-mining indicators, malicious-IP communication, and reconnaissance patterns all go unobserved. A pack without Inspector2 signal has no managed CVE-detection coverage on the compute surface (EC2 AMIs, ECR images, Lambda functions). Plugin 1200 audits enablement state across 4 SOC 2 substrate-evidence dimensions: GuardDuty Detector enablement (CC7.1 — flags any audited region with no GuardDuty Detector configured; HIGH on absence), GuardDuty protection-feature coverage (CC7.1 — checks each Detector against the institutional baseline of S3 data events / EKS audit logs / EBS malware protection / RDS login events / Lambda network logs / runtime monitoring; MEDIUM on each missing baseline feature with explicit name in the finding details), Inspector2 enablement (CC7.2 — flags accounts where Inspector2 is not enabled, suspended, or disabled; HIGH on absence), and Inspector2 scan-target coverage (CC7.2 — confirms the institutional baseline resource types EC2 / ECR / Lambda are all enabled for scanning; HIGH on zero coverage, MEDIUM on partial with the disabled list in finding details). For each dimension, plugin 1200 distinguishes auditor-side IAM gaps (the auditor role lacks the GuardDuty or Inspector2 read permission) from genuine service-side absence, so remediation paths are unambiguous. Conservative classification — ambiguous AWS-SDK responses emit LOW+evidenceGap with a walkthrough prompt, never silent-PASS. Case-insensitive enum handling at the SDK boundary defends against case variation across SDK versions. Zero data exfiltration — findings carry only AWS-public-namespace identifiers (Detector IDs, region, status enums); operator-supplied tags / descriptions are never read. Soft-degrade — GuardDuty and Inspector2 SDKs load independently; failure of one does not block the other. 7 new soc2.json titlePattern entries (4 CC7.1 + 3 CC7.2). Maps to CC7.1 + CC7.2.
Multi-region EC2 + EBS instance-level coverage via DescribeRegions (single-region fallback emits an evidence-gap, never silent-PASS). IMDSv1 detection + IMDSv2 hop-limit > 1 with profile-aware severity (CC6.1), EBS volume unencrypted + account default-EBS-encryption disabled (C1.1 + CIS 3.11), public-IP exposure including IPv6 GUA + secondary-ENI / EIP (CC6.6), instance-store evidence-gap, and AMI inventory → cisImageInventory producer — the enablement substrate for CIS-Hardened-Image substrate-evidence credit across the CIS v8 mapping (Safeguards 4.1 / 4.2 / 4.6). Survived 3 review rounds across 5 adversarial skill lenses. Maps to CC6.1 + CC6.6 + C1.1.
First dedicated Azure auditor beyond the multi-purpose plugin 1022. Owns the Azure Storage Account encryption-at-rest + encryption-in-transit + authorization-mode surface across 7 dimensions: HTTPS-only transit (enableHttpsTrafficOnly), minimum TLS version, Shared Key authorization (allowSharedKeyAccess), infrastructure double encryption (requireInfrastructureEncryption), customer-managed-key reachability + rotation (encryption.keyVaultProperties — verifies key access, not just key reference), blob recoverability (soft-delete + versioning via blobServices.getServiceProperties), and per-container anonymous public access (account-toggle-aware via blobContainers.list). Deliberately non-overlapping with plugin 1022's network-exposure dims — mirrors the AWS 1020+1120 two-plugin S3 split. Maps to CC6.1 + CC6.7 + C1.1 + C1.2 + A1.2.
Azure NSG perimeter analysis at AWS-1170 parity. Evaluates each NSG's inbound rules in Azure priority order (first-match-wins; DenyAllInbound default) across 5 dims: all-protocol (*) public Allow, public-source to RESTRICTED_PORT (SSH/RDP/MSSQL/MySQL/Postgres/Redis/Memcached/MongoDB/Elasticsearch/CouchDB/SMB/WinRM/Oracle/Docker/Kubelet), ::/0 IPv6-wildcard to a restricted port (the dimension 1022's flat lint misses), public→non-restricted INFO substrate, and PASS substrate. Attachment-aware severity via nsg.subnets[] / networkInterfaces[] back-references — attached permissive = EFFECTIVE exposure; orphaned = LATENT. UDP transport lane with 27-port set (RADIUS 1812/1813 + legacy 1645/1646, L2TP 1701, SIP 5060, mDNS 5353, RIP 520, XDMCP 177, chargen 19) for auth backplanes / VPN endpoints / amplification vectors. Effective priority + deny-override resolution; service-tag / ASG-source normalization. Maps to CC6.6.
Third dedicated Azure auditor (after 1220 storage + 1221 NSG). The Key Vault analog of how plugin 1221 deepens plugin 1022's flat NSG dim. Enumerates each vault's keys, role assignments, and diagnostic settings across 5 dimensions: key auto-rotation policy, key expiry (epoch-s/ms/Date/string coerced), diagnostic logging → Log Analytics via @azure/arm-monitor, privileged-access depth (RBAC roleAssignments admin/data-plane/scope-aware tiering + legacy accessPolicies export/wide-crypto breadth + custom-role resolution via roleDefinitions.getById so custom RBAC roles granting KV wildcards are no longer a silent PASS), and HSM-backing software-vs-HSM key.kty discrimination (FIPS 140-2 Level 2/3 hardening recommendation on RSA / EC software-backed keys). Deliberately orthogonal to plugin 1022's vault-property dims — no double-emission. Secret/cert expiry is a stated data-plane scope boundary. Maps to CC6.1 + CC6.3 + CC7.2 + C1.1.
Amazon DocumentDB (MongoDB-compatible) rides the shared RDS control plane, so a docdb cluster's storage-encryption gap could read clean under the RDS auditor's Aurora-only filter. Plugin 1230 owns the docdb engine across 7 dimensions: storage encryption at rest + KMS key-custody classification (customer-alias PASS / AWS-managed / foreign-account & key-UUID custody-unverifiable evidence gaps — encryption is fixed at cluster creation, so the emission gives a migration remediation, never an unrunnable in-place one), TLS enforcement via the tls cluster parameter, audit logging (the audit_logs parameter and the CloudWatch audit export), backup retention, deletion protection, replica/AZ availability topology under the cluster lens (the per-instance Multi-AZ flag is RDS semantics and never consulted), and manual-snapshot public/cross-account restorability (all = CRITICAL). The RDS auditor now engine-filters DocumentDB and Neptune off the shared plane with a standing disclosure that a Neptune estate is unaudited; DocumentDB Elastic clusters are declared deferred. Per-dimension fail-closed evidence gaps. Maps to C1.1 + CC6.1 + CC6.6 + CC7.2 + A1.2.
The Model Context Protocol server registers seven tools and every tier sees all seven. Enterprise unlocks the two that reach your cloud accounts — scan_cloud and get_findings — and puts the 28 cloud auditors and all eight compliance frameworks behind them, so compliance_matrix answers for SOC 2, HIPAA, NIST CSF 2.0, PCI DSS, ISO 27001, CIS v8, GDPR Art. 32, and NIST SP 800-171 Rev 2 rather than for nothing.
Three tiers for every team size. All include the full Enterprise feature set — cloud scanning, the eight-framework compliance engine, air-gapped operation, and read-only cloud access enforced in code. Annual invoicing · net-30 · volume discounts available.
report --from <dir> --format executive (self-contained HTML, optional --brand cover; --format jira writes a Jira-importer CSV; the import mapping is done in Jira and has not been verified against a live Jira instance)report --from <dir> --format executive --since prior: what is new, resolved or changed severity, plus a NOT-COMPARABLE list with the reason on every row (how it works)Everything the engineers will ask about — architecture, the read-only execution model, cloud APIs, and the Zero-Data-Exfiltration design. Read the full technical specifications →
NSAuditor AI Enterprise runs entirely inside your infrastructure. Scan data, findings, reports, and credentials never touch Nsasoft servers. License validation is offline (JWT + embedded public key). We are not a data processor under any regulation.
CLOUD_PROVIDER=aws AWS_REGION=us-east-1 \ nsauditor-ai scan --host aws --plugins 1020,1030,1040,1050,1060,1070,1080,1090,1100,1110,1120,1130,1140,1150,1160,1170,1180,1190,1200 \ --compliance soc2,hipaa --out tasks/aws-scan-out # 1020 S3 · 1030 IAM Deep · 1040 CloudTrail · 1050 API Gateway · 1060 DynamoDB Audit Integrity · # 1070 KMS · 1080 Lambda · 1090 Secrets+SSM · 1100 CodePipeline+CodeBuild · 1110 IAM Decrypt-Path · # 1120 S3 Lifecycle+Replication · 1130 AWS Backup Auditor (12-dim air-gap attestation) · # 1140 AWS RDS Auditor (10 dims — pgAudit + CWL exports + log retention; CC7.2/CC7.3 database audit-logging) · # 1150 AWS SQS/SNS Auditor (7 dims — CloudWatch alarm coverage on SQS ApproximateAgeOfOldestMessage + SNS NumberOfNotificationsFailed; empty-AlarmActions silent-PASS closure) · # 1170 AWS EC2 SG Perimeter Auditor (23 restricted ports — CIS AWS Foundations v3.0) · # 1180 AWS ElastiCache Redis Auditor (kms:DescribeKey promotion + subnet route-table verifier with default-VPC main-RT-inheritance false-NEGATIVE closure; cross-plugin sister of 1170 SG perimeter) · # 1190 AWS SES Email Integrity Auditor (DKIM CNAME DNS resolution + DMARC TXT parser with pct=0 closure + sp override + SES classic API parity; first network-layer cross-reference in the EE evidence baseline). # Run just the headline plugin: --plugins 1130 (SEC 17a-4 / FINRA 4511 ransomware-defense substrate). # Tune VPC-endpoint PAGE_CAP for large fleets: --plugin-opts '{"1130":{"vpcEndpointsPageCap":50}}'
CLOUD_PROVIDER=azure \ AZURE_TENANT_ID=<your-tenant-id> \ AZURE_CLIENT_ID=<sp-app-id> \ AZURE_CLIENT_SECRET=<sp-secret> \ AZURE_SUBSCRIPTION_ID=<subscription-id> \ nsauditor-ai scan --host azure --plugins 1022 \ --compliance soc2,hipaa --out tasks/azure-scan-out # Baseline (test subscription): findingCount=2, byStatus pass=6 fail=2 # Maps to: CC6.1 (RBAC Owner / Contributor / User Access Administrator at sub-scope), # CC6.6 (NSG inbound from * / 0.0.0.0/0 / Internet), # C1.1 (Storage defaultAction=Allow, allowBlobPublicAccess=true)
GCP_PROJECT_ID=my-project \ GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.json \ nsauditor-ai scan --host gcp --plugins 1024 \ --compliance soc2,hipaa --out tasks/gcp-scan-out # Plugin 1024: 6 SOC 2 dimensions — IAM public bindings (CC6.6) · UBLA (CC6.6 + C1.1) · # Object Versioning (C1.1 + A1.2) · Retention Policy / Bucket Lock (C1.1 + C1.2) · # CMEK via Cloud KMS (CC6.1) · Bucket-level access logging (CC7.1). # Full GCP discovery: GCP_PROJECT_ID=my-project nsauditor-ai scan --host gcp --plugins all --compliance soc2,hipaa
GCP_PROJECT_ID=my-project \ GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.json \ nsauditor-ai scan --host gcp --plugins 1025 \ --compliance soc2,hipaa --out tasks/gcp-iam-scan-out # Plugin 1025 v2: 7 SOC 2 dimensions — Public-member bindings (CC6.1 CRITICAL/HIGH) · # Sensitive-role inventory: 12 predefined roles incl. owner/editor/iam.securityAdmin/serviceAccount* (CC6.1+CC6.6 MEDIUM) · # IAM Conditions classifier on sensitive roles: restrictive CEL = PASS · absent = MEDIUM · vacuous = LOW+evidenceGap (CC6.1). # Run all GCP plugins: GCP_PROJECT_ID=my-project nsauditor-ai scan --host gcp --plugins 1024,1025 --compliance soc2,hipaa
# One per-account dotenv file each — credentials, region, CLOUD_PROVIDER live in the file: nsauditor-ai scan --host aws --env ~/envs/dev.env --compliance soc2 nsauditor-ai scan --host aws --env ~/envs/prod.env --compliance soc2 # Or a named profile from the OS-default ~/.aws/credentials (no .env needed) — implies CLOUD_PROVIDER=aws: nsauditor-ai scan --host aws --aws-profile prod --compliance soc2 # GCP / Azure per-account via --env (key-file path / service-principal vars live in the file): nsauditor-ai scan --host gcp --env ~/envs/gcp-prod.env --compliance soc2,cis-v8 nsauditor-ai scan --host azure --env ~/envs/azure-prod.env --compliance soc2 # --env is a dotenv (KEY=value) file; for ~/.aws/credentials (multiple profiles) use --aws-profile. # Missing --env file = hard error (fail-fast — never silently audit the wrong/empty account). # On a sentinel host, --plugins all AUTO-SCOPES to that cloud's plugins (other clouds + non-cloud skipped + logged). # Your license is resolved independently of --env — no key needed in the per-account file.
# Audit one region, a comma-separated list, or EVERY account-enabled region. The regional auditors # (security groups, EC2, RDS, KMS, Lambda, DynamoDB, Backup, SQS/SNS, SES, Inspector/GuardDuty, CloudTrail, …) # run in every in-scope region; S3 resolves each bucket's own region — closing cross-region false-cleans. nsauditor-ai scan --host aws --plugins all --aws-region us-east-1 --compliance soc2 nsauditor-ai scan --host aws --plugins all --aws-region us-east-1,eu-west-1,ap-southeast-2 --compliance soc2 nsauditor-ai scan --host aws --plugins all --aws-region all --compliance soc2 # Precedence: --aws-region › AWS_REGION › single-region default. No flag = one region (and the report # discloses the unscanned regions); pass --aws-region all for full coverage. Unknown region = fail-fast. # In Claude Desktop, ask for "all regions" — coverage is batched by region group to fit the ~60s tool-call limit.
The MCP server registers seven tools, and every tier sees all seven listed. Your licence decides which ones run: the gate is at call time, so an unlicensed call returns a clear refusal rather than a silent empty result. Enterprise does not add tools — it unlocks the two that reach your cloud accounts, and it is what puts 28 cloud plugins and eight frameworks behind the ones you already had.
# @nsasoft/nsauditor-ai-ee is a private (restricted) package. # Use the npm read-token delivered with your license email. npm config set //registry.npmjs.org/:_authToken npm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Or, project-scoped, in an .npmrc file echo "//registry.npmjs.org/:_authToken=npm_xxxx..." >> ~/.npmrc
# Free Community Edition (nsauditor-ai) is the 27-plugin base. # The Enterprise package (@nsasoft/nsauditor-ai-ee) installs on top, adding 29 plugins — 28 cloud auditors # plus a network-host Zero Trust assessment → 56 total once licensed. npm install -g nsauditor-ai@latest @nsasoft/nsauditor-ai-ee@latest # Driving NSAuditor from an AI agent or Claude Desktop? Add the agent skill — it teaches the # agent NSAuditor's MCP tools, schemas, plugins and audit workflows (knowledge only; the MCP # server above still does the scanning): npm install -g nsauditor-ai-agent-skill@latest # • Claude Code: npx nsauditor-ai-agent-skill install (copies it into ~/.claude/skills/) # • Claude Desktop: npx nsauditor-ai-agent-skill build-zip --out ~/Desktop, then upload that zip # in Settings → Skills. Upload the zip, never SKILL.md alone; skills do not sync between # Claude surfaces, so Desktop is an upload by design. # • Cursor / Windsurf: copy the package's skill folder into the agent's skills or rules dir. # Docs: https://www.npmjs.com/package/nsauditor-ai-agent-skill
# CE 0.2.24+ verifies the JWT signature before persisting # and stores the key in macOS Keychain (or ~/.nsauditor/.env mode 0600 on Linux/Windows). nsauditor-ai license install enterprise_eyJhbGciOiJFUzI1NiIs... ✓ Enterprise license installed Stored at: macOS Keychain (service=nsauditor-ai) Org: you@example.com Seats: 5 Expires: 2027-04-04T... # CI/CD alternative: env var still works (highest priority in the multi-source loader) export NSAUDITOR_LICENSE_KEY=enterprise_eyJ...
nsauditor-ai license --status ✓ Enterprise license active | Org: you@example.com | Seats: 5 | Expires: 2027-04-04 nsauditor-ai license --capabilities ✓ intelligenceEngine ✓ riskScoring ✓ complianceEngine ✓ cloudScanners ✓ zeroTrust ✓ enterpriseMCP
# Dual-framework SOC 2 + HIPAA §164.312 audit in one scan — both evidence packs from the same findings nsauditor-ai scan --host aws --plugins all \ --compliance soc2,hipaa
--compliance soc2 or --compliance hipaa. For per-cloud and on-prem recipes, see the Cloud audit samples section below.npm i -g nsauditor-ai@1.0.0 @nsasoft/nsauditor-ai-ee@2.0.0. The agent skill 1.0.0 requires the same floor. The Community floor is an optional peer that npm install -g does not enforce, so installing Enterprise alone over an older Community gives no warning.
2 · Check the floor: Enterprise 2.0.0 imports a name that first ships in Community 1.0.0; below it Enterprise’s core does not load while its plugins still do — on Community 0.2.57 as on 0.2.56 — so the scan skips its intelligence, analysis-agent and compliance stages: Community 0.2.56 and later name that on stderr ([EE] Enterprise is installed but FAILED TO LOAD), and 0.2.55 or older says nothing.
3 · Rotate a webhook URL a logged --watch run printed: --watch printed the full --webhook-url to stdout; it now prints the host.
4 · A weak certificate under a trusted CA now reads as the weak-key or weak-signature finding alone, not also as an untrusted chain; a weak certificate under an untrusted CA still reads untrusted. And compared across the upgrade, the phantom rows’ disappearance reads as not measured, never as fixed.
identity-basis-changed, never RESOLVED or NEW (and the two limits ↑).
b · Two exit codes can move a pipeline: --fail-on now gates findings it never read, so a pipeline that passed may fail on findings that were always there; and nsauditor-ai mcp verify-call <id> without --response exits 3, not 0.
NVD_CACHE_DIR, else NSAUDITOR_NVD_CACHE_DIR, else ~/.nsauditor/nvd_cache; --cache-dir is a flag of feed import alone, for the feeds you downloaded. An old .nvd-cache folder is no longer read, and every run records which location it used.
To keep an offline store you built with feed import from your own downloaded feeds, move it once, from the directory that holds the old .nvd-cache folder: mkdir -p ~/.nsauditor/nvd_cache && mv .nvd-cache/* ~/.nsauditor/nvd_cache/ — or set NVD_CACHE_DIR to that folder. If an old folder exists where you run from, the scan and the import both name it and the fix.
Until you move it, an offline-only scan emits a [COVERAGE GAP] record rather than reading as no CVEs, and since Enterprise 1.3.0 that record fails, as an evidence gap, the compliance controls a CVE row maps to (HIPAA has no CVE-mapper rule) — a service with no CPE mapping or no detected version is still recorded but routed to no control. An online scan simply fetches again.
b · The first delta report across that upgrade shows a large NOT-COMPARABLE list, because fourteen producers changed what identifies a finding: nine of them (1020, 1024, 1025, 1030, 1150, 1170, 1190, 1200, 1210) name the object a finding is about; the S3 lifecycle and replication auditor (1120) and the CloudTrail auditor (1040) carry the region the report reads; the Zero Trust checker (1023) names the port; the effective-decrypt auditor (1110) carries corrected text on its HIGH row; and the CVE analysis agent no longer keys a finding on the software label it detected. That is the declaration working, not a broken report — it is how a delta tells two findings apart.
c · The effective-decrypt auditor (1110) keeps a kms:Decrypt on Resource:* HIGH on a live run, because it reads one region and one region cannot show that no key elsewhere trusts the principal. And plugins can declare their own time budgets, bounded by a ceiling — an exceeded budget reads not measured, not clean.
Coming from a release before 0.32.9? The evidence-gap finding title changed there, so re-check suppression rules written against the old text.
nsauditor-ai report --from <dir> --format executive --since prior, where <dir> is the directory you gave the scan as --out, compares two scan runs and renders what is new, what is resolved and what changed severity into the self-contained HTML report you hand a client or an assessor. When the report can see that a finding was not measured the same way twice, it files it under NOT-COMPARABLE, with the reason on the row, instead of calling it resolved — among the reasons: a host that was not scanned; a finding that carries no producer identity; a plugin that did not run, errored or timed out; an analysis agent that did not run, or whose input plugin was left out of the scan or did not complete; an Enterprise package that failed to load; an evidence gap, including a CVE lookup that failed; a narrower scope; a port whose check could not complete; a TCP port the port scanner saw open that stopped answering between the two scans, or that answered without its service being identified (for a CVE or end-of-life row); a UDP port the other scan did not record as closed or answering; a producer whose identity basis changed across an upgrade; and a CVE the vulnerability data stopped attributing while the same program and version still answer. A finding that could not be compared is not a finding that was fixed. Two measured limits remain: only a scan made since Enterprise 1.3.0 records a plugin left out of it, so in a comparison with an older scan, an agent’s row that scan lacks is not refused — the report’s Basis cell says so on the row; and a scan that discovered ports with the Nmap plugin (024) alone records no port oracle, so an analysis agent’s or the CVE mapper’s row on a port it did not measure can read RESOLVED and count as closed in MTTR, and the control it failed can read PASS — include the port scanner (003) in scans you compare. Two runs at different licence tiers are refused outright, and so are two runs straddling a release where a reported number changed meaning. Beside every comparison it states that framework-enumeration movement was not evaluated in this release, and what it could establish about the baseline’s integrity. Each run record and each host’s findings files are sealed with SHA-256 digests and chained to the previous run, so an altered findings file is named and the comparison refused. Only scans run since Enterprise 1.1.0 are sealed: a baseline scanned before the upgrade is still compared, but the report says it carries no integrity digest, so alteration of that baseline could not be ruled out. The chain is tamper-evident against accidental corruption, partial restores and unsophisticated edits; it is not tamper-proof against an attacker with host-level access, and it is not non-repudiation, because nothing in the chain is signed and nothing names an author. How it decides ↑ · The delta report on the Pro page →scan_drift_<fw>.json beside its pack: the controls that went to fail or to pass, the controls that lost measurement, and the violations that are new or cleared. A violation is cleared only when this scan looked for it and it was gone; one whose scanner did not run or reported itself down, or whose port or region was not measured, is listed as could-not-measure with its reason. The notification is opt-in: --notify-webhook (public https only), --notify-format generic|slack|teams and --notify-severity send the drift to your webhook, Slack or Teams when a control goes to fail or loses measurement, when a new violation reaches the severity you set, or when the drift could not be compared with a previous run; the first scan, with no previous run, is the baseline and sends nothing. The payload is minimal by default. CLI only — not --watch, not the MCP server. A notification retried after a timeout or a server error can arrive twice, and a hanging endpoint can cost about 32 seconds per framework. A scan that found its ports with the Nmap plugin (024) alone has no port oracle, so a violation on a port that scan did not measure can be listed as cleared; include the port scanner (003) in the scans you compare. On a host where another port completed a TLS handshake, a port whose TLS probe failed in transport is not read, so an earlier TLS finding there can be listed as cleared; and a previous pack that recorded neither a scanned host nor a single scope target (a pack records its host since Enterprise 1.1.0) cannot be re-keyed, so its agent findings are listed as cleared and new once. What 2.0.0 brings ↑Pick the Enterprise tier that fits your team — Base, Growth, or Scale. All tiers include the full Enterprise feature set, with onboarding call included.
A scanner on an isolated network has a standing problem: the vulnerability data it matches against lives on the internet, and it does not. Enterprise ships a dependency-complete bundle carrying both editions, an install script and SHA-256 checksums — a restricted distribution — so the install and the CVE data can both be carried in.
The condition travels with this path and is part of the offer, not a footnote:
the bundle is a restricted distribution rather than a public
npm install. It is not architecture-restricted — the install
script in the restricted package is verified on native aarch64 as well as amd64, so an arm64 enclave is
covered by this path. The published container image is amd64 only; that is a
different delivery vehicle from this bundle.
No CVE, KEV or EPSS data ships with the product. You download the NVD feeds you want on a connected host, bundle them, and carry the archive across. Your own CISA KEV catalogue and FIRST EPSS scores can ride the same archive. Both fail closed when stale, so an out-of-date catalogue never reports “not exploited”.
⚠️ A carried bundle is integrity-checked, not authenticated. The recorded SHA-256 detects a file altered in transit, but it travels inside the archive it covers, so it cannot establish who built it.
The install, end to end. On a connected host, authenticate with the download token from your purchase email and fetch the bundle:
npm pack @nsasoft/nsauditor-ai-ee-airgap@2.0.0
tar xzf nsasoft-nsauditor-ai-ee-airgap-2.0.0.tgz
Carry the extracted directory to the isolated host and run its script. It verifies the carried checksums before installing anything, installs Community Edition first (Enterprise declares a peer dependency on it), and forces every install offline:
./install.sh
nsauditor-ai license --plugins
Then carry the vulnerability data, which is separate and never ships with the product:
# connected host
nsauditor-ai feed bundle --from ./nvd-downloads --out feeds.json.gz \
--kev ./known_exploited_vulnerabilities.json --epss ./epss_scores.csv.gz
# isolated host — imports the feeds you downloaded, from a bundle you carried; restricted distribution
nsauditor-ai feed import --file feeds.json.gz --extras-dir ./stores
export NSAUDITOR_OFFLINE_ONLY=1
nsauditor-ai scan --host aws --env ./org.env --compliance soc2 --out ./out
NSAUDITOR_OFFLINE_ONLY=1 refuses to start if an outbound path is also configured,
which rules out the opt-in RFC 3161 timestamping path inside the enclave. A host with no
sha256sum or shasum is refused rather than installed onto.
What is verified before the bundle ships. Every release re-builds it and runs a delivery
gate against those exact tarballs: all 44 declared production dependencies resolve from the carried
closure, 29 Enterprise plugins load, a store-backed scan returns findings from carried CVE data, and
the run makes zero network attempts. The gate never reads npm’s exit status —
every production dependency is an optionalDependency, so a NIC-down install of the
unvendored package exits 0 having installed almost nothing.
Verify the delivery yourself — not the installer. The installer’s exit code is the
one thing not to trust on an isolated host, and it is structural rather than a bug: every production
dependency is an optionalDependency, so npm skips an unfetchable one silently
and still exits 0. After install.sh, confirm what actually landed —
nsauditor-ai license --plugins must report the Enterprise plugins active, and a
require.resolve sweep of the declared production dependencies must reach 44 of 44
— the carrier shipped in EE 0.43.0 measured 44 of 44 at that release. The same sweep against the ordinary, non-bundled package on an isolated host reaches
0 of 44 — with npm still exiting 0. The full command is in the walkthrough.
# on a connected host — bundle the feeds you downloaded nsauditor-ai feed bundle --from ./nvd-downloads --out feeds.json.gz # carry it across, then on the isolated host ./install.sh # verifies checksums first, installs offline nsauditor-ai feed import --file feeds.json.gz export NSAUDITOR_OFFLINE_ONLY=1 nsauditor-ai scan --host aws --compliance soc2