Nuno
Nuno

SOC 2 Evidence an Infrastructure Team Can Actually Produce

I led a fintech's first SOC 2 and kept it for 3 to 4 years in a row. The evidence that held up came from code and AWS settings, not screenshots.
Vander Nunes
February 10, 2026
XInstagramYouTubeLinkedIn
A merge request, a backup plan and an audit log side by side, each labelled as a control

The first one is the hard one

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.

Backups: a tag, not a list

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.

Change management: the merge request history

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.

Secrets: encrypted in Git

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.

Network and access

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?

Recovery: tested from code

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.

What made renewals easier

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.

A short list to start with

  • Assign backups by tag in your modules. Show the plans and the tags.
  • Route all infrastructure changes through merge requests. The history is your change log.
  • Limit production deploys to protected CI environments.
  • Encrypt secrets in Git and describe the mechanism, not the secrets.
  • Turn on CloudTrail at the organization level.
  • Test recovery by redeploying from code, and write down the date.
  • Write evidence about how things work, not lists of what exists.

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.