Cloud Compliance (SOC2/GDPR) Cheat Sheet
Summarizes SOC 2 Trust Service Criteria and core GDPR requirements relevant to running compliant cloud infrastructure.
SOC 2 Trust Service Criteria
The five categories audited under a SOC 2 report.
- Security- Protection against unauthorized access, the only mandatory criterion
- Availability- Systems are available for operation and use as committed/agreed
- Processing Integrity- System processing is complete, valid, accurate, timely, and authorized
- Confidentiality- Information designated confidential is protected as committed/agreed
- Privacy- Personal information is collected, used, retained, and disposed of per policy
- Type I vs Type II- Type I audits design at a point in time; Type II audits operating effectiveness over a period (typically 6-12 months)
GDPR Core Concepts
Key requirements of the EU General Data Protection Regulation.
- Data Controller- Entity that determines the purposes and means of processing personal data
- Data Processor- Entity that processes personal data on behalf of the controller (e.g. a cloud vendor)
- Lawful Basis- Must have a valid legal ground (consent, contract, legitimate interest, etc.) to process personal data
- Right to Erasure- Data subjects can request deletion of their personal data ('right to be forgotten')
- Data Portability- Subjects can request their data in a structured, machine-readable format
- 72-Hour Breach Notification- Controllers must notify the supervisory authority within 72 hours of becoming aware of a breach
- DPA (Data Processing Agreement)- Contract between controller and processor defining data handling obligations
Common Cloud Controls Mapped to Compliance
Practical controls that support audit requirements.
- Encryption at Rest/Transit- Required by most frameworks; use KMS-managed keys and TLS 1.2+
- Access Logging (CloudTrail)- Immutable audit trail of who did what, required for SOC 2 evidence
- Least Privilege IAM- Role-based access scoped to only what's needed, reviewed periodically
- Data Residency Controls- Restrict where data is stored/processed to satisfy GDPR data transfer rules
Framework Crosswalk (SOC 2 / ISO 27001 / GDPR)
How overlapping controls across frameworks map to each other so one control set can satisfy multiple audits.
- Access Control- SOC 2 CC6.1 ~ ISO 27001 A.9 ~ GDPR Art. 32 (appropriate technical measures) — one IAM policy review satisfies all three
- Risk Assessment- SOC 2 CC3.1 ~ ISO 27001 Clause 6.1 ~ GDPR Art. 35 (DPIA) — reuse the same risk register, tag entries by applicable framework
- Incident Response- SOC 2 CC7.3 ~ ISO 27001 A.16 ~ GDPR Art. 33/34 — GDPR's 72-hour clock is stricter than SOC 2's 'timely' language, so design to the tightest SLA
- Vendor Management- SOC 2 CC9.2 ~ ISO 27001 A.15 ~ GDPR Art. 28 (processor contracts) — a single sub-processor questionnaire can gather evidence for all three
- Change Management- SOC 2 CC8.1 ~ ISO 27001 A.12.1.2 — no direct GDPR clause, but supports Processing Integrity and Art. 32 integrity requirements
- Bridge Letter- Covers the gap between a SOC 2 Type II report's end date and the current date when a new audit hasn't completed yet
Policy-as-Code: Enforce Encryption (OPA/Rego)
A Rego policy evaluated in CI/CD or an admission controller to block unencrypted storage before it becomes an audit finding.
package compliance.storageimport future.keywords.in# Deny any S3 bucket resource lacking server-side encryptiondeny[msg] { resource := input.resource_changes[_] resource.type == "aws_s3_bucket_server_side_encryption_configuration" not resource.change.after.rule msg := sprintf("bucket %v missing SSE configuration", [resource.address])}deny[msg] { bucket := input.resource_changes[_] bucket.type == "aws_s3_bucket" not has_matching_encryption(bucket.address) msg := sprintf("bucket %v has no encryption resource attached", [bucket.address])}has_matching_encryption(bucket_address) { enc := input.resource_changes[_] enc.type == "aws_s3_bucket_server_side_encryption_configuration" enc.change.after.bucket == bucket_address}
Custom AWS Config Rule for Evidence Collection
A Lambda-backed Config rule that continuously evaluates IAM users for MFA, producing timestamped compliance evidence instead of a manual screenshot.
import boto3config = boto3.client('config')iam = boto3.client('iam')def lambda_handler(event, context): invoking_event = event['invokingEvent'] user_name = event['configurationItem']['resourceName'] if 'configurationItem' in event else None mfa_devices = iam.list_mfa_devices(UserName=user_name) compliant = len(mfa_devices['MFADevices']) > 0 config.put_evaluations( Evaluations=[{ 'ComplianceResourceType': 'AWS::IAM::User', 'ComplianceResourceId': user_name, 'ComplianceType': 'COMPLIANT' if compliant else 'NON_COMPLIANT', 'Annotation': 'MFA evidence collected for SOC 2 CC6.1', 'OrderingTimestamp': event['configurationItem']['configurationItemCaptureTime'] }], ResultToken=event['resultToken'] )
GDPR International Data Transfer Mechanisms
Legal instruments required when personal data leaves the EEA, relevant to any multi-region cloud deployment.
- Adequacy Decision- EU Commission has ruled the destination country provides adequate protection (e.g. UK, Japan, South Korea) — no extra paperwork needed
- Standard Contractual Clauses (SCCs)- Pre-approved EU contract clauses binding the importer to GDPR-equivalent protections; the default mechanism for US cloud vendors
- Transfer Impact Assessment (TIA)- Required alongside SCCs post-Schrems II to assess whether local surveillance laws in the destination undermine the clauses
- EU-US Data Privacy Framework (DPF)- Self-certification scheme for US companies that replaced Privacy Shield after it was invalidated
- Binding Corporate Rules (BCRs)- Internal intra-group data transfer policy approved by a lead supervisory authority, used by large multinationals
- Data Localization- Some sectors/regions require data to physically remain in-region regardless of contractual safeguards — check before relying on SCCs alone
Automating a GDPR Data Subject Access Request (DSAR)
A skeleton fan-out job that queries every system of record for a subject's data within the GDPR one-month response window.
DATA_SOURCES = [ {"name": "users_db", "query": "SELECT * FROM users WHERE email = %s"}, {"name": "analytics_warehouse", "query": "SELECT * FROM events WHERE user_email = %s"}, {"name": "support_tickets", "query": "SELECT * FROM tickets WHERE requester_email = %s"},]def run_dsar(subject_email: str, request_type: str): """request_type: 'access' | 'erasure' | 'portability'""" results = {} for source in DATA_SOURCES: rows = execute_query(source["name"], source["query"], (subject_email,)) results[source["name"]] = rows if request_type == "erasure": for source in DATA_SOURCES: anonymize_or_delete(source["name"], subject_email) log_dsar_evidence(subject_email, request_type, sources_checked=len(DATA_SOURCES)) return results # feeds the 30-day response letter
Compliance frameworks describe outcomes, not specific tools — map each control to concrete evidence (CloudTrail logs, IAM policies, encryption configs) early, since auditors want proof, not intent.