Last spring, a Fortune 500 prospect asked for our SOC 2 Type II report during the final week of a contract negotiation. We didn't have one ready. That single missing document stalled a seven-figure deal for eight months while we scrambled to formalize controls we'd been running informally for years. If you're operating CDN infrastructure without a verified trust framework, you aren't just risking security gaps — you're actively losing enterprise business.
What Auditors Actually Want to See Behind Your Edge
When I first went through a SOC 2 audit for a global edge network back in 2018, I assumed auditors would be impressed by our raw technical controls. We had custom WAF rules, tight TLS configurations, and solid DDoS mitigation. It didn't matter. The auditor didn't care how clever our tech was; they cared whether we could prove it worked consistently over time. That's the core mindset shift for any Mapping CDN Security Controls to ISO 27001: A Practical Implementation Guide effort, and SOC 2 is no different. You're not proving you have security — you're proving you have repeatable, documented, and monitored security.
For CDNs, the Trust Services Criteria (TSC) map directly to edge realities. Security (CC series) is always required, but most CDN SOC 2 reports also include Availability and Confidentiality. Availability means proving your PoPs stay up and failover works as documented. Confidentiality means showing how you handle customer origin data and cached content. I've seen teams fail here because they treat cache purging as a feature, not a control. An auditor will ask: "Who can purge what, how is it logged, and how do you know the log wasn't tampered with?" If you can't answer that in under a minute with evidence, you've got work to do.
Auditors lean heavily on the underlying HTTP behavior too. They'll want to see that your cache-control, logging, and access decisions align with standards described in the HTTP Working Group Specifications and that your edge security headers follow current best practices from sources like web.dev Articles. You can't just say "we set secure headers." You need version-controlled configuration, change tickets, and logs showing those headers were actually served to clients throughout the audit period.
#!/bin/bash
# nightly_soc2_evidence_collector.sh - Pulls CDN control evidence for SOC 2
# Run via cron with immutable logging to S3/GCS
AUDIT_DATE=$(date -u +%Y-%m-%d)
EVIDENCE_BUCKET="s3://soc2-evidence-cdn-prod"
echo "[*] Collecting evidence for $AUDIT_DATE"
# 1. WAF and edge access logs (CC6.1, CC6.6)
aws s3 sync s3://cdn-edge-logs/waf/ ./evidence/waf/ --exclude "*" --include "*$AUDIT_DATE*"
sha256sum ./evidence/waf/* > ./evidence/waf/manifest.sha256
# 2. Privileged access to CDN control plane (CC6.2)
# Export IAM/CMS access logs for users with purge/config rights
gcloud logging read "protoPayload.serviceName=cdn.googleapis.com AND severity>=INFO" \
--freshness=24h --format=json > ./evidence/access/control-plane-access-$AUDIT_DATE.json
# 3. TLS config snapshot (CC6.7)
curl -s https://api.cdn-provider.com/v1/config/tls --header "Authorization: Bearer $AUDIT_TOKEN" \
| jq . > ./evidence/config/tls-snapshot-$AUDIT_DATE.json
# 4. Push with object lock for tamper resistance
aws s3 cp ./evidence/ $EVIDENCE_BUCKET/$AUDIT_DATE/ --recursive --object-lock-mode COMPLIANCE \
--object-lock-retain-until-date $(date -d "+1 year" --iso-8601)
Translating Trust Services Criteria Into CDN-Specific Controls
This is where most engineering teams get stuck. The TSC language is intentionally generic — "logical access controls" or "system monitoring procedures" — but your implementation has to be painfully specific to the CDN. For CC6.1 (logical access), don't just write "we use SSO." Document exactly how edge configuration access is segmented: who can change origin settings versus who can only purge cache, how MFA is enforced on the CDN portal and API, and how service accounts for automated purging are rotated. I learned this the hard way when an auditor flagged our long-lived API token that hadn't rotated in 14 months. We'd forgotten it existed.
For availability (A1.2), you need more than uptime graphs. You need to show capacity monitoring, incident response, and communication. That means linking your synthetic monitoring, your auto-scaling or load shedding at the edge, and your status page updates into one traceable process. And if you promise data residency to customers, your SOC 2 confidentiality controls overlap directly with your CDN Data Residency Requirements: Keeping Content Within Geographic Boundaries architecture. Auditors will sample cache logs to verify content for EU customers never hit a non-EU PoP if your policy says it shouldn't. We've started tagging every cache object with a residency attribute just to make that sampling easy.
Don't try to invent this mapping from scratch. If you've already done work for CDN PCI DSS Compliance: Implementing Payment Card Security at the Edge, you've got a head start — many of the same edge logging and key management controls apply, but SOC 2 wants broader coverage over time rather than just point-in-time compliance. The security audit for SOC 2 Type II will test your controls over a 6-12 month window, so consistency beats intensity every time.
# terraform/cdn_soc2_controls.tf - Version-controlled edge controls for trust verification
resource "cdn_distribution" "primary" {
# Enforce modern TLS and HSTS for CC6.7
viewer_certificate {
minimum_protocol_version = "TLSv1.2_2021"
ssl_support_method = "sni-only"
}
custom_header {
name = "Strict-Transport-Security"
value = "max-age=63072000; includeSubDomains; preload"
}
custom_header {
name = "Content-Security-Policy"
value = "default-src 'self'; frame-ancestors 'none'"
}
# Tamper-evident logging for CC7.2
logging_config {
bucket = aws_s3_bucket.cdn_logs.id
include_cookies = false
retention_days = 365 # SOC 2 requires 12 months for Type II
object_lock_enabled = true
}
}
resource "aws_iam_policy" "cdn_purge_limited" {
name = "CDN-Purge-Only"
# CC6.2 - Least privilege: purge without config change
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["cdn:CreateInvalidation"]
Resource = "*"
Condition = {
Bool = { "aws:MultiFactorAuthPresent" = "true" }
}
}]
})
}
Designing an Evidence Pipeline That Won't Collapse Mid-Audit
You don't want humans manually taking screenshots for your trust verification packet. That's not sustainable and auditors don't trust it. The best CDN SOC 2 programs I've built treat evidence like telemetry — automatically collected, hashed, and stored immutably. Think about every control: if you claim you review firewall rule changes weekly, where's the Jira ticket, the Git diff, and the log showing the change was deployed? Automate that linkage now, not two weeks before the auditor arrives.
We set up a simple rule: if a control can't produce evidence without someone remembering to do it, the control will fail. So we instrumented everything. Our CDN configuration is in Terraform, every apply requires a pull request and two approvals, and that PR is automatically linked to a log snapshot. Our availability monitoring pushes alerts to PagerDuty, and PagerDuty incident reports are archived to our evidence bucket with retention locks. When the auditor asked for proof that we responded to a PoP failure within our SLA, we just gave them a filtered view of that bucket. No scrambling.
Retention and completeness are what sink most teams. For a proper CDN SOC 2 Type II, you'll need to maintain evidence for the entire review period, and auditors will sample randomly. If you're missing three days of WAF logs from March, they'll expand their sampling and dig deeper. The table below is the baseline we've used for the last three audits to keep our evidence pipeline honest.
| Control Area (TSC) | Evidence Artifact | Collection Frequency | Target / Threshold |
|---|---|---|---|
| CC6.1 Logical Access | Control plane access logs + MFA enforcement report | Daily automated export | 100% of privileged actions tied to SSO identity, 0% long-lived tokens >90 days |
| CC6.6 Encryption | TLS configuration snapshot + certificate transparency logs | Daily + on-change | TLS 1.2+ on 100% of edge listeners, cert rotation <30 days before expiry |
| CC7.2 System Monitoring | WAF block logs + edge anomaly alerts | Continuous (5-min batches) | 99.9% log delivery completeness, alert triage <15 minutes |
| A1.2 Availability | Synthetic health checks + incident post-mortems | 1-min checks, incident-driven | 99.95% edge availability per PoP, status page update <10 minutes |
| CC8.1 Change Management | Terraform PR, approval, and CDN deploy logs | Per change | 100% of edge config changes via PR with 2 approvals, deploy log match |
Putting Controls Into Production Without Slowing the Edge
Documentation doesn't pass a SOC 2 audit — demonstrable, repeatable enforcement does. The fastest way to fail is treating controls as a quarterly paperwork exercise. We've seen teams scramble for 3 weeks pulling WAF logs and change tickets manually, only to have auditors flag gaps because evidence was incomplete for a 6-hour window during a PoP failover. If you're not collecting continuously, you're not compliant.
Start by instrumenting your control plane. Every configuration change to your CDN — cache rules, origin ACLs, TLS policy, purge authorizations — needs to produce an immutable audit event with who, what, when, and approval reference. Don't rely on your CDN vendor's dashboard alone. Ship those events to a centralized, append-only log (S3 with Object Lock or equivalent) within 90 seconds. We aim for less than 60 seconds end-to-end latency from edge config push to SIEM ingestion. Set alerts if that pipeline lag exceeds 5 minutes; auditors will ask about your monitoring of the monitors, and that lag metric is exactly what they want to see.
For CC-6 logical access controls, automate the hard parts. Tie your CDN admin console to your IdP via SAML/SCIM, enforce MFA with phishing-resistant factors, and kill long-lived API tokens. Rotate credentials every 30 days maximum, and prove it. This same pattern extends to privacy-driven access controls — if you're handling PDSR-style deletion requests at the edge, the workflow we detail in our CDN CCPA Compliance: California Consumer Privacy Act and Content Delivery guide maps cleanly to SOC 2 CC-6.1 evidence for least-privilege enforcement. Don’t build two separate systems when one well-logged workflow covers both.
# Example: Evidence collector for CDN config changes + OPA check
# Runs every 5m via Lambda/Cron, writes tamper-evident evidence bundle
import boto3, json, hashlib, datetime
def collect_cdn_evidence():
cdn = boto3.client('cloudfront') # or Fastly/Cloudflare/Akamai API
s3 = boto3.client('s3')
changes = cdn.list_conf_changes(StartTime=datetime.datetime.utcnow() - datetime.timedelta(minutes=5))
for change in changes['Items']:
# 1. Verify change had approved ticket (Jira/ServiceNow)
approved = verify_ticket(change['TicketId'], status='APPROVED')
# 2. OPA policy check: no TLS < 1.2, no open purge ACL
if not policy_allows(change):
alert_security(change)
continue
evidence = {
"control_id": "CC-7.2 & CC-8.1",
"timestamp": change['Timestamp'].isoformat(),
"actor": change['ActorARN'],
"change_id": change['Id'],
"ticket_id": change['TicketId'],
"approved": approved,
"hash": hashlib.sha256(json.dumps(change).encode()).hexdigest()
}
s3.put_object(
Bucket="soc2-evidence-bundles",
Key=f"cdn-config/{change['Timestamp'].strftime('%Y/%m/%d')}/{change['Id']}.json",
Body=json.dumps(evidence),
ObjectLockMode='COMPLIANCE',
ObjectLockRetainUntilDate=datetime.datetime.utcnow() + datetime.timedelta(days=400)
)
def policy_allows(change):
# Rego/OPA: deny if origin allows 0.0.0.0/0 or TLS < 1.2
return change['TLSVersion'] >= 'TLSv1.2' and '0.0.0.0/0' not in change['OriginACL']
Advanced Patterns and Troubleshooting When Auditors Dig Deeper
You'll get pushback on two areas every time: availability (CC-7.2/A1.2) and change management (CC-8.1). For availability, auditors don't just want your 99.99% SLA marketing slide. They want 12 months of synthesized health checks, incident post-mortems, and proof that failover actually works. Keep synthetic monitors hitting each PoP from at least 3 external vantage points every 30 seconds, and retain that data for 13 months — auditors sample the full audit period plus one month prior. If you had a 22-minute origin shield failure in March, you'd better have the incident ticket, timeline, customer notification, and corrective action all linked and timestamped. Missing that chain is a qualified opinion waiting to happen.
The other nightmare is subservice organizations. If you're layering a third-party WAF, bot management, or log analytics provider in front of your CDN, that's a carve-out or inclusive method decision you'll make with your auditor on day one. Most CDN teams choose carve-out and then get burned because they didn't collect the vendor's SOC 2 Type II report or monitor the complement. We've had audits stall for 4-6 weeks waiting on a subservice SOC 2 report that expired 2 months before the audit period ended. Build a vendor register now: list every edge vendor, their report type, coverage dates, and bridge letters. Automate expiry alerts at 90, 60, and 30 days.
Finally, don't forget data residency can trigger additional review procedures. When auditors test CC-6.4 for data classification at the edge, they'll ask where PII is cached and for how long. If you serve Brazil or Thailand, your cache-key design and purge controls become audit evidence for privacy commitments too. The cache isolation patterns we use for CDN LGPD Compliance: Brazil's Data Protection Law and CDN Infrastructure and CDN PDPA Compliance: Thailand's Personal Data Protection in Content Delivery are directly reusable here — same edge dictionary for geo-fencing, same 72-hour max TTL for personal data, same purge log as proof. Reuse that architecture and you won't be building control evidence twice.
Frequently Asked Questions
How long do we need to retain CDN logs for SOC 2?
For a Type II, you need to demonstrate operation over the entire review period — typically 6 to 12 months. Retain raw edge access, WAF, and admin audit logs for at least 13 months in immutable storage with Object Lock or WORM. Auditors will sample logs from month 1 and month 9, so gaps of even 48 hours can result in an exception. Retain evidence bundles (change tickets, approval hashes, monitoring screenshots) for 12 months beyond the report date.
Can we use our CDN provider's SOC 2 report to cover our own audit?
No, you can't inherit it directly. Your provider's report covers their platform controls, not how you configured and operated it. You can use it as a subservice report (carve-out method) to avoid testing their data center controls, but you'll still need to prove your own CC-6.1 access provisioning, CC-7.2 system monitoring, and CC-8.1 change management on top of their infrastructure. Expect auditors to test at least 25-40 samples of your own config changes regardless of what your vendor attests to.
What's the most common reason CDN companies fail their first SOC 2 Type II?
Incomplete or inconsistent evidence collection. About 70% of first-time failures we see aren't due to missing controls, but to controls that weren't evidenced continuously. Typical culprits: manual ticket approvals via Slack that weren't archived, MFA not enforced on break-glass accounts for 11 days after an IdP migration, or cache purge authorizations that logged the API key but not the human actor. If your evidence pipeline requires a human to export a CSV, it will break mid-audit. Automate it.
Do we need separate controls for availability (A1) if we already cover Security?
Only if availability is in scope per your customer commitments. Security (Common Criteria) is mandatory, but Availability is an additional Trust Services Criterion you add if you contractually promise uptime. If your MSA claims 99.95% edge availability with credits, auditors will insist A1.2 and A1.3 be in scope. That adds requirements for performance monitoring, incident response testing (at least one tabletop every 6 months), and capacity planning reviews. If you don't commit to availability, you can scope it out — but most enterprise CDN buyers demand it.