SOC 2 evidence the auditor actually accepts.

NSAuditor AI Enterprise Edition produces a Type-I-friendly pre-audit gap report mapped to the AICPA Trust Services Criteria 2017 (with 2022 points of focus) — SHA-256 chain-of-custody sidecars, a cover-page Scope Attestation, and opt-in scan-time GRC push (Vanta, Drata, Secureframe).

✓ 10 controls fully covered ⚠ 4 partial ↑ Type I & Type II ⇄ GRC push (opt-in)
About this page. This describes what NSAuditor AI EE — our flagship product — delivers for your SOC 2 audit. Nsasoft itself does not currently hold its own SOC 2 attestation, and unlike most security vendors we don't need one: NSAuditor AI runs entirely on customer infrastructure with Zero Data Exfiltration. We are not a data processor. Read why →

TL;DR — what this does for SOC 2

NSAuditor AI EE generates a pre-audit gap report with institutional-level evidence controls. It maps cloud and network scan findings to specific Trust Services Criteria, produces evidence artifacts (cover-page Scope Attestation, SHA-256 chain-of-custody sidecars), and ships in machine-readable form suitable for GRC platform ingestion (Vanta + Drata + Secureframe connectors shipped, opt-in early-access).

It is not a SOC 2 Type II evidence pack on its own (Type II requires recurring-scan attestation across 6–12 months — supported via recurring-scan attestation + SLA/MTTR tracking, both shipped). It is not a replacement for governance, risk-assessment, or business-continuity evidence. It is not a substitute for a CPA-firm audit — this is the pre-audit report you give your auditor so they don't bill you for finding what you already knew.

The market split: GRC platforms (Vanta, Drata, Secureframe) automate workflow but lack native vulnerability scanning; legacy scanners (Tenable, Qualys, Rapid7) produce voluminous CVE reports but don't map findings to TSC controls. Our wedge is the bridge — deep scanning + auditor-mapped output + opt-in GRC push.

Direct TSC Mapping

Each finding carries stable rationale text mapped to a specific Trust Services Criterion the auditor can attach.

RFC 3161 Timestamps (opt-in — set NSAUDITOR_TSA_URL)

Third-party Time-Stamp Authority signs each artifact's hash — non-repudiation an internal actor can't backdate.

Suppression Signature Verification (when the approver's registry entry carries key material)

Each rendered signature is checked against the public key the registry names for that approver, so a tampered record reads FAILED and a revoked key makes signing after revocation a cryptographic finding. Late-renewal flagging surfaces governance drift.

Type II Recurring Attestation

Multi-scan chronological matrix across 6–12 month windows with cadence-gap and scope-drift detection.

Opt-in GRC push

Vanta + Drata + Secureframe connectors (opt-in, scan-time, early-access) — TestResult outcome mapping, idempotency, retry/backoff; live-tenant validation in progress.

WORM Evidence Storage

S3 Object Lock COMPLIANCE-mode validation for SEC 17a-4 / FINRA 4511. GOVERNANCE mode rejected by design.

AICPA TSC 2017

Coverage matrix

Source of truth is data/compliance/soc2.json in the EE package; this matrix mirrors it. A test asserts the two stay in sync.

StatusCountTrust Services Criteria
✓ Covered10CC6.1, CC6.2, CC6.6, CC6.7, CC6.8, CC7.1, CC7.2, CC7.3, C1.1, C1.2
⚠ Partial4CC6.3, CC8.1, A1.2, PI1.5
⚪ Out of scope37CC1.*, CC2.*, CC3.*, CC4.*, CC5.*, CC9.*, PI1.1–PI1.4, P1.0–P8.0, CC6.4, CC6.5, CC7.4, CC7.5, A1.1, A1.3

What "Covered" means here

"Covered" means the engine produces direct evidence the auditor can attach to the control. CC6.1 (Logical access security) catches password-only SSH, exposed admin panels, AWS users without MFA, shadow admins, privilege-escalation paths, Azure RBAC role assignments at subscription scope, and RDS IAM database authentication evidence (password-less auth on mysql/postgres/mariadb/aurora). CC6.6 (Network-boundary protection) flags exposed-to-Internet management ports, Azure NSG 0.0.0.0/0 rules, the 12-dimension air-gapped backup-vault attestation arc (plugin 1130) verifying cryptographic isolation of LogicallyAirGappedBackupVault resources across vault TYPE + ARN account-segment + KMS key-policy + KMS Grants + MRK-replica topology + source-account VPC-endpoint policy, the AWS SQS transit-encryption policy + SNS topic-policy permissive-Principal classifier with NotAction-Allow + NotPrincipal-Allow + Resource-scope filtering (plugin 1150), and the AWS EC2 SG Perimeter Auditor (plugin 1170) with deterministic CRITICAL findings on IPv4 0.0.0.0/0 and IPv6 ::/0 ingress to 13 RESTRICTED_PORTS (SSH/RDP/MS SQL/MySQL/Postgres/Redis/Memcached/MongoDB/Elasticsearch/CouchDB/Docker daemon/Kubelet API) — orthogonal evidence to plugin 1023 zero-trust-checker (1023 reads OBSERVED open ports; 1170 reads DECLARED SG policy). CC6.7 (Data in transit) flags TLS 1.0/1.1, weak ciphers, missing HSTS, API Gateway custom-domain TLS policy with worst-policy tracking (plugin 1050), and RDS parameter-group SSL enforcement (postgres rds.force_ssl + mysql require_secure_transport). CC7.1 is evidenced by CVE matching against an offline NVD feed, EOL-software detection, S3 access-logging gaps (raised only when no CloudTrail data-event trail already covers the bucket — coverage is judged per selector, and org trails or prefix-scoped selectors are refused rather than assumed), CloudTrail log-file-validation gaps, CodePipeline stale-execution detection + S3 cross-region replication destination-bucket reachability, and SQS dead-letter queue presence (plugin 1150 — dual-mapped with A1.2). CC7.2 + CC7.3 — covered via the CloudTrail Operational Integrity Auditor (1040). C1.1 (Confidentiality) is evidenced by S3 misconfiguration findings, Azure Storage, KMS wildcard-principal classification (plugin 1070), Lambda EOL runtime / environment-variable secret detection (1080), Secrets Manager + SSM Parameter Store metadata-only audit with the ZDE verb-prefix denylist (1090), SQS + SNS encryption-at-rest with KMS-custody classification (plugin 1150), and RDS storage encryption with the headline kms:DescribeKey cross-reference promoting UNVERIFIABLE :key/UUID ARN shapes to deterministic PASS (CUSTOMER-managed CMK) or MEDIUM (AWS-managed) — without compromising the conservative-classifier discipline (AccessDenied / NotFound / unknown KeyManager → still leaves at LOW). C1.2 (Disposal of confidential information) is evidenced by S3 lifecycle findings, CloudTrail trail-destination buckets, and the AWS Backup Auditor (1130) — the most-evidenced control across the backup substrate. The full list with example findings and TSC rationale (spanning AWS + Azure + GCP plugins, 29 EE plugins) lives in the EE package's SOC 2 coverage doc.

What "Partial" means

NSAuditor AI evidences one dimension of these controls (typically the configuration-state-at-this-moment dimension). CC6.3 is partial because we detect stale IAM keys but the removal-cadence dimension needs CTEM history. CC8.1 is partial because we capture configuration snapshots but change-authorization linkage requires ITSM/Git PR webhook integration. A1.2 is substantially evidenced: plugin 1130 AWS Backup Auditor closes the "Backup/recovery posture itself" gap across the full AWS Backup substrate (Plans, Vaults, Recovery Points, Selections, Frameworks, Restore Testing Plans, ReportPlans, Legal Holds, vault TYPE, Vault Tags, Vault Access Policy); plugin 1140 AWS RDS Auditor adds Multi-AZ deployment evidence, backup retention period (operator-tunable 1-35 days, ≥7 institutional default), snapshot encryption via DescribeDBSnapshots with explicit IncludeShared=false + IncludePublic=false, and the Aurora DB-cluster snapshot dimension (a public restore=all cluster snapshot is CRITICAL; cross-account HIGH; unencrypted HIGH); plugin 1150 adds SQS dead-letter queue presence (dual-mapped with CC7.1). The cadence dimension (recurring-scan attestation of restore-test outcomes) is what would move A1.2 to covered. PI1.5 (Stored items) is partial via the DynamoDB Audit Integrity plugin (1060). Substrate-only scope — full PASS requires application-tier Lambda Runtime Assurance. The renderer surfaces a ⚠ Coverage caveat line on every partial control so an auditor seeing FAIL/PARTIAL knows the boundary of what we evidenced.

What "Out of scope" means

A SOC 2 audit covers technical, administrative, and physical controls. NSAuditor AI evidences the technical-network-and-cloud slice. Everything else is genuinely not our job — pretending otherwise would create what auditors call "scope illusion": the false belief that buying a scanner replaces governance work. The renderer emits all 37 OOS controls with their reason text in every gap report so auditors immediately see the engine's known boundaries and don't have to guess what wasn't evaluated. Pair with a GRC platform (Vanta / Drata / Secureframe) for the governance layer.

Output artifacts

What the auditor actually receives

Each --compliance soc2 run writes 10 files to out/<scan-id>/ (14+ when recurring-attestation is configured), every one with a .sha256 integrity sidecar.

FilePurpose
scan_compliance_soc2.mdMarkdown gap report — engineering / GRC consumption.
scan_compliance_soc2.htmlStandalone HTML report (inline CSS, dark theme, "Print to PDF" button) — give this to the auditor.
scan_compliance_soc2.jsonFull report data (machine-readable) — for GRC API push or custom downstream tooling.
scan_attestation_soc2.jsonCover-page Scope Attestation — CIDR list, exclusions, scanner version, and an ntp block of constants because the NTP clock attestation is WITHDRAWN as of EE 0.45.0.
scan_chain_of_custody_soc2.jsonChain-of-custody envelope linking scan → findings → artifact hashes.
*.sha256Per-artifact SHA-256 sidecars — verify with shasum -a 256 -c <file>.sha256.
*.tsr / *.tsr.bundle.jsonRFC 3161 Time-Stamp Response + TSA cert chain bundle (opt-in — written when NSAUDITOR_TSA_URL names a Time-Stamp Authority).
compliance_recurring_attestation_soc2.{md,json}Type II recurring-attestation report (when configured).

The report you send

nsauditor-ai report --from <run> --format executive turns a finished scan into a single self-contained, print-ready HTML file: nothing is fetched when the auditor opens it, and an optional --brand puts your own mark on the cover page. --format jira writes a Jira-importer CSV instead — the column mapping is completed inside Jira’s own importer and is not validated against a live Jira instance. The executive report carries a container census: where finding-like records sit in a place the report does not read, the report names and counts them on the page, so a silence is disclosed rather than rendered as a clean result. Pro and Enterprise tiers.

The cover-page Scope Attestation

Every artifact opens with the same attestation block — this is the auditor's single source of truth for what was assessed:

How an auditor verifies the artifacts

# Verify integrity sidecars (all four MUST return OK) $ shasum -a 256 -c scan_compliance_soc2.md.sha256 $ shasum -a 256 -c scan_compliance_soc2.html.sha256 $ shasum -a 256 -c scan_compliance_soc2.json.sha256 $ shasum -a 256 -c scan_attestation_soc2.json.sha256 # RFC 3161 trusted timestamp (opt-in — set NSAUDITOR_TSA_URL to a Time-Stamp Authority, # and a .tsr sidecar is written beside each artifact; leave it unset and # nothing is timestamped, so this command has nothing to verify). # NOTE: -data, not -queryfile. No .tsq is written — the request is built in a # temporary directory and deleted — and the two flags are mutually exclusive, # so passing both makes openssl exit 1 with no verdict at all: $ openssl ts -verify \ -in scan_compliance_soc2.json.tsr \ -data scan_compliance_soc2.json \ -CAfile /path/to/tsa-ca-bundle.pem
Why this holds up to a CPA review

Evidence integrity — three layered guarantees

SOC 2 evidence falls apart the moment an auditor finds a gap a security team could exploit. We engineered for the threat model where the security team itself is one of the actors.

1. Integrity (against bit-rot & unsophisticated tampering)

Cover page is part of the report bytes. .sha256 sidecars verify the report bytes. If the cover-page scope is wrong, the hashes won't match. Always written.

2. Non-repudiation (against an insider regenerating both)

Opt-in, and off unless you configure it: set NSAUDITOR_TSA_URL to a Time-Stamp Authority and each artifact ships a .tsr sidecar containing a Time-Stamp Response from an RFC 3161 Time-Stamp Authority (opt-in; nothing is timestamped unless you name one, and an offline-only posture refuses it outright rather than skipping quietly). The TSA's signature attests "this hash existed at <TSA timestamp>" — a third-party time floor an internal actor cannot backdate. Recommended TSAs: FreeTSA.org (free, testing), DigiCert / Sectigo / GlobalSign (paid commercial), or your internal corporate TSA.

3. Suppression non-repudiation

The compliance suppress command signs an approval with Ed25519 when NSAUDITOR_SIGNING_KEY names a key and the compliance report checks that signature for approvers whose identity-registry entry carries key material. The signature payload is NFC-normalized per RFC 5198 and capped at 64KiB. The registry binds approver names to public keys with authorization scopes (which frameworks an approver may authorize for); an entry may carry the approver's public key beside its fingerprint, and the fingerprint must equal the one computed from that key material or the registry is refused at load. Two axes are reported rather than one: verified answers whether the suppression should stand, and cryptoValid answers whether those bytes came from the named key — they diverge on a revoked key, which is what makes signing after revocation a cryptographic finding. A missing verdict means the report did not check, never that a check failed; the report renders “signed — not checked by this report”. Late-renewal flagging surfaces governance gaps as bands: HEALTHY / ACCEPTABLE / DEFICIENT / CRITICAL. Quarterly trend analysis catches degradation that single-point-in-time review would miss.

The "what about false positives?" answer

Suppression workflow

Every real scan produces findings the security team triaged out — false positives, accepted risks with compensating controls. SOC 2 auditors reject silent deletion (looks like under-reporting) but accept documented exclusions.

The compliance engine resolves the suppressions file in three steps — NSAUDITOR_SUPPRESSIONS when you set it (an absolute path is honoured verbatim, a relative one resolves against your working directory), then the per-scan folder if a file is genuinely there, then the --out base, which is where compliance suppress writes — and enforces three fields per suppression: a specific match, a non-empty rationale, and an approver. Suppressions missing any of these are rejected and the underlying finding stays in fail status — the engine refuses to silently absorb undocumented suppressions.

Per-status default expiry

Where suppressions show up

Every suppression appears in Appendix B — Accepted Risks & False Positives with control ID, finding text, status (accepted_risk vs false_positive), approver, rationale, and renewal chain. Expired suppressions surface as report.expiredSuppressions[] with a "REVIEW REQUIRED" callout when non-empty.

Type I vs Type II

Operating-effectiveness over time

Audit typeSupportEvidence produced
Type I — point-in-time control design Full Single scan + cover-page attestation + SHA-256 integrity sidecars (always written). TSA timestamps are opt-in — set NSAUDITOR_TSA_URL to add an RFC 3161 .tsr sidecar to each artifact.
Type II — operating effectiveness over 6–12 months Supported Recurring-scan attestation + SLA / MTTR tracking with per-severity thresholds + suppression renewal cadence + version-delta detection across scans + quarterly trend analysis.

Recurring-scan attestation — compliance status taxonomy

SLA / MTTR tracking

Per-severity thresholds from sla.json. Three statuses per finding: compliant, approaching (default 75% of threshold), breached. The renderer separates breachedTotal (raw count) from breachedEffective (post-compensating-control). Auditors read both — breachedEffective > 0 is a hard CC7.1 finding. Suppressions with status: accepted_risk + non-empty compensating_control flip the effective status to breached_with_compensating_control; the renderer surfaces an inline disclaimer requiring auditor verification of each compensating-control text.

GRC platform integration

Opt-in GRC push (Vanta, Drata, Secureframe)

The Vanta, Drata, and Secureframe connectors map NSAuditor findings to each platform's evidence objects (e.g. Vanta TestResult; Secureframe uses the records model — NSAuditor pushes structured control records to the workspace evidence collection and your Secureframe rules evaluate them, the connector carrying the control status verbatim) and push them opt-in at scan time — you choose when to share. All three are early-access and single-workspace (not a multi-tenant sync); Secureframe's API shape is published-assumed and live-tenant validation is in progress.

Outcome mapping (Vanta)

NSAuditor statusVanta outcome
passpassed
fail (all violations compensated)passed_with_compensating_control
fail (any uncompensated)failed
partialfailed (Vanta has no partial; partialReason in description)
accepted_riskpassed_with_compensating_control
false_positivepassed

Reliability features

Vendor FAQ

Is Nsasoft itself SOC 2 audited?

A direct answer to the most common procurement question. We're transparent about what we do and don't have.

Short answer

No, and we don't currently need to be. NSAuditor AI runs entirely on customer infrastructure. Scan data, findings, reports, and credentials never touch Nsasoft servers. License validation is offline (JWT with embedded public key). AI analysis uses customer-provided API keys (OpenAI, Claude, Ollama). We are not a data processor under any regulation.

Why most security vendors need SOC 2 (and we don't)

SaaS GRC platforms, MDR services, and cloud SIEMs all ingest customer security telemetry into their own infrastructure. They are data processors. SOC 2 attestation is the table-stakes proof that they handle that data competently — DPAs and BAAs are required, vendor security reviews are required.

NSAuditor AI is the inverse architecture. The product is a CLI / scanner / MCP server that runs in your environment. It produces files you keep. The only network traffic between you and us is npm package installs and (if you're an Enterprise customer) license-key purchase & renewal — all of which happen through standard npm and Stripe infrastructure. We have nothing of yours to safeguard.

What we offer instead of an attestation

Future plans

If we ever begin processing customer data — for example a hosted GRC service or a SaaS dashboard layer — we will pursue SOC 2 Type II at that point and will publish the attestation here. Until then, the honest answer is "we don't need it, and we'd rather you didn't trust us than perform a compliance theater."

Auditor FAQ

Questions your CPA firm asks, answered up front

How do I verify the scope of this report wasn't manipulated post-scan?

Three layered guarantees: integrity via SHA-256 sidecars on every artifact (always written, verifiable with shasum -a 256 -c); non-repudiation via opt-in RFC 3161 trusted-timestamp .tsr sidecars, written when NSAUDITOR_TSA_URL names a Time-Stamp Authority and absent when it does not; suppression non-repudiation via Ed25519 signatures checked against the identity registry for approvers whose entry carries key material, with a missing verdict meaning not checked rather than failed.

What if the security team marked a real finding as "false positive" to make the report look clean?

Multiple controls prevent this: every suppression is logged in Appendix B with rationale + approver; suppressions renewed after expiration are flagged LATE or VERY_LATE; quarterly trend analysis surfaces governance degradation. (Ed25519 suppression signing and identity-registry cross-reference run for approvers whose registry entry carries key material, and a missing verdict means the report did not check rather than that a check failed.)

How does the scanner handle clock drift?

WITHDRAWN as of EE 0.45.0 — the NTP clock attestation, its drift probe, its strict mode and its probe-staleness classification are removed from the product and are no longer claimed. Two measured reasons: it attested this scanner’s own host clock, while every framework time-synchronisation control asks about the customer estate; and over unauthenticated UDP it accepted any well-shaped reply, so the assurance never matched the word beside it. Report time is anchored instead by RFC 3161 trusted timestamping, opt-in via the NSAUDITOR_TSA_URL environment variable, whose token takes its time from the Time-Stamp Authority rather than from this host. The cover-page scope attestation still carries its ntp block, now with constant values and a note stating that this scanner does not measure its own clock.

This is a single-point-in-time scan. How does Type II apply?

NSAuditor AI EE supports Type II evidence via recurring-scan attestation, SLA / MTTR tracking with per-severity thresholds, version-delta detection across scans, and quarterly suppression-renewal cadence trend analysis with governance bands.

Why is CC1 (control environment) marked out of scope?

CC1 is about board oversight and organizational ethics — these are inherently human / process artifacts, not network state. We could pretend, but pretending creates more audit risk than admitting the boundary. Pair NSAuditor AI EE with a GRC platform (Vanta / Drata / Secureframe) for the governance layer.

Where can I see the canonical mapping?

The source of truth is data/compliance/soc2.json in the EE package. The full SOC 2 coverage matrix in the EE repo mirrors that file, and a test asserts the two stay in sync. The customer-facing version is at nsauditor.com/ai/docs/soc2/.

Ready to ship a SOC 2 audit?

Talk to us about an Enterprise license, or grab the open-core CE on npm to evaluate the scanner first. Audit-ready evidence in under five minutes from your first scan.