← SOC 2 · ISO and SOC Certifications · All Tools
SOC 2 Evidence Helper
An auditor's evidence request list arrives written in audit language and lands on engineers who have to turn each line into a file. This decodes the common requests: what is actually being tested, what to produce, where to get it, and why it gets sent back.
Paste a line from your request list, or browse by area.
Six rules that apply to every item on this page
Give the population, not your sample. When a request says "listing" or "all", export the complete set and let the auditor choose what to test. Supplying a hand-picked subset is treated as a control weakness in itself, because it means you decided what was examined.
Every screenshot needs four things. The system it came from (URL or hostname visible), the date and time, the account that took it, and the full unfiltered view. A cropped screenshot with no timestamp is the single most common reason evidence is returned.
Prefer an export to a screenshot. Auditors ask for screenshots because they work everywhere, not because they are best. A CSV or JSON export from the console or API is reproducible, complete, and harder to dispute. Provide the export and a screenshot of the screen it came from.
Date it inside the observation period. Evidence produced after the period ended does not test the period. For a Type 2, evidence has to fall within the window, and for recurring controls it has to appear at the stated frequency across the whole window.
Redact secrets, not context. Mask passwords, tokens and keys. Do not mask usernames, timestamps, hostnames or role names -- those are the parts being tested, and over-redaction makes the evidence unverifiable.
Name the file so it can be found again. Something like 2026-03-14_okta_mfa-policy_prod.png. Auditors work through hundreds of files and unnamed screenshots generate follow-up requests.
Password or authentication settings for in-scope production applications (include screenshots of MFA in use if applicable)
#What they are actually testing
The auditor is not collecting your password policy for its own sake. They are testing that access to production is protected by an authentication mechanism that is actually enforced, and that its configuration matches what your own policy claims. Two separate assertions: the setting exists, and it applies to everyone in scope. The parenthetical about MFA is the part that carries most of the weight — password rules are weak evidence on their own, and a configured MFA policy with no exceptions is strong evidence.
Typically maps to: Security (common criteria) — logical access; authentication of users before granting access
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The authentication policy configuration for each in-scope production application and for the identity provider in front of them.
- Evidence that MFA is enforced — the policy, and the population it applies to.
- A user listing for each in-scope application showing MFA status per user, so the auditor can see there are no uncovered accounts.
- The list of any exceptions (break-glass, service accounts) with their compensating controls.
- Your written password/authentication policy, so the configuration can be compared against what you committed to.
Where to get it
Identity provider (Okta, Entra ID, Google Workspace, JumpCloud) — This is the strongest evidence and where to start. Screenshot the authentication or sign-on policy showing the factor requirement and who it applies to, then export the user list with MFA enrolment status. In Entra ID that is the Conditional Access policy plus an authentication-methods report; in Okta, the global session policy and app sign-on policy plus a user report; in Google Workspace, the 2-Step Verification enforcement setting plus the user list with the 2SV column. Show the policy is ON and in 'enforced' state, not 'report only' — a Conditional Access policy in report-only mode enforces nothing, and auditors look for this specifically.
Application-level settings (where the app has its own) — For each in-scope application, screenshot its security/authentication settings page: minimum length, complexity, lockout threshold, session timeout, and whether SSO is mandatory. If the app allows both SSO and local passwords, show that local login is disabled — otherwise the identity provider's MFA is bypassable and the whole control fails.
Cloud consoles (AWS, Azure, GCP) — AWS: the IAM credential report is the single best artefact — `aws iam generate-credential-report` then `aws iam get-credential-report --query Content --output text | base64 -d > credential-report.csv`. It lists every user, whether MFA is active, password age and key age, in one file. Also capture the account password policy: `aws iam get-account-password-policy`. Azure: the Conditional Access policy plus `Get-MgReportAuthenticationMethod...` or the authentication methods activity report. GCP: the org policy and the Cloud Identity 2SV enforcement setting.
Oracle Cloud Infrastructure (OCI) — First establish which IAM you are on, because the evidence differs: newer tenancies use identity domains, older ones the legacy IAM. With identity domains, capture the password policy and the MFA settings under the domain's security settings, plus the sign-on policies — these are OCI's equivalent of Conditional Access and carry the same question of who they actually apply to, so show the group scope rather than just that a policy exists. Export the user list from the domain with the MFA enrolment attribute. On legacy IAM, `oci iam user list --all` returns `is-mfa-activated` per user, which is the single cleanest artefact — the equivalent of the AWS credential report. Two OCI-specific traps worth pre-empting, because an auditor who knows the platform will ask: federation, where the tenancy federates to an external identity provider and the real MFA control lives there — produce the IdP evidence too, and show that local IAM users cannot bypass it; and API signing keys and auth tokens, which authenticate without any interactive factor at all, so list who holds them and how they are governed. Also capture the membership of the tenancy Administrators group, which is the first thing looked at.
Linux servers with direct access — Show that password authentication is off, so the authentication control is the key rather than the password policy: `sshd -T | grep -Ei 'passwordauthentication|permitrootlogin|pubkeyauthentication'` captures the effective running configuration rather than what the file says, which is the distinction auditors care about. Add `grep -E '^(PASS_MAX_DAYS|PASS_MIN_LEN)' /etc/login.defs` and the PAM password quality configuration if local accounts exist at all.
Databases — Frequently missed and frequently the weakest point, because a database often allows local authentication that bypasses SSO entirely. Show the authentication method configuration (for PostgreSQL, `pg_hba.conf` and `SHOW password_encryption;`) and the account listing. If humans connect directly to production databases, the auditor will follow that path.
The 'in-scope' part — Before producing anything, confirm which applications are in scope with the practitioner and produce the same evidence for every one of them. A complete set for four applications when the system description names six is an immediate follow-up request.
Why it gets sent back
- A policy document with no configuration screenshot — that shows intent, not enforcement.
- A screenshot of MFA on the auditor's own test account, or on yours. The request is about the population, not one user.
- A Conditional Access or sign-on policy left in report-only mode.
- A user list where some accounts show no MFA and the exceptions are not explained.
- Evidence for the identity provider only, when applications also accept local logins that bypass it.
- Undated screenshots, or screenshots dated after the observation period closed.
Related
What they are actually testing
A companion to the authentication-settings request, and usually sent alongside it. The auditor is testing that repeated failed logins are throttled or stopped rather than allowed to continue indefinitely, and that the configured values match what your own policy states. As always, you are measured against your own commitment, which is a good reason for the policy to describe what you actually do. One nuance worth understanding before you answer, because it changes what good evidence looks like: where you have disabled password authentication entirely, lockout thresholds are close to irrelevant — there is no password to guess. Saying that plainly, and showing the configuration that proves it, is a stronger answer than producing a lockout number for a system nobody can attempt a password against. Say it explicitly though; leaving the field blank reads as an omission.
Typically maps to: Security (common criteria) — logical access; protection against repeated unauthorised authentication attempts
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The lockout configuration per in-scope production application and for the identity provider: threshold, lockout duration, and reset or observation window.
- Your written policy, so the configuration can be compared against it.
- Evidence of what happens on lockout — automatic unlock after a period, or a verified manual unlock process.
- Where lockout does not apply because password authentication is disabled, the configuration demonstrating that.
- Any systems deliberately excluded, with the reason and what protects them instead.
Where to get it
Identity provider — Where SSO is in place this is the primary artefact and often the only one that matters, because the applications never see a password. Screenshot the lockout or sign-on policy showing threshold, duration and reset window, and show which users or groups it applies to. Entra ID's smart lockout and Okta's authentication policy both expose these as explicit numbers.
Applications with their own authentication — Per in-scope application, the security settings page showing the threshold and duration. If an application has no lockout capability at all, do not hide it — state it, and describe the compensating control, which is typically a WAF or gateway rate limit in front of it. An acknowledged limitation with a compensating control is a normal finding; a silent one is not.
Cloud consoles — AWS: the account password policy has no lockout setting, which surprises people — `aws iam get-account-password-policy` will not answer this request. The honest answer is that console access is protected by MFA and by federation, and that is what you evidence. Azure: the Entra ID smart lockout threshold and duration. GCP and OCI: the policy in the identity domain or Cloud Identity settings.
Linux servers — Only relevant if password authentication is possible at all, so lead with whether it is: `sshd -T | grep -i passwordauthentication`. If it returns `no`, that is your evidence, and it is better evidence than a lockout number. Where local passwords do exist, show the PAM faillock or tally configuration (`grep -r faillock /etc/pam.d/ /etc/security/faillock.conf`) with deny count and unlock time, plus `faillock --user <name>` to show it is actually recording. If you run fail2ban or similar at the network layer, include its jail configuration — it is a different control but it answers the same underlying risk and auditors accept it when described as such.
Databases — Often the weakest point, because databases frequently allow local authentication with no lockout whatsoever and sit behind nothing. Show the account policy where the engine supports one, and where it does not, show what restricts reachability instead — network policy, private subnet, no route from outside.
Proving it works, if asked — Some auditors ask for demonstrated behaviour rather than configuration. A short screen recording or a screenshot sequence of a test account being locked after the threshold, timestamped, settles it. Use a dedicated test account, never a real user's.
Why it gets sent back
- A policy document stating a threshold, with no configuration screenshot.
- Configured values that do not match the stated policy — either is defensible, the mismatch is not.
- Evidence for the identity provider only, while an application also accepts local logins with no lockout.
- A blank or omitted answer for a system where password login is disabled, instead of saying so and showing the configuration.
- Lockout with no unlock path, or an unlock process with no identity verification — an unlock that anyone can request by email is its own weakness.
- Undated screenshots, or ones taken after the observation period ended.
Related
What they are actually testing
The auditor needs the population before they can sample anything else. This listing is also what the joiner/leaver and access-review tests are checked against, so an incomplete one undermines several later tests rather than just this one.
Typically maps to: Security — logical access; least privilege
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- One export per in-scope system: username, full name, role or group, status, creation date, last login.
- A mapping of service and shared accounts to an owner and a purpose.
- The date the export was taken, and by whom.
Where to get it
Identity provider — Export all users with their group memberships and application assignments. This is the master list the others are reconciled against.
AWS — `aws iam list-users`, `aws iam list-roles`, and per user `aws iam list-attached-user-policies` / `list-groups-for-user`. The credential report also covers most of this in one file.
Linux — `getent passwd` for accounts and `getent group sudo wheel` (or your elevation group) for who can escalate — the second is the one that gets tested.
Databases — The role and grant listing; for PostgreSQL `\du` or a query against `pg_roles`, including which roles carry SUPERUSER.
SaaS applications — Each admin console has a user export. Include the role column — a list of names without permission levels does not answer the request.
Why it gets sent back
- Active users only, when the request said complete — disabled accounts that were never removed are exactly what is being looked for.
- No role or permission column.
- Service accounts with no named owner.
Related
What they are actually testing
Testing that somebody with authority looked at who has access, decided it was still appropriate, and acted where it was not. The review happening is half of it; the other half is that the removals it identified were actually carried out. Auditors routinely find reviews completed with findings and no follow-up.
Typically maps to: Security — logical access is periodically reviewed and modified as needed
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The review record for each occurrence in the period, at your stated frequency.
- Who performed it, who approved it, and the date — approval by someone other than the person being reviewed.
- The listing the review was performed against.
- The resulting actions, and evidence each one was completed with its date.
Where to get it
If you run reviews in a ticket or GRC system — Export the ticket with its full history: the assignment, the reviewer's comments, the sign-off, and linked remediation tickets. This is the cleanest form.
If you run reviews in a spreadsheet — Keep the file for each cycle with reviewer name and date inside it, and keep the removal tickets it generated. Store them somewhere with reliable timestamps — a file whose only date is 'last modified' is weak.
Closing the loop — For each access the review said to remove, produce the removal evidence: the ticket, and a later user listing that no longer contains the account. That before-and-after pair is the strongest version of this evidence.
Why it gets sent back
- One review when your policy says quarterly and the period was twelve months.
- A review with findings and no evidence they were remediated.
- Self-review — the system owner reviewing their own access.
- A signed summary with no underlying listing attached.
Related
What they are actually testing
Comparing two dates: when the person left, and when their access ended. The control is your stated timescale, so the test is against your own commitment rather than an external standard — which makes an unrealistic policy actively harmful.
Typically maps to: Security — access is removed when no longer required
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The complete list of leavers in the period, with termination dates — the auditor samples from it.
- Per sampled leaver: the offboarding ticket, the deactivation record from each system, and the timestamp of each.
- Evidence the account is gone now, from a current listing.
Where to get it
The leaver list — From HR, not from IT. Reconciling the HR list against your identity provider is the test, so the populations have to come from different sources.
Identity provider — The system log entry for the deactivation, with its timestamp. Okta's system log, Entra ID's audit log, Workspace's admin audit log all export this.
Anything outside SSO — The accounts most often missed: VPN, database logins, cloud console IAM users, source control, CI/CD, monitoring, on-call paging, shared password vault. Produce evidence per system, not just for the IdP.
Why it gets sent back
- An HR list and an IdP list that disagree.
- A revocation date later than your policy allows, with no explanation.
- Evidence for SSO only, while a git or database account for the same person is still active.
Related
What they are actually testing
Following individual changes end to end. The specific thing being tested is that approval happened *before* deployment and by someone other than the author — so timestamps matter as much as the existence of each artefact.
Typically maps to: Security — changes are authorised, designed, tested and approved before implementation
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The complete population of production changes in the period, so the auditor can sample.
- Per sampled change: the ticket, the pull request with reviewer and approval timestamp, the test or pipeline result, and the deployment record with its timestamp.
Where to get it
The population — The hardest part, because changes arrive through several paths. Deployment logs from the pipeline are usually the best single source. If changes can also be made outside the pipeline, that population has to be included too — and the auditor will ask how you know it is complete.
Git and code review — The PR page shows author, reviewer, approval time and merge time in one view. `git log --merges --since=... --pretty=format:'%h %ad %an %s'` gives the population; the PR link gives the detail.
Pipeline — The run record: what was built, which tests ran and passed, who triggered it, when it deployed, and to which environment.
Emergency changes — Handle these explicitly rather than hoping they are not sampled. Show the retrospective approval and that it followed your documented emergency process. An emergency path is acceptable; an undocumented one is not.
Why it gets sent back
- Approval timestamped after deployment.
- The author approving their own change.
- A change in production with no corresponding ticket or PR.
- A population that omits hotfixes or manual changes.
Related
Evidence that access to deploy to production is restricted to authorised personnel
#What they are actually testing
Testing that the change-management control cannot be bypassed. If anyone can push directly to production, every other change control is advisory.
Typically maps to: Security — segregation of duties; restricted deployment capability
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- Branch protection settings on production branches.
- The list of who can approve and merge, and who can trigger a production deployment.
- Cloud IAM showing who holds write access to production infrastructure.
- Evidence that the pipeline's own credentials are not held by individuals.
Where to get it
Source control — Screenshot branch protection: required reviews, dismiss stale approvals, restrict who can push, and — the one that gets checked — whether administrators can override.
Pipeline — The environment protection rules and the list of approvers.
Cloud — `aws iam list-entities-for-policy` for the production deployment role, or the equivalent role assignment listing, showing who can assume it.
Standing access — If engineers hold permanent production credentials, expect scrutiny. Time-bound elevation with an approval trail is far easier to evidence than explaining why it is not needed.
Why it gets sent back
- Branch protection with an admin override that several people hold.
- A shared deployment account whose credentials are in a wiki.
- A list of authorised deployers that does not match the actual permissions.
Related
Vulnerability scan results and evidence of remediation within defined timeframes
#What they are actually testing
Two things: that scanning happens at your stated frequency across the whole estate, and that findings are closed within your own stated SLA. As with offboarding, you are measured against your policy — a policy promising 7 days for criticals when you achieve 30 creates exceptions that a 30-day policy would not.
Typically maps to: Security — vulnerabilities are identified, evaluated and remediated
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- Scan reports across the period at the stated frequency, showing coverage.
- The findings register with severity, discovery date, and closure date.
- Remediation tickets for a sample.
- Documented, approved risk acceptances for anything open past its SLA.
Where to get it
Scanners — Export the scan history showing dates and target counts — coverage is tested as well as findings. A scan of 40 hosts when the estate has 60 is a gap.
Container and dependency scanning — Pipeline scan output per build, plus how the gate behaves on a finding.
Cloud posture — Security Hub, Defender for Cloud or SCC findings with their timeline.
Proving the timeline — The strongest artefact is a report with discovery date, severity and closure date in one row per finding — it demonstrates the SLA directly rather than requiring the auditor to cross-reference.
Why it gets sent back
- A single recent scan for a twelve-month period.
- Scans covering part of the estate.
- Open criticals past SLA with no risk acceptance.
- A clean report with no evidence of what was scanned.
Related
What they are actually testing
That patching is a running process rather than an occasional effort, and that it covers the whole in-scope estate including anything outside the automation.
Typically maps to: Security — system components are maintained and updated
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- Patch status per host across the period.
- Configuration showing automatic security updates enabled, where claimed.
- The reboot record for kernel updates.
- Exceptions with their justification.
Where to get it
Linux — `grep -E 'Unattended-Upgrade|APT::Periodic' -r /etc/apt/apt.conf.d/` or `systemctl is-enabled dnf-automatic.timer`, plus `/var/log/dpkg.log` or `dnf history` as proof updates actually applied. `uptime` alongside it — a kernel patched and never booted is not applied.
Fleet-wide — Patch manager or configuration management compliance report, which covers population and status in one artefact.
Containers — Base image rebuild cadence and the registry scan history.
Why it gets sent back
- Configuration showing automation is enabled, with no evidence it ran.
- Hosts absent from the report that appear in the asset list.
- Long uptimes on hosts whose kernel was patched.
Related
What they are actually testing
Not that backups are configured — that they ran, that somebody would know if one did not, and that failures were acted on. A period with zero recorded failures often means nobody is watching rather than that nothing failed, and auditors read it that way.
Typically maps to: Availability — data is backed up and recoverable
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- Backup job history across the period, showing successes and failures.
- The alerting configuration for failures.
- For a sampled failure, the ticket and its resolution.
- The retention configuration, against your stated policy.
Where to get it
Job history — Export from the backup tool or cloud backup service covering the full period, not a screenshot of this week.
Home-grown scripts — The log plus the cron or timer definition, plus how a failure raises an alert. A script that fails silently is the finding, not the evidence.
Snapshots — The snapshot listing with timestamps and the lifecycle policy.
Failure handling — If nothing failed, say so and show the alerting would have fired — a test alert, or a failure from outside the period.
Why it gets sent back
- A screenshot of a backup dashboard showing 'last run: success'.
- No failures and no evidence that failures are detectable.
- A failure with no ticket.
Related
What they are actually testing
The control is recoverability, and the only evidence of recoverability is a restore. This is the request organisations most often cannot satisfy, because backups are monitored and restores are not tested.
Typically maps to: Availability — recovery procedures are tested
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The restore test record: date, what was restored, to where, by whom.
- How the restored data was validated — this is the part usually missing.
- The elapsed time, compared against your stated recovery objective.
- Any issues found and what was done about them.
Where to get it
Automated tests — The job log per run, including the validation step — a row count, a checksum, a query returning an expected value. 'Restore completed' is not validation.
Manual tests — A short written record is enough, provided it names the date, the performer, what was restored, how it was checked and how long it took. Make it a template so each test produces the same record.
DR exercises — The exercise plan, the outcome, and the actions arising — which also serves ISO 22301 if you hold it.
Why it gets sent back
- No restore test in the period.
- A restore with no validation of the restored data.
- A test of a non-production system presented as covering production.
Related
What they are actually testing
That monitoring exists, that alerts reach a human, and that the human did something. The third is where evidence is usually thin — a dashboard is not a control, and an alert nobody acted on is worse than no alert.
Typically maps to: Security — the system is monitored and anomalies are evaluated
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The alert rules or detection configuration in scope.
- The routing: who is notified, by what channel, and the escalation if unanswered.
- A sample of alerts from the period with the response recorded.
- Evidence that log collection itself is monitored.
Where to get it
Alert configuration — Export the rule definitions rather than screenshotting a dashboard — rules are the control, dashboards are a view.
Routing — The on-call schedule and escalation policy from the paging tool, covering the period.
Response — For sampled alerts, the acknowledgement time and the resulting ticket or note. This closes the loop that the auditor is looking for.
Log integrity — That logs ship off the host and that the destination is append-only or access-controlled.
Why it gets sent back
- Dashboard screenshots with no alert rules.
- Alerts with no evidence anyone responded.
- Alerting configured to an unmonitored mailbox.
Related
Listing of security incidents during the period and, for a sample, evidence of handling
#What they are actually testing
That the incident process is used, not that no incidents occurred. Declaring zero incidents over twelve months invites more scrutiny than declaring several handled well.
Typically maps to: Security — incidents are identified, responded to and resolved
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The incident register for the period, with severity and dates.
- Per sampled incident: detection, triage, actions taken, resolution, and follow-up.
- Evidence of customer or regulator notification where your policy required it.
- The incident response procedure itself.
Where to get it
The register — Export from the ticketing or incident tool with timestamps intact.
Per incident — The timeline is the evidence: detected at, acknowledged at, mitigated at, resolved at, with who did what.
Follow-up — The post-incident review and the resulting actions with owners — see /post-incident-follow-up. An incident closed with no action is a reasonable outcome only if the review says why.
If there were none — Say so explicitly, and show the process is live: a tabletop exercise, or operational incidents handled through the same process.
Why it gets sent back
- Zero incidents with no explanation of how you would know.
- Incidents with no timeline.
- A procedure document with no incidents run through it.
Related
What they are actually testing
That you know who processes your data, that somebody assessed the risk, and that the assessment is refreshed. Obtaining a vendor's SOC 2 report is not the control — reading it is, including its exceptions and the complementary controls it expects of you.
Typically maps to: Security — vendors and business partners are assessed and monitored
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The vendor inventory with what each one does and what data they touch.
- Risk classification per vendor.
- Assurance evidence for the significant ones, with a record that it was reviewed.
- Contracts with the relevant security and data protection terms.
Where to get it
The inventory — Reconcile the list against what is actually paid for — finance's records find vendors that IT's list does not.
Review record — A short note per vendor: who read the report, when, what the exceptions were, and whether the complementary user entity controls apply to you. A stored PDF with no note is a filed document, not a review.
Ongoing — Evidence that reports are refreshed as they expire, and that a vendor with no current report was escalated.
Why it gets sent back
- A vendor list with no risk assessment.
- Stored SOC 2 reports with no evidence anyone read them.
- An expired report accepted without comment.
Related
System configuration standard documents or "system hardening procedure documentation" for all in-scope system types (include router, firewall, servers — web, database, application, POS servers, etc.)
#What they are actually testing
This request is about the documents, not about any individual machine. The auditor is testing two things. First coverage: that a configuration standard exists for every system type in scope, which they will check by laying your list of standards against your asset inventory and system description — a type that appears in the inventory with no corresponding standard is the finding, and the enumeration in the request (router, firewall, web, database, application, POS) is a prompt to make you go looking rather than an exhaustive list. Second, that each standard is a controlled document: owned, approved, versioned, dated and reviewed, rather than a wiki page somebody wrote once. Note the wording. "System configuration standards" and the mention of POS servers is PCI DSS vocabulary rather than SOC 2 vocabulary, so a request phrased this way is often a checklist being reused across frameworks, or a combined assessment. It is worth asking which framework the request belongs to before you answer it, because PCI expectations around configuration standards are more prescriptive than SOC 2's — and if you have no POS estate at all, say so explicitly rather than leaving a silent gap in the coverage table.
Typically maps to: Security (common criteria) — baseline configurations are defined and maintained for system components
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The list of in-scope system types, taken from the asset inventory and the system description — this is what coverage is measured against, so it comes first.
- One configuration or hardening standard per type, as a document you can hand over.
- A coverage table mapping each system type, and each asset, to the standard that governs it. This single artefact answers most of the request.
- Approval evidence per standard: author, approver, version, effective date.
- Evidence each standard was reviewed within your stated cycle during the period.
- The recognised source each one derives from, and where you departed from it.
- Documented, approved deviations — the exceptions that exist in reality.
Where to get it
Start from the inventory, not from the documents — Produce the list of in-scope system types first and get agreement on it. Writing standards before the scope is settled is how you end up with five polished documents and a sixth type nobody covered. The /infrastructure-audit output is usually the right source, and the same reconciled asset register serves both purposes.
If the hardening lives in code and not in a document — This is the normal situation for an engineering team, and it is a good position rather than a gap. Your configuration management role, image build definition or Terraform module is the de facto standard — so generate the document from it: what the role enforces, why, and which deviations are parameterised. Do not write an aspirational document separately from the code. An auditor may sample a running host and compare it against the standard, and a document that disagrees with reality is worse evidence than no document, because it turns a coverage gap into a control failure.
Derive from a recognised source and say which — CIS Benchmarks, vendor hardening guides, or DISA STIGs. Name the source and version in the document. Two things auditors look for: that you tailored it rather than attaching the PDF unchanged, and that the tailoring decisions were made deliberately — a recorded 'not applicable, we do not run this service' is a perfectly good answer.
Routers and switches — Management plane access and authentication, disabled unused services and ports, SNMP community and version, logging destination, NTP, firmware baseline, and config backup. Evidence the running configuration matches: a diff of the live config against the intended one is strong, and easy to automate.
Firewalls — The default-deny posture, rule review cadence and last review date, admin access and MFA, logging, and firmware. See /network-and-firewall-configuration — the rule set itself belongs to a different request, this one is about the standard the rule set is built to.
Servers, by role — Web, application, database and any others each need their own standard, because what is hardened differs: a web server standard covers TLS configuration, headers and disabled modules; a database standard covers authentication method, network binding, encryption and privileged roles. A single 'server hardening' document covering all roles is the most common way this request fails. The shared base — accounts, logging, time, patching, minimal install — can sit in one common standard with role-specific ones layered on it, which is both less work and easier to defend. See /os-installation-and-hardening.
POS and payment terminals, if you have them — Usually vendor-supplied and vendor-maintained, which does not remove them from the coverage table. Document the vendor's hardening guidance you follow, your deployment configuration, how updates reach them, and the split of responsibilities with the vendor. If you have no POS estate, put a line in the table saying so.
Cloud, virtual and container images — Frequently missed because they do not feel like 'system types'. Base images, machine images, Kubernetes node configuration and the cloud account baseline each need a standard. For images, the build definition plus the scan gate is the document.
Making them controlled documents — Whatever you use — a document system, or Markdown in a repository. A repo is often the better answer: the commit history is the version control and the review evidence, pull request approvals are the approval record, and it sits next to the code that implements it. Either way each document needs an owner, a version, an effective date and a recorded review inside the period.
Why it gets sent back
- One 'server hardening' document when the inventory distinguishes web, database and application servers.
- Standards covering servers but not network devices, or the reverse.
- A CIS Benchmark PDF attached unchanged, with no adoption or tailoring decision.
- Documents with no version, no approver or no date.
- No review recorded during the period when the policy says annual.
- A standard that does not match the running configuration of a sampled host.
- Deviations that exist on systems but appear nowhere in the documents.
- A system type in the asset inventory that no standard covers, and no statement that it was consciously excluded.
Related
/system-configuration-standards · /os-installation-and-hardening · /network-and-firewall-configuration · /infrastructure-audit · /infrastructure-as-code
What they are actually testing
That systems are built to a defined standard rather than individually, and that drift from it is detected. Configuration management makes this straightforward; hand-built servers make it painful.
Typically maps to: Security — infrastructure is configured to prevent unauthorised access
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The baseline itself — the configuration code or hardening standard.
- Evidence it is applied across the in-scope estate.
- Drift or compliance reporting across the period.
- Firewall and network rules for in-scope environments.
Where to get it
Configuration management — A check-mode or dry-run report across the fleet is the ideal artefact: it shows both the standard and the conformance in one output.
Cloud — Config rules, policy compliance dashboards, or the equivalent posture report, exported with dates.
Network — Security group and firewall rule exports, plus evidence they are reviewed — see /network-and-firewall-configuration.
Encryption — That storage encryption and TLS are enforced: the setting, and a listing showing no unencrypted resources.
Why it gets sent back
- A hardening document with no evidence of application.
- Compliance reporting covering some hosts.
- Firewall rules with no review record.
Related
/os-installation-and-hardening · /network-and-firewall-configuration
What they are actually testing
Simple to satisfy and frequently failed on completeness. The test is that everyone in scope completed it, including joiners during the period and contractors if your policy covers them.
Typically maps to: Security — personnel are made aware of their responsibilities
Indicative only — your own control matrix and agreed scope decide this.
What to produce
- The completion report with names and dates.
- The employee population for the period, to reconcile against.
- The training content or its outline.
- Follow-up evidence for non-completers.
Where to get it
Platform export — Completion report per person per course, with dates.
Reconciliation — Against the HR list including leavers and joiners — the reconciliation is the evidence, not the raw report.
Joiners — That training happened within the window your policy states after start date.
Why it gets sent back
- A completion percentage with no names.
- Gaps with no follow-up.
- Joiners late in the period with no training and no explanation.
A note on what this is
This is a preparation aid written from the perspective of the people who operate the systems being audited. It is not a control framework, not authoritative, and not a substitute for your practitioner. The criteria mappings are orientation; the actual scope, control objectives and evidence expectations are agreed with your audit firm, and two organisations answer the same request differently. See SOC 2 for what the examination is, and the AICPA SOC suite for the authoritative definitions.
API
The same library as JSON, for scripting:
curl -s 'https://devops.majbase.com/soc2-evidence/api?q=restore+test' curl -s 'https://devops.majbase.com/soc2-evidence/api/auth-settings-prod-apps'