SOC 2 Type II

The PDF your auditor reads. Reproducible by the hash.

Type II audits require 6–12 months of continuous evidence — multiple samples per control, every month, all stitched together when the CPA arrives. Most tools panic-assemble that package the week of the audit. CME materialises samples on every audit run and surfaces gaps before the auditor finds them.

Sample picker
Deterministic per-control sample selection across the period
  • ›3–12 samples per control (AICPA minimum or stricter)
  • ›Re-export produces byte-identical samples
  • ›Stratified across the observation window
Gap analysis
Surface missing-evidence windows before the auditor does
  • ›Critical / warning / info severity per gap
  • ›Per-control × per-window coverage matrix
  • ›Resolution trail (auditor sees you fixed it)
Hashed package
Auditor can re-verify the PDF hasn't been edited
  • ›SHA-256 terminal-hash on every export
  • ›Per-sample hash chain to source audit_trail.jsonl
  • ›Auditor re-hashes; mismatch = tamper signal
CPA-ready by construction. The export matches the structure A-LIGN / Schellman / Insight Assurance reviewers expect — executive summary, per-control sample table, gap analysis, hashed audit-trail index. No bespoke formatting at audit time.
Employees

Did everyone sign the AUP? Did everyone train?

CC1.4 (control environment, hiring, training) and CC1.5 (sanctions for misconduct) are the criteria auditors ask about by name. The answer used to live in a spreadsheet. CME brings it inside the product — every active employee, every AUP signature against the CURRENT published version, every training completion within the rolling annual window.

Roster as evidence
Hired / on-leave / terminated with dates
  • ›Manual entry today; HRIS sync (Rippling / Gusto / BambooHR / Workday / SCIM) next
  • ›Termination auto-stamps the date — auditor reads CC1.5
  • ›Soft-delete: terminated rows preserved for the audit window
AUP signature tracking
Tied to policy version — republish resets the slate
  • ›Append-only attestations with method (clickwrap / DocuSign / API)
  • ›Body-hash captured at sign time — auditor verifies what was signed
  • ›Re-publishing a policy invalidates prior signatures
Training completion
Rolling 365-day window per training module
  • ›training_key + title — run quarterly modules without schema churn
  • ›Most-recent completion within window counts
  • ›% completed rollup feeds Readiness + Evidence catalog
Version-aware signatures. Re-publish the AUP because the content changed, and the rollup re-resets — every employee signs the new version within their onboarding window. The audit trail shows both the new + the prior signature so the auditor sees the lifecycle, not just the latest state.
MDM

Are your laptops encrypted? Now answerable.

CC6.7 — endpoint protection — is one of the criteria auditors push hardest on. Connect Jamf, Kandji, or Intune; CME pulls the fleet snapshot, computes per-OS encryption + screen-lock + firewall + check-in compliance, and surfaces the rollup on every screen (Readiness, Evidence catalog, Auditor packet).

Three vendors, one shape
Jamf Pro, Kandji, Microsoft Intune
  • ›OAuth / Bearer / Azure-AD credential flows
  • ›Fernet-encrypted at rest with rotating keys
  • ›Self-hosted-Jamf works through the same code path
Per-OS posture rollup
% encrypted / screen-lock / firewall per OS family
  • ›macOS / Windows / Linux / iOS / iPadOS / Android
  • ›Tristate: vendor-reports-yes / no / unknown
  • ›Stale check-in window is auditor-tunable
Auditor-ready
Feeds Readiness + Evidence catalog + Packet
  • ›CC6.7 + ISO A.7.10 + NIST SC-28 mapped per signal
  • ›Snapshot refreshes on every sync, drops stale rows
  • ›Re-issuable in the packet at any time
Mixed fleet? Connect more than one vendor at once. The customer- facing rollup combines all connections — 94% of your 117 devices encrypted; the 7 exceptions surface as individual rows for follow-up.
Evidence catalog

See exactly what we collect. And how fresh it is.

Every buyer evaluating compliance tooling asks the same question: “what do you actually pull from my environment?” CME answers with a list — fifty-plus evidence types across AWS, GitHub, and the CME platform, each mapped to specific framework controls, each with a freshness badge so you can see at a glance which pieces are current for your tenant.

50+ evidence types
Curated, framework-mapped, version-controlled
  • ›29 AWS collectors (IAM, S3, EC2, RDS, KMS, CloudTrail, GuardDuty, etc.)
  • ›11 GitHub collectors (2FA, branch protection, audit log, etc.)
  • ›10 platform attestations (policies, risks, Type II, POAM)
Per-tenant freshness
Fresh / stale / missing badges per entry
  • ›Fresh = last collected within 30 days
  • ›Stale = 30–90 days; CPA-visible warning
  • ›Missing = never collected or > 90 days
Framework citations on every row
SOC 2 / ISO 27001 / NIST SP 800-53 mapped per entry
  • ›165 framework citations across the catalog
  • ›Filter by criterion — "show me everything for CC6"
  • ›Mappings curated, never LLM-generated
Why this matters to the CPA. The auditor doesn't trust “we collect everything.” They want the inventory + the timestamps. CME hands them both as a single screen they can verify line by line — the same view the customer sees on /evidence.
POAM

Plan of Action and Milestones. Not a spreadsheet.

Every CPA asks the same question: “how are you tracking remediation?” If the answer is a Google Sheet or a Jira board the customer happens to use, the auditor has to chase context across three tools. CME ships POAM as a first-class product — every finding or risk gets an owner, a priority, a due date, and an append-only comment trail. No Jira required.

Assign from any finding or risk
One click → POAM row with priority pre-derived
  • ›POST /v1/remediations/from-finding/{id}
  • ›Priority auto-set from severity (critical→P1, etc.)
  • ›Title + summary denormalised so renames don't break the trail
Owner + due date + status
The fields every project tracker has, scoped to compliance
  • ›Open / in-progress / blocked / done / cancelled
  • ›Auto-stamp completed_at on status=done
  • ›Overdue badge: items past due never silently slip
Auditor-grade history
Append-only comments the CPA reads as the running record
  • ›No edit / delete on comments — by design
  • ›Author + timestamp on every entry
  • ›Exports into the auditor packet (06_poam/poam.csv)
You can still pipe to Jira. The existing Jira integration (Track integrations) keeps working — POAM rows can mirror to Jira issues. The difference: the customer doesn't have to choose between Jira and CME for compliance evidence. CME is the system of record; Jira is the engineering work-tracker.
Access reviews

Quarterly access reviews. Attested, not asserted.

Every SOC 2 engagement opens with the same CC6.3 ask: “show me the last quarterly access review.” Most prep tools answer with a spreadsheet someone exported on a Friday afternoon. CME ships campaigns as a first-class product — scoped by AWS / GitHub / app / MDM, one attestation per grant (keep / reduce / revoke), timestamped per reviewer, exported as CSV the CPA can re-import as workpaper.

One campaign per scope
AWS IAM, GitHub org, application, MDM enrollment
  • ›Display ID (AR-NNNN) is auditor-citable for life
  • ›Due date drives the overdue derivation — no manual flag
  • ›Cancelled is sticky: closed campaigns never reopen
Per-grant attestation
Keep / reduce / revoke with reviewer + timestamp
  • ›Pending → keep/reduce/revoke (one click per row)
  • ›reviewed_at + reviewed_by recorded on every decision
  • ›Notes field captures the reasoning for the workpaper
Auditor packet integration
CC6.3 + ISO A.5.15/A.5.18 + NIST AC-2/AC-6
  • ›CSV export per campaign — drop into the CPA's workpaper
  • ›Feeds Evidence catalog freshness on platform.access_reviews.campaigns
  • ›Recompute campaign state derives overdue from due_date
Why this matters to the CPA. The control isn't “we limit access” — it's “someone in authority reviewed the grants and attested.” CME records the attestation per row, with a reviewer identity and a timestamp the auditor can cross-reference against the HRIS roster. The whole campaign exports as one CSV, citable by AR-NNNN.
Vendor questionnaires

CAIQ, SIG, cyber insurance. Evidence already pinned.

The procurement-side ask the customer hears every other deal: “please complete our security questionnaire by Friday.” Prep tooling mostly answers with “here’s a folder, fill it yourself.” CME flips it: import the prospect’s CSV, the system pins the matching evidence from your existing platform data — policies, audit findings, MDM rollups, access-review CSVs — next to each question. You write the answer; the citations are already attached.

LLM-grounded, not auto-drafted
Bedrock picks the evidence; you write the answer
  • ›Tool-gated outputs: model can only cite real catalog IDs
  • ›Pydantic-validated JSON; invented citations are dropped
  • ›Confidence floor strips noisy low-confidence suggestions
Closed-set evidence index
50+ catalog entries × your tenant freshness
  • ›Suggester sees policies + findings + MDM + Type II + access reviews
  • ›Each citation carries last-collected timestamp
  • ›Framework citations (SOC 2 / ISO / NIST) on every suggested cite
Approval trail for the auditor
Reviewer identity + timestamp per question
  • ›Append-only approval record — workpaper-grade
  • ›VQ-NNNN display ID citable for life
  • ›CSV export drops back into the prospect's form
Why we don't auto-draft the answer text. A fabricated answer in a procurement contract carries legal risk that wipes out the time saved. CME's job is to surface the right evidence + framework citations; your counsel signs the answer. The CSV deliverable shows both the answer and the citations side by side, so the prospect's security team verifies, not just trusts.
Auditor packet

One zip. Everything the CPA reviews. Tamper-evident.

The week of the audit, every prep tool ships a different grab-bag — exports from Vanta, screenshots from Notion, spreadsheets from someone's laptop. CME builds one zip from current tenant data, with a SHA-256 chain across every artefact. The CPA re-runs the chain locally to confirm nothing was altered after export.

Composed, not authored
Built from current data — no per-engagement template
  • ›Per-framework readiness PDF (score + blocker list)
  • ›Every published policy (markdown + body hash)
  • ›Risk register heat-map + every entry + review trail
Type II + findings included
The Track A export is wrapped in alongside everything else
  • ›Per-cycle Type II PDFs (existing terminal-hash chain preserved)
  • ›Open findings CSV (severity-sorted, framework-aliased)
  • ›Auditor receives ONE bundle, not a folder of zips
Tamper-evident chain
SHA-256 chain stitches every artefact
  • ›Per-artefact hash printed in HASHES.txt
  • ›Terminal hash on cover sheet — auditor re-runs locally
  • ›Re-issue at any time; chain proves nothing slipped in
Re-issue without panic. Fixed a policy mid-engagement? Re-export. The new packet picks up the latest body + a fresh terminal hash. The CPA verifies the new chain; the prior chain remains independently verifiable as a historical artefact.
Risk register

The artefact your auditor reads first. Not in a spreadsheet.

Auditors review the risk register independently of the Risk Management policy. The policy says how you assess; the register IS the assessment — live list of identified risks, treatment, owner, review history. CME ships it as a first-class product, with the 5×5 matrix from ISO/IEC 27005:2022 + NIST SP 800-30r1 wired in.

Inherent + residual rating
Likelihood × impact on the 5×5 heat map
  • ›Score 1–25 → Low / Moderate / High / Critical
  • ›Residual ≤ inherent enforced at the DB layer
  • ›Heat-map view sized for the CPA presentation deck
Treatment + milestones
Mitigate / accept / transfer / avoid + owner + due date
  • ›Milestone tracker with owner + due date + status
  • ›Auto-bump risk to in-treatment on first milestone
  • ›Linkable to findings, policies, framework citations
Review attestation trail
Append-only review history with rating snapshots
  • ›Cadence derived from residual rating (P1M / P3M / P6M / P1Y)
  • ›Each review snapshots the pre-state for delta visibility
  • ›Overdue badge: review past due never silently slips
Methodology you can cite. Classifications, cadences, and snapshot semantics match the Risk Management policy template in our policy library — the customer's leadership reads one consistent methodology in the policy AND in the register. No silent drift.
Readiness

One number, refreshed live. How close are you?

Every SOC 2 buyer asks the same question on the first call — “how close are we today?” Most tools answer with a checklist. We answer with a score, composed live from the audit findings you actually have, the policies you've actually published, and the Type II evidence gaps the auditor is going to flag. No predictive wizardry, no marketing math — visible evidence, scored consistently.

The headline number
Auditor-readable, executive-readable, one screen
  • ›Big % across every criterion in the framework
  • ›Counts: passing · warning · blocking · no evidence
  • ›Updates the moment a finding or policy changes
The blocker list
Fix-these-first surface, sorted worst-first
  • ›Open critical / high findings + missing policies + Type II gaps
  • ›Each row drills to the finding that triggered it
  • ›Auditor's CPA can read this directly during review
Per-framework
SOC 2 today, ISO / HIPAA / NIST tomorrow — same lens
  • ›Denominator from the corpus (33 SOC 2 CC criteria)
  • ›Honest about no-evidence vs passing (different things)
  • ›Score formula documented in the UI itself
Honest about what this is. The score is the visible-evidence picture, not a prediction of auditor sign-off. Two distinct tenants with the same score can land at different audit outcomes — the score does not weight CC1.4 (control environment) the way an auditor weights it. What it does is keep the customer and the CPA looking at the same current picture, every day until the audit.
Microsoft 365 audit

Who has admin in your tenant? Answerable now.

CC6.1 (authorization — privileged access) is the criterion every auditor cites for M365. CME connects to Microsoft Entra via a read-only app registration, pulls the user roster, identifies admins by directory-role template ID, and reads the MFA-registration report. One screen tells you how many admins exist, what roles they hold, and whether they have MFA registered.

App-only auth, not delegated
Client-credentials OAuth, no user impersonation
  • ›Customer registers an app with read-only Graph scopes
  • ›Global admin grants consent once via Microsoft's flow
  • ›Client secret Fernet-encrypted at rest with rotation
Admin enumeration that auditors trust
13 curated directory-role template IDs
  • ›Global / Privileged Role / Privileged Auth / Security / Conditional Access...
  • ›Template IDs (stable across tenants), not localized names
  • ›Full role list per user surfaces on the workpaper
MFA coverage with explicit unknowns
Tristate: registered / capable-only / unknown
  • ›/reports/credentialUserRegistrationDetails parsed per user
  • ›Tenants without Entra P1/P2 surface as 'unknown' (gap visible)
  • ›Admin MFA % is the headline metric — never hidden in averages
Why an Azure app registration, not delegated SSO? App-only credentials let CME read evidence on a schedule without a human-in-the-loop. The customer’s global admin grants consent once and revokes any time; CME never holds a user’s session. Same pattern Microsoft recommends for compliance + SIEM integrations.
Google Workspace audit

Workspace admins + 2SV. One screen, no spreadsheet.

CME connects to Google Workspace via a service account with domain-wide delegation, pulls every user from the Admin SDK Directory API, identifies admins by pre-built directory-role membership, and reads 2-Step Verification enrollment + enforcement directly off each user. One screen tells you how many admins exist, what roles they hold, and whether they have 2SV enforced.

Service account, not delegated SSO
JWT-bearer flow, no user impersonation prompt
  • ›Customer creates GCP service account, downloads JSON key
  • ›Workspace Admin Console wires domain-wide delegation
  • ›JSON key Fernet-encrypted at rest; rotation supported
Pre-built admin role enumeration
8 curated Google Workspace admin role names
  • ›Super / User Mgmt / Help Desk / Groups / Mobile / ...
  • ›Custom roles surface on the workpaper but don't flip is_admin
  • ›Native isAdmin / isDelegatedAdmin flags also captured
2SV that distinguishes enrolled from enforced
Tristate: enrolled / enforced / unknown
  • ›isEnrolledIn2Sv + isEnforcedIn2Sv per user
  • ›Admin 2SV % is the headline (CC6.1 strong-auth signal)
  • ›Missing flag → 'unknown' bucket, never silent false
Why service account + domain-wide delegation? Admin SDK reads run on a schedule without a human in the loop. The customer's super-admin grants the delegation once and revokes any time; CME never holds a user's OAuth session. Same pattern Google recommends for compliance + SIEM integrations.
GitHub audit

Audit your source-control posture. Not just your cloud.

Change management and access control don't stop at the AWS console. Connect your GitHub organisation — via our GitHub App (auditable on GitHub's side) or a fine-grained PAT — and the agent sweeps branch protection, signed commits, secret scanning, Dependabot, deploy keys, Actions permissions, the org audit log, 2FA enforcement, and outside collaborators. Every tool result is canonical and reproducible.

Two auth flows
GitHub App (preferred) or fine-grained PAT — your call
  • ›App: short-lived installation tokens, auditable on GitHub
  • ›PAT: fastest setup, works on app-restricted orgs and GHE
  • ›Credentials encrypted at rest with rotating Fernet keys
12 deterministic tools
Source-control evidence the auditor recognises
  • ›Branch protection, signed commits, PR review requirements
  • ›Secret scanning + push protection + open-alert counts
  • ›Dependabot + Actions permissions + audit log + 2FA + outside collaborators
Framework-mapped
Curated mappings to SOC 2, ISO 27001, NIST
  • ›Sorted output — re-runs produce byte-identical samples
  • ›Per-tool citations land in the auditor PDF
  • ›Type II sample picker treats GitHub findings like AWS
Self-hosted GitHub Enterprise works too. Point the connection at your GHE host (https://ghe.example.com/api/v3) and every tool routes through the same code path. No separate code path, no two-product surface.
Policy library

Auditor-ready policies, version-controlled. Not LLM-generated.

Human-curated policy templates from MIT-licensed open compliance projects (Comply and JupiterOne) — full document control, definitions, RACI, procedures, retention, training, revision history. The seed pack covers SOC 2 and ISO 27001 essentials; customers extend the library in place. Clone, edit, route for approval, publish. Every published version is body-hashed so the auditor can verify the document they're reading is the one you attested to.

Open-source templates
Comply + JupiterOne, framework-tagged out of the box
  • ›MIT-licensed starters — access control, IR, change mgmt, BCDR
  • ›Pre-mapped to SOC 2, ISO 27001, HIPAA, PCI
  • ›Original attribution preserved on every clone
Version control
Every save is a new version, every version is hashed
  • ›Predecessor chain (the auditor sees the edit history)
  • ›SHA-256 body hash per version — tamper-evident
  • ›Diffable history without leaving the workbench
Approval workflow
Separation of duties enforced — editor cannot approve
  • ›Draft → Review → Approved → Published lifecycle
  • ›Server-side check across the version's edit history
  • ›Approval trail captured for the audit narrative
Why not AI-generated policies? Auditors recognise LLM boilerplate on sight and dock the engagement for not reflecting how the company actually operates. We give you a curated starting point, you edit it to fit your environment, and the hash chain proves nothing slipped in after approval.
Privacy by construction

The LLM never sees your users. Your report still names them.

Customer identifiers — names, emails, IAM ARNs — are tokenized before they reach the model and detokenized on the way to your report. The LLM sees [CME-EMAIL-a1b2c3]; your team reads jane@helixcloud.com and can act on it.

STEP 1
Tokenize before send
Email jane@helixcloud.com becomes [CME-EMAIL-a1b2c3] — a stable, opaque token. The LLM only ever sees the token. Same value → same token across every step of the audit, so the agent can reason about “the same user” without ever holding the address.
STEP 2
Vault the mapping
The forward + reverse mapping lives tenant-scoped in your Redis vault, with a 24-hour TTL. Token a1b2c3 in tenant X means nothing in tenant Y — cross-tenant leakage is structurally impossible, not policy- promised.
STEP 3
Detokenize before save
When the agent emits a finding, we replace the token with the original value before it's written to your audit. Your team reads jane@helixcloud.com and can act on it. Credentials (access keys, bearer tokens, PAN, SSN) are blocked, not tokenized — they never reach the model under any circumstance.
Why it matters: the tokenization vault is tenant-scoped with a 24-hour TTL. The model never holds a raw identifier. Your auditors still get findings with real names, real emails, real ARNs they can route to a human owner the same day.