Nsasoft US LLC today shipped NSAuditor AI Enterprise Edition (EE) v0.3.6 — an evidence-quality release that consolidates five distinct SOC 2 CC6.1 improvements without moving any controls in the AICPA Trust Services Criteria coverage matrix (still 8 covered / 5 partial / 34 OOS). The release pairs with Community Edition v0.1.38 on npm. Auditors evaluating SOC 2 evidence must verify the CE version recorded in artifacts is ≥ 0.1.37 (the security-fix floor).
For AWS-using SOC 2 audit teams, EE 0.3.6 closes three distinct classes of false negatives in the shadow-admin BFS, and ships two new auditor-workflow improvements that materially reduce remediation cost at organizational scale.
The false-negative classes that closed
Federated identity providers (SAML, OIDC)
Pre-0.3.6, _assumeRoleTrustsPrincipal only inspected principalSpec.AWS — the Federated: principal type was silently ignored. Any customer using Okta, Azure AD, Google Workspace, or GitHub Actions OIDC federation had an undetectable shadow-admin class. SSO-via-SAML is the dominant assumption pattern in modern enterprises, so the blind spot was material.
EE 0.3.6 ships _detectFederatedTrustRoles(roles) which emits per-role records under result.federatedTrustRoles[]. Records distinguish SAML providers from OIDC providers from well-known string IdPs (cognito-identity, Google, Amazon, Facebook). The crossAccount: true flag fires when the SAML/OIDC provider account ID differs from the role’s account ID — the canonical adversarial pattern (attacker creates IdP in their account, victim’s role trusts it).
A subtle but important post-fold detail: when a role has mixed-Condition federated statements (statement 0 unconstrained, statement 1 Condition-scoped), the new hasUnconstrainedStatement flag fires loud while hasCondition also fires — the detail string prioritizes the unconstrained signal so auditors don’t get the soft “Condition-scoped” wording for a role that actually has an unconstrained trust path.
NotAction-encoded trust statements
NotAction Allow statements are legitimate AWS IAM constructs. Allow + NotAction: ["iam:GetRole"] + Principal: AWS: <user-arn> grants every action EXCEPT iam:GetRole to that user — including sts:AssumeRole. Pre-0.3.6 four trust-evaluator helpers (_assumeRoleTrustsPrincipal, _detectWildcardTrustRoles, _detectFederatedTrustRoles, _assumeRoleTrustsService) each used raw actions.some(...) patterns that silently returned false on NotAction-encoded trust. An attacker writing such a statement evaded BFS detection entirely.
EE 0.3.6 refactors all four helpers onto the existing NotAction-aware _actionMatches(stmt, action) helper — which had been correct for years for action-level analysis but was never plumbed into the trust-evaluator path. Single unified semantic across the codebase.
The false-clean class: AccessDenied on permission-needed APIs
A misconfigured auditor IAM role missing iam:GetPolicyVersion, ListAttachedRolePolicies, or any other read permission would produce a scan with an empty findings array on the denied API. The scan completed. The report said “no findings.” The auditor accepted the evidence. Worst possible SOC 2 Type II audit outcome.
EE 0.3.6 ships an SDK-client instrumentation layer that captures every permission-class error (AccessDenied | AccessDeniedException | UnauthorizedOperation | AuthorizationError) at a single point and surfaces a frozen summary.scanCoverage.accessDeniedByApi map:
{
"scanCoverage": {
"accessDeniedByApi": {
"GetPolicyVersion": 14,
"ListAttachedRolePolicies": 7,
"ListGroupsForUser": 3
}
}
}
Combined with a warnings[] entry naming the affected APIs, an empty findings array on these APIs can no longer be silently mistaken for “no findings” — the scan never got authoritative answers.
The two auditor-workflow wins
Per-hop statement-index pointers
EE 0.3.5 emitted [via policy: <arn1>, <arn2>; inline: <name1>] aggregate suffixes — auditors knew WHICH policies contributed but not WHICH STATEMENT inside the policy granted the action enabling each hop. A 15-statement policy meant reading every statement to find the one to revoke.
EE 0.3.6 ships per-hop statement-index pointers in a new pathEvidenceByPath field. The auditor’s remediation workflow goes from “open policy → read 15 statements → find one to revoke” to “open policy → jump to statement N.” For SOC 2 Type II evidence at organizational scale, this is the single biggest auditor-workflow improvement of the release.
Conditional-trust triage signal
A role with Condition: { StringEquals: { "sts:ExternalId": "datadog-tenant-abc" } } on its assumeRolePolicy is a Datadog cross-account integration — a legitimate, scoped, vendor-verified pattern. Pre-0.3.6 BFS treated this identically to an unconditional wildcard trust. Same with AWS Marketplace seller roles and AWS Organizations management cross-account roles. Auditors paid the triage cost on every one.
EE 0.3.6 ships a [conditional trust — verify] suffix in the path string AND a structured conditionalHopsByPath map per finding. The “unconditional wins” semantic is conservative: if a role has ANY unconditional matching trust statement, the path is NOT flagged conditional. Only paths where EVERY contributing trust match was Condition-scoped get the triage signal.
Validation evidence
- Test counts: 249/249 in
tests/aws_iam_auditor.test.mjs(+94 new since 0.3.5). 526/526 across the targeted regression set covering IAM + compliance engine + S3/Azure/GCP plugins + coverage doc + SOC 2 renderer. Zero pre-existing tests modified. - Reviewer cycles: 5 same-session cycles with parallel general + network-security-audit lenses, 36 reviewer folds total, 0 ship-blocked. 2 post-fold CRITICALs caught and folded in the C.1.1 cycle (statement OR-ing masking unconstrained federated stmts, and all-oversize Federated input silently dropping the role record).
- Adversarial input handling: Statement index bounded at
MAX_STATEMENT_INDEX = 10_000. Federated provider value length bounded atMAX_FEDERATED_VALUE_LENGTH = 2048. Anchored ARN regex rejects substring-match attacks. Control-char + Unicode separator strip (U+2028, U+2029, ZWSP/ZWNJ/ZWJ/BOM).Effect: Denystatements explicitly excluded from trust detection. - Zero Data Exfiltration (ZDE) maintained: Sentinel tests pin that policy body content does NOT leak through
conclude(). All new fields are identifiers or integers — no policy bodies, no Condition operator values, no Resource ARNs from inside policies.
Security advisory: CE 0.1.37 floor
EE 0.3.6 inherits the CE 0.1.37 security-fix floor from the 0.3.5 window. Pre-0.1.37 CE silently bypassed the MCP auth check + license verification via the published bin shim. SOC 2 evidence generated under pre-0.1.37 CE would fail audit. Auditors must verify CE ≥ 0.1.37 in evidence artifacts. Fresh installs should use CE 0.1.38 — a docs-only patch on top of 0.1.37.
Install
npm install -g nsauditor-ai@0.1.38 @nsasoft/nsauditor-ai-ee@0.3.6
nsauditor-ai license install <KEY>
nsauditor-ai scan --host aws --plugins 030 --compliance soc2 --out evidence.json
Resources
- Enterprise overview: nsauditor.com/ai/enterprise
- Pricing & licensing: nsauditor.com/ai/pricing
- Press: press@nsasoft.us · Enterprise trials: enterprise@nsasoft.us




