
I was the first DevOps engineer at a US fintech for on-demand pay, and I led its first SOC 2. The company got the report, and then kept SOC 2 for 3 to 4 years in a row.
The first audit is where most of the pain is. The auditor asks how you do backups, who can change production, how secrets are stored, how you recover a region. You probably do most of it. You have probably never written it down, and some of it lives in one person's head.
What made the years after the first one easier was a simple rule: as far as possible, the evidence for a control should be something that already exists because of how the platform runs. Code, configuration, history. Not a screenshot someone takes once a year.
I wrote about 17 infrastructure evidence documents. Here is what most of them pointed at.
The weakest backup evidence is a list of resources that are backed up. Lists go stale the day someone adds a database.
Instead, backups were assigned by tag. AWS Backup plans selected resources by a backup plan tag, with tiers for daily backups kept two weeks, weekly kept three months, monthly kept one year or seven years, and yearly kept five years. A resource declared which plan it belonged to, in Terraform, when it was created.
The evidence for the control is then the backup plans and the tag on each resource. When the tag is set in the module, a new database gets a backup plan without anyone remembering to add it to a list.
Databases also kept their own automated backups for 35 days, which covers the most common restore: someone needs yesterday's data back.
Auditors want to know that changes to production are reviewed and approved. If infrastructure changes go through merge requests, you already have that evidence: who proposed it, who approved it, what the plan showed, when it was applied.
So capacity changes went through infrastructure-as-code merge requests, not tickets that ask someone to click. Production deploys were limited to protected CI environments, so the pipeline, not a laptop, was the only path to production.
This is the control where infrastructure as code pays off most. The history is the evidence, and nobody has to collect it.
Kubernetes secrets were kept in Git, encrypted. At first that was SOPS with AWS KMS: the secret file is encrypted with a KMS key, and only roles allowed to use the key can decrypt it. Later I moved Kubernetes secrets to Sealed Secrets, where the cluster holds the private key and Git only ever sees the sealed form.
Either way, the evidence story is the same. Secrets are versioned, reviewed like code, and never stored in plain text in the repository. The control is the encryption, and the proof is the repository.
The network evidence was a diagram with three subnet tiers and security groups that deny by default. Audit logs came from CloudTrail at the organization level, so a new account was covered without extra setup.
Access to AWS used single sign-on with MFA. I am keeping the details of access tooling out of this post on purpose. For your own program, the useful question is the same one the auditor asks: if someone had access yesterday, can you show what they did?
The disaster recovery procedure was rewritten around Terraform. The test that mattered was not a tabletop exercise. It was redeploying the Kubernetes tooling and infrastructure from code and checking that it came back.
A DR document that says "restore from backups" is evidence that someone wrote a document. A recorded redeploy from code is evidence that recovery works.
The first report took real work. The renewals took less, because most controls did not need new evidence. They needed proof that the same mechanism was still in place: the backup plans still selected by tag, the merge request history still showed reviews, the secrets were still encrypted.
When the platform changed, the evidence changed with it. When disaster recovery moved to Terraform, the procedure was updated. Because the evidence described mechanisms, not lists, these were edits, not rewrites.
If you are facing a first SOC 2 and want the infrastructure side to be something you can keep up for years, Nuno can help.
Our edge could not issue one TLS certificate because port 80 already redirected to HTTPS. How I fixed it without a proxy, and a new AWS account surprise.
A CDN forwarded the Origin header to S3 but left it out of the cache key, so the first site to load each font decided who else could use it.
AWS daily spend looked like it fell from $284 to $62 in two days. It was late billing data, and why you never report savings from the last 1 to 3 days.