GCP Lesson 44 of 98

SOC 2 Continuous Compliance Automation on GCP with Drata

In a nutshell

SOC 2 is the report that enterprise customers demand before they will trust you with their data: an independent auditor — a licensed CPA firm — inspects how you protect information and issues a report their own security team reads. The demanding version, a Type II report, does not ask “are your controls set up correctly today.” It asks “did your controls actually work, every single day, for the last 6–12 months.” Continuous compliance is the practice of collecting the evidence for that answer automatically, all year long, instead of scrambling for console screenshots the week before the auditor shows up. Drata is the software that stores all that evidence, maps each piece to the specific SOC 2 requirement it satisfies, and gives the auditor a login to check your work.

Picture a continuous heart monitor. A single blood-pressure reading at a check-up tells the doctor how you were for one minute — that is a screenshot, and it is all a point-in-time audit ever sees. A wearable that logs your heartbeat every minute for a year, timestamped and tamper-proof, tells the doctor how you actually lived — that is continuous compliance, and it is exactly what a Type II auditor wants to read. This lesson wires that “wearable” onto a Google Cloud estate: Security Command Center watches for misconfigurations, Cloud Audit Logs record who did what, Organization Policy blocks bad changes before they can happen, and small scheduled jobs read all three every day and stream timestamped pass/fail evidence into Drata. The SOC 2 report stops being an annual fire drill and becomes a byproduct of simply operating well.

Do not worry if several of these words are new — every one is defined plainly in the Glossary at the end, and the Practice challenges let you try each idea yourself before you build anything.

Level: Advanced · Time: ~36 min

Before you start, it helps to be comfortable with GCP’s resource hierarchy (organization → folders → projects), IAM roles and service accounts, and Cloud Logging; being able to read a little Terraform lets you follow the snippets. You need no prior compliance or audit background — we build the SOC 2 concepts from zero. If you want to shore up the foundations first, three sibling lessons line up directly with this one: IAM Fundamentals — Roles, Service Accounts, Policy, Resource Hierarchy & Org Policy Guardrails, and Centralized Logging Lake for Security & Compliance.

After this lesson you will be able to:

A Series-C digital health company that processes claims and care-coordination data for regional payers gets the email every scaling startup eventually gets: their three largest prospects, each a hospital network, will not sign until they produce a SOC 2 Type II report covering a 12-month observation window. The deals are worth more than the company’s entire current ARR, and the auditor wants to start the window in 90 days. The head of security does the math and it is grim: 64 trust-services controls, evidence to be pulled from a GCP estate of nine projects, two GKE clusters, BigQuery warehouses full of PHI-adjacent data, and a workforce of 140 — and the way they have always done it is a frantic, screenshot-driven scramble in the two weeks before the auditor arrives. That approach does not survive a Type II audit, which does not ask “is this control configured today” but “was this control operating effectively, continuously, for twelve months.” This article is the reference architecture for the only thing that actually answers that question: a continuous compliance system on Google Cloud that collects control evidence automatically, every day, and streams it into Drata so the report is a byproduct of how you operate rather than a fire drill you survive.

The pressures here are specific to a company growing through its first serious audit. Revenue is gated on the report — no SOC 2, no enterprise contracts, full stop. Continuity is the trap of Type II: a control that was green in January and silently drifted red in March produces an audit exception, and exceptions are what prospects’ security teams flag. Headcount is the constraint — a 140-person company cannot dedicate three engineers to manually screenshotting IAM policies forever. And trust is the actual product being sold: a healthcare buyer is handing you their patients’ data, and the report is the artifact that says you can be trusted with it. Continuous compliance — machine-collected, timestamped, immutable evidence mapped to each trust-services criterion — satisfies all four at once. The control state lives in your cloud’s own telemetry; Drata supplies the mapping, the monitoring, and the auditor-facing evidence room.

Why not the obvious shortcuts

Three shortcuts will be proposed in the first planning meeting, and each fails a Type II audit in a way worth naming.

The pre-audit screenshot sprint — assign people to capture console screenshots the month before fieldwork — produces evidence for a point in time, not the period, and a screenshot proves nothing about the eleven months the auditor cannot see. It also rots: the engineer who took it leaves, the console UI changes, and next year you start from zero. A spreadsheet of controls maintained by hand drifts out of sync with reality the day after someone updates it, and an auditor who finds the spreadsheet says “GKE RBAC is restricted” while the cluster actually allows broad access has just found you an exception and a credibility problem. Buying a compliance tool and stopping there is the most expensive mistake: Drata is not magic, and a GRC platform with nothing feeding it real, current evidence is a very polished to-do list. The tool is the system of record; the architecture is what makes the evidence true.

Continuous compliance threads the needle. Every control is backed by an automated evidence collector that reads the live state from GCP’s own security and audit telemetry on a schedule, compares it to the policy the control requires, and pushes a timestamped pass/fail with the underlying artifact into Drata. When a control drifts, the platform detects it within hours — not at audit time — and raises a ticket so it is remediated inside the window, which is exactly what keeps an exception off the final report.

Architecture overview

SOC 2 Continuous Compliance Automation on GCP with Drata — architecture

The diagram traces the platform’s two flows: the continuous evidence path, where GCP’s first-party signals — Security Command Center, Cloud Audit Logs, and Organization Policy / Policy Controller — feed the daily Cloud Run collectors that normalize and stream timestamped evidence into Drata; and, running independently beside it, the event-driven remediation path that turns a Pub/Sub finding into a tracked ServiceNow ticket.

The platform runs two distinct flows that share telemetry but live on different schedules: a continuous evidence flow that proves controls are operating, and an event-driven remediation flow that closes the gap the moment a control drifts. Keeping them separate is the first step to operating this without alert fatigue.

The defining property of the topology is that evidence is derived from immutable, first-party platform signals, never from a human re-stating what they believe is true. Three GCP sources do the heavy lifting: Security Command Center (SCC) Premium for posture and misconfiguration findings, Cloud Logging for the audit trail of who did what, and Organization Policy + Policy Controller for the policy-as-code guardrails that make many controls preventive rather than merely detective. Drata sits above them as the mapping and monitoring layer that turns raw signal into a SOC 2 trust-criterion it can show an auditor.

Evidence flow, following the control path:

  1. The GCP organization is the root of trust. Below it, a folder hierarchy separates prod, non-prod, and shared projects, and the whole org is enrolled in Security Command Center Premium, which continuously scans every project for misconfigurations — public buckets, over-broad IAM, unencrypted resources, disabled audit logs — and emits structured findings mapped to standards including SOC 2.
  2. Cloud Audit Logs (Admin Activity, Data Access, and System Event) capture every administrative and data-plane action across the org. An aggregated organization-level log sink exports these continuously to a dedicated, bucket-locked Cloud Storage bucket and to a BigQuery dataset, so the audit trail is immutable and queryable — the raw material for any “show me access over the period” question.
  3. Policy-as-code guardrails run at two layers: Organization Policy constraints deny whole classes of misconfiguration at the API (no public IPs, no external service-account keys, region pinning for data residency), and Policy Controller (managed OPA Gatekeeper) enforces admission policy inside GKE so a non-compliant workload is rejected before it ever runs. These make controls preventive, which is the strongest evidence you can give an auditor.
  4. An evidence-collection service — a small set of Cloud Run jobs triggered by Cloud Scheduler — runs daily per control. Each job queries the relevant source (SCC findings API, the BigQuery audit dataset, IAM policy bindings, the Policy Controller constraint status), evaluates it against the control’s expected state, and produces a normalized evidence record: control ID, SOC 2 criterion, pass/fail, timestamp, and the underlying artifact.
  5. Those records flow into Drata through its API and native GCP integration. Drata maps each to one or more Trust Services Criteria (Security/Common Criteria, Availability, Confidentiality, Processing Integrity, Privacy), maintains the continuous monitoring view, and becomes the evidence room the auditor logs into — every control, its current status, and the dated history that proves it held for the whole period.
  6. Personnel and policy controls — background checks, security-awareness training, signed acceptable-use and access-review attestations — are collected by Drata’s HR and identity integrations, including security-awareness training delivered through Moodle, the company’s LMS, whose completion records satisfy the “personnel receive security training” criterion automatically.

Remediation flow, event-driven and independent: a new high-severity SCC finding, or a control flipping to fail in Drata, publishes to a Pub/Sub topic. A subscriber automatically opens a ServiceNow incident with the control, the criterion at risk, and the offending resource, routed to the owning team with an SLA tied to keeping the fix inside the audit window. Critical, deterministic fixes (a bucket that went public, an audit-log sink that was disabled) can trigger auto-remediation Cloud Functions, while everything else is human-reviewed through the ticket. The loop is what converts “we found drift” into “we fixed it before it became an exception.”

Component breakdown

Component Service / tool Role in the platform Key configuration choices
Posture findings Security Command Center Premium Continuous misconfiguration + threat findings, SOC 2 mapped Org-level activation; SOC 2 posture; findings export to Pub/Sub
Audit trail Cloud Audit Logs + sink Immutable record of every admin/data action Aggregated org sink; bucket-lock retention; BigQuery for query
Preventive guardrails Organization Policy + Policy Controller Deny misconfig at the API and at GKE admission constraints/* org policies; Gatekeeper constraint templates
Evidence collectors Cloud Run + Cloud Scheduler Daily per-control evaluation → normalized evidence One job per control family; least-privilege service accounts
GRC system of record Drata TSC mapping, continuous monitoring, auditor evidence room API + GCP integration; control owners; alerting on drift
Workforce identity Okta (or Microsoft Entra ID) SSO, MFA, lifecycle, access-review source SCIM provisioning; MFA enforced; logs feed access-review evidence
Secrets HashiCorp Vault Dynamic DB creds, API tokens, signing keys Short-lived leases; audit device on; no static secrets in code
CSPM (independent) Wiz / Wiz Code Second-opinion posture + attack paths + IaC scanning Agentless scan; Wiz Code gates Terraform pre-merge
Runtime security CrowdStrike Falcon Endpoint + GKE node runtime threat detection Sensor on nodes + laptops; detections feed SOC and evidence
Observability / SLO Datadog (or Dynatrace) Availability evidence: uptime, SLOs, monitoring coverage Synthetic checks; SLO monitors; alert history as availability proof
ITSM / workflow ServiceNow Incident, change, and access-review ticketing Auto-incident on drift; change gate; review campaigns
CI / IaC GitHub Actions / Jenkins + Argo CD Pipeline build/test/policy-gate; GitOps deploy OIDC to GCP; Terraform plan + Wiz Code gate; Argo for GKE
IaC / config Terraform + Ansible Declarative infra + golden-image/config baselines Terraform for cloud; Ansible for VM/appliance hardening
Edge Akamai TLS, WAF, DDoS at the perimeter of the patient portal WAF rules; bot mitigation; logs as a monitored control surface
LMS Moodle Security-awareness training delivery + completion records Annual + onboarding courses; completion API feeds Drata

A few choices deserve the why, because they are the ones teams get wrong.

Why preventive guardrails beat detective ones. A detective control finds the public bucket after it exists and someone has to close the gap before the auditor notices; a preventive control means the bucket could never be made public in the first place. Organization Policy constraints like constraints/storage.publicAccessPrevention and constraints/iam.disableServiceAccountKeyCreation are enforced by GCP at the API, so the misconfiguration is impossible org-wide, and that impossibility is the cleanest evidence you can hand an auditor. Policy Controller does the same at GKE admission. Detective controls via SCC are the safety net for everything you cannot prevent — you want both, but lead with prevention.

Why the audit-log sink must be bucket-locked. The single most damaging audit finding is tampered or deleted evidence. An aggregated organization sink exports every project’s audit logs to one place; bucket-lock applies a retention policy that even a project owner cannot shorten or bypass, so the trail is immutable for the full observation period. Skip this and a clever insider — or a ransomware actor — can erase exactly the records the auditor needs, and you cannot prove they didn’t.

Why an independent CSPM alongside SCC. SCC is Google’s view of Google’s cloud, and Drata trusts it. Wiz provides a second, vendor-independent posture assessment with attack-path analysis that correlates a misconfiguration with a real exploitation route, and Wiz Code scans Terraform before merge so a misconfiguration never reaches the cloud to be found later. Two independent posture sources is not redundancy for its own sake — it is what lets you tell an auditor your control coverage does not depend on a single tool’s blind spots.

Implementation guidance

Provision with Terraform, and treat the org structure and log sink as the first deliverables. The order matters: you cannot prove a control held for the period if logging started after the period did.

  1. The organization with a folder hierarchy (prod / non-prod / shared) and projects placed beneath it, so policy and logging inherit by structure rather than per-project toil.
  2. The aggregated org-level audit-log sink to a bucket-locked Storage bucket and a BigQuery dataset — first, so the trail is complete from day one of the window.
  3. Security Command Center Premium activated at the org, with the SOC 2 posture enabled and findings exported to Pub/Sub.
  4. Organization Policy constraints applied at the org node, then Policy Controller installed on each GKE cluster with the constraint templates the controls require.
  5. The evidence-collection Cloud Run jobs and their Cloud Scheduler triggers, each with a least-privilege, read-only service account scoped to exactly the API it queries.

A minimal Terraform shape for the immutable sink communicates the intent — org-wide, retained, tamper-resistant:

resource "google_logging_organization_sink" "audit_all" {
  name             = "org-audit-to-locked-bucket"
  org_id           = var.org_id
  destination      = "storage.googleapis.com/${google_storage_bucket.audit.name}"
  include_children = true                       # every project under the org
  filter           = "logName:\"cloudaudit.googleapis.com\""
}

resource "google_storage_bucket" "audit" {
  name                        = "hc-soc2-audit-logs-locked"
  location                    = "US"
  uniform_bucket_level_access = true
  retention_policy {
    retention_period = 34128000                 # ~13 months, covers the window
    is_locked        = true                      # cannot be shortened or deleted
  }
}

The pipeline that applies this runs in GitHub Actions (or Jenkins where a team already lives there), authenticating to GCP via OIDC / Workload Identity Federation so there is no long-lived service-account key to leak — which is itself a SOC 2 control. The same pipeline runs Wiz Code against the Terraform plan as a required gate, and Argo CD handles GitOps delivery of the in-cluster policy and workloads so the deployed state is always the reviewed, version-controlled state — a continuous “changes are authorized and tested” evidence stream by construction.

Identity: one front door, fully logged. Workforce access flows through Okta as the IdP (or Microsoft Entra ID in a Microsoft-centric shop), with SCIM provisioning so a leaver is deprovisioned everywhere the moment HR offboards them, and MFA enforced on every app. Okta’s system log is itself evidence — it answers “MFA is enforced” and “access was reviewed and revoked” without a screenshot — and Drata reads it directly. Human access to GCP is granted through Okta-federated groups mapped to least-privilege IAM roles, never standing project-owner grants. The few secrets that are not workload identities — third-party API tokens, database credentials — live in HashiCorp Vault, issued as short-lived dynamic leases with the audit device enabled, so secret access is itself a logged, time-bounded, auditable event rather than a static string in a config file.

Map collectors to control families, not to individual controls. Write one evidence collector per family — encryption, IAM/least-privilege, logging, network, vulnerability management, change management, availability — and let each emit evidence for the several SOC 2 criteria that family touches. A collector that reads IAM bindings and flags any external or primitive-role grant feeds multiple Common Criteria controls at once, which keeps the number of jobs manageable as the control set grows.

Enterprise considerations

Security & Zero Trust. The architecture is evidence-generating by construction: least-privilege IAM, preventive org policy, immutable audit logs, no standing admin. Layer on top: (a) Wiz running continuous, independent CSPM and attack-path analysis across the org, so a misconfiguration that SCC’s ruleset misses is still caught and a real exploitation path is prioritized over a theoretical one; (b) CrowdStrike Falcon sensors on GKE nodes, VMs, and workforce laptops for runtime threat detection, feeding the SOC and supplying the “endpoints are protected and monitored” evidence directly; © Akamai at the edge of the patient portal for TLS, WAF, and DDoS protection, whose logs are a monitored control surface; (d) any drift or detection auto-raises a ServiceNow incident so the response is a tracked ticket with an SLA, not a buried log line; (e) virtual appliances — a network firewall and a secrets/HSM appliance from the GCP Marketplace — hardened with Ansible golden configs and patched on a tracked cadence, because an unpatched appliance is exactly the kind of vulnerability-management exception auditors look for.

Cost optimization. Continuous compliance is cheap relative to a lost enterprise deal, but the line items still warrant engineering.

Lever Mechanism Typical effect
Right-size SCC SCC Premium at org, not redundant per-project scanners One posture bill, full coverage
Tier log retention Hot in BigQuery 90 days; cold in locked bucket for the window Cuts query/storage spend without losing the trail
Serverless collectors Cloud Run jobs that run daily and scale to zero Pay per evaluation, not for idle infra
Partition the audit dataset Date-partition BigQuery; query only the window in scope Slashes scan cost on access-review queries
Consolidate GRC Drata as the single evidence room across frameworks Reuse SOC 2 evidence for ISO 27001/HIPAA later

The real cost story is reuse: the evidence collected for SOC 2 maps largely onto ISO 27001 and HIPAA controls in Drata, so the second framework is mostly mapping work, not a new collection effort — which is how a health company adds HIPAA attestation without doubling the team.

Scalability. Each part scales independently. SCC and Organization Policy apply org-wide automatically as new projects are created beneath the folders, so onboarding the tenth project adds zero compliance work — the controls inherit. The Cloud Run collectors scale to zero between runs and fan out per control family, so the evidence volume grows with controls, not with infrastructure cost. Drata scales by mapping, and adding a second framework reuses most existing evidence. The natural ceiling is people: control ownership must scale with the org, which is why every control in Drata has a named owner and a review cadence rather than being “security’s problem.”

Failure modes, and what each one looks like. Name them before they cost you an exception.

Reliability & evidence integrity. For a compliance system, “reliability” means the evidence is durable and trustworthy, and the availability of the product is itself a SOC 2 criterion. On the evidence side: the locked bucket and BigQuery dataset are the durable record, retained past the window, and the collectors are stateless and idempotent so a failed run simply re-runs. On the Availability criterion: Datadog (or Dynatrace) supplies the proof — synthetic uptime checks, defined SLOs with error budgets, and a documented alert-and-response history that shows monitoring was in place and incidents were handled, which is precisely what an availability auditor asks for. A pragmatic posture: treat any evidence gap longer than 24 hours as an incident, because an unexplained gap in the trail is itself an audit finding.

Observability. Instrument the compliance platform like production, because to an auditor it is production. Emit the metrics that matter: control pass rate (the headline number), mean time to remediate a failed control (does drift get fixed inside the window), collector freshness (is every evidence stream current), and open compliance incidents by criterion. Pipe these to Datadog dashboards the security lead watches daily, with alerting so a control flip pages someone rather than waiting for the weekly review. The auditor-facing view lives in Drata; the operator-facing view lives in Datadog — and the two should never disagree.

Governance. Every control has a named owner and a review cadence in ServiceNow, which runs the quarterly access-review campaigns that produce the “access is reviewed periodically” evidence automatically. Policy-as-code lives in version control, reviewed and revertable, so a change to a guardrail is itself an auditable change-management event. Pin tool and policy versions explicitly so behavior does not drift between audits. And log the provenance of every evidence record — which collector, which source, which timestamp — so when an auditor asks “how do you know this was true on March 12,” the answer is a query, not a memory.

Explicit tradeoffs

Accept these or do not build it. Continuous compliance is real engineering, not a purchase: you are building and maintaining evidence collectors that break when an API changes, and a stale collector that silently fails is worse than a manual process because it manufactures false confidence — which is why freshness monitoring is non-negotiable, not optional. Preventive guardrails via Organization Policy and Policy Controller will, by design, block legitimate work sometimes — a developer’s deploy gets rejected by an admission policy — and you must staff the exception path or the platform becomes the thing teams route around. The immutable, bucket-locked log trail costs storage you cannot reclaim early and cannot delete even when you want to. And the whole system front-loads effort: the screenshot sprint is cheaper this quarter and ruinous over a Type II window, while continuous compliance is the reverse — more now, far less every audit after.

The alternatives, and when they win. If you are pre-revenue and pursuing a Type I report (a point-in-time snapshot, not a period), the lightweight path — Drata’s out-of-the-box GCP integration with minimal custom collectors — is genuinely enough, and you should not over-build. If you live in multi-cloud, the same pattern holds but the sources change (AWS Security Hub or Azure Defender for Cloud in place of SCC), and Drata or Vanta sits above all of them as the unifying evidence room — Vanta is the close substitute here and wins where your team already runs it. And if compliance is genuinely not your bottleneck — a tiny internal tool with no enterprise buyers — then none of this is justified, and a hand-maintained control list is the honest answer. This architecture earns its complexity precisely when a Type II report on a regulated-data platform stands between you and the contracts that fund the company.

The shape of the win

For the health company’s first enterprise audit, the payoff is not “a passed report.” It is that fieldwork week is boring: the auditor is given a login to Drata, sees 64 controls each backed by dated, machine-collected evidence that held continuously for twelve months, samples a handful, queries the immutable audit trail to confirm, and finds zero exceptions — because every drift that happened during the year was caught by SCC or a freshness alert, ticketed in ServiceNow, and remediated inside the window. That clean Type II report is what unlocks the three hospital-network contracts, and it is reusable: the same evidence, re-mapped in Drata, carries most of the way to HIPAA and ISO 27001. Everything upstream — the org policy guardrails, the bucket-locked sink, the Cloud Run collectors, the Okta-fed access reviews, the Vault-issued short-lived secrets, the Wiz and CrowdStrike posture, the Moodle training records — exists so that the report is a byproduct of operating well, not a thing you brace for once a year. Start narrower if you are only chasing Type I, but for a regulated platform selling into healthcare at scale, this is where continuous compliance has to land.

Going deeper

Everything above is the architecture. This section is the mechanism — the parts an experienced engineer or the security lead running the audit needs to reason about precisely.

The Trust Services Criteria, precisely

SOC 2 is built on the AICPA’s Trust Services Criteria (TSC) — five categories, only one of which is mandatory:

Category Code Mandatory? What it covers
Security (Common Criteria) CC1–CC9 Always The baseline: control environment, risk assessment, access control, change management, operations. Every SOC 2 report includes it.
Availability A1.1–A1.3 Opt-in The system is available for operation and use as committed — capacity, monitoring, DR.
Confidentiality C1.1–C1.2 Opt-in Information designated confidential is protected — encryption, retention, disposal.
Processing Integrity PI1.1–PI1.5 Opt-in Processing is complete, valid, accurate, timely, and authorized.
Privacy P1–P8 Opt-in Personal information is collected, used, retained, disclosed, and disposed of per commitments.

The Common Criteria (CC) are organized on the COSO framework and carry the bulk of the controls — CC6 (logical and physical access) and CC7 (system operations, including monitoring and incident response) are where most of a cloud team’s engineering evidence lands. You choose the other four categories based on the commitments you make to customers; a health company selling availability-sensitive services typically adds Availability and Confidentiality, and adds Privacy only if it makes explicit privacy commitments. The scoping decision matters because every category you include is more controls to operate continuously — pick what you can actually sustain, not the full set for show. This is a common early over-reach: teams include all five to look thorough and then manufacture exceptions in the two categories they never really operate.

Mapping GCP signals to the criteria

Continuous compliance lives or dies on a defensible mapping from a GCP signal to a TSC point. This is the table the security lead maintains and the auditor scrutinizes:

SOC 2 criterion (example) GCP control / signal How the evidence is collected
CC6.1 — logical access is restricted IAM policy bindings; Org Policy iam.allowedPolicyMemberDomains Collector reads IAM bindings org-wide, flags external/primitive-role grants
CC6.1 — no long-lived keys Org Policy iam.disableServiceAccountKeyCreation Constraint state = enforced is the evidence (preventive)
CC6.6 — encryption in transit / at rest SCC findings; CMEK config SCC “unencrypted resource” findings = 0; CMEK bindings present
CC6.8 — only authorized software runs Policy Controller (Gatekeeper) constraints on GKE Constraint status: no admission violations
CC7.2 — monitoring detects anomalies SCC threat findings; Cloud Logging Findings flow to Pub/Sub; log-based alerts fire
CC7.3 — incidents are responded to ServiceNow tickets from Pub/Sub Ticket exists, has owner + SLA + resolution timestamp
CC8.1 — changes are authorized & tested GitHub Actions + Argo CD + Wiz Code gate PR approval, CI logs, policy-gate pass in the pipeline
A1.2 — availability is monitored Datadog SLOs + synthetic checks SLO history + alert-and-response record
C1.1 — confidential data is protected Org Policy gcp.resourceLocations; bucket-lock Region pinning enforced; retention locked

Notice the two evidence shapes: a preventive control’s evidence is simply “the guardrail is enforced” (a boolean org-policy state), while a detective control’s evidence is “the finding count is zero” or “the ticket was resolved.” Preventive evidence is stronger and cheaper to defend, which is why the architecture leads with Organization Policy and Policy Controller and treats SCC as the net beneath them.

Anatomy of an evidence collector

A collector is deliberately small: read one source, compare to expected, emit a normalized record. Here is the shape of the SCC collector as a Cloud Run job, using the Security Command Center client library:

from google.cloud import securitycenter_v1
from datetime import datetime, timezone
import json

client = securitycenter_v1.SecurityCenterClient()

# "-" for the source lists findings from every SCC source under the org
parent = "organizations/ORG_ID/sources/-"
public_bucket_findings = client.list_findings(request={
    "parent": parent,
    "filter": 'state="ACTIVE" AND category="PUBLIC_BUCKET_ACL"',
})

open_count = sum(1 for _ in public_bucket_findings)

evidence = {
    "control_id": "CC6.1-no-public-storage",
    "tsc": "CC6.1",
    "result": "pass" if open_count == 0 else "fail",
    "observed": {"active_public_bucket_findings": open_count},
    "source": "securitycenter.googleapis.com",
    "collected_at": datetime.now(timezone.utc).isoformat(),
}
print(json.dumps(evidence))     # -> shipped to Drata via its API

Representative output:

{"control_id": "CC6.1-no-public-storage", "tsc": "CC6.1", "result": "pass",
 "observed": {"active_public_bucket_findings": 0},
 "source": "securitycenter.googleapis.com", "collected_at": "2026-07-19T02:00:00+00:00"}

Four properties make this auditable: it reads a first-party signal (SCC, not a human), it records the exact query and count so the result is reproducible, it stamps UTC time so the evidence has a defensible date, and it is stateless and idempotent — re-running it the next day produces the next day’s record with no side effects. The same skeleton, pointed at the BigQuery audit dataset or at IAM, becomes the logging and access-review collectors.

The access-review collector reads the audit trail directly. This query pulls every IAM-policy change in the observation window from the BigQuery-exported audit logs — the raw population an auditor samples:

SELECT
  timestamp,
  protopayload_auditlog.authenticationInfo.principalEmail AS actor,
  protopayload_auditlog.methodName             AS method,
  resource.labels.project_id                   AS project
FROM `PROJECT.audit_dataset.cloudaudit_googleapis_com_activity_*`
WHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20261231'
  AND protopayload_auditlog.methodName = 'SetIamPolicy'
ORDER BY timestamp DESC;

Date-partitioning with _TABLE_SUFFIX is not just tidy — it is the cost control that keeps an access-review query over a year of org-wide logs from scanning terabytes it does not need.

Least privilege for the collectors themselves

The collectors read sensitive state, so they are prime targets — and an over-permissioned collector is itself an audit finding. Each runs as its own service account with exactly the read-only role its source requires, attached to the Cloud Run job so it uses Application Default Credentials with no downloaded key (which the iam.disableServiceAccountKeyCreation guardrail forbids anyway):

Collector Read-only role(s) Reads
SCC findings roles/securitycenter.findingsViewer Posture / threat findings
Audit-log / access review roles/bigquery.dataViewer, roles/bigquery.jobUser Exported audit dataset
IAM bindings roles/iam.securityReviewer Org-wide IAM policies
Org Policy state roles/orgpolicy.policyViewer Constraint enforcement
Policy Controller roles/container.viewer Gatekeeper constraint status

None of these can change anything — a collector that could remediate would be a control able to defeat its own evidence. (The CI pipeline is where Workload Identity Federation belongs: it lets GitHub Actions authenticate to GCP without a stored key, and the collectors, running inside GCP, need only their attached identity. See Workload Identity Federation — Keyless CI/CD.)

How Drata turns a record into a control test

Inside Drata, each incoming evidence record is attached to one or more control tests that run on a cadence (typically daily). A test has a defined evidence window — if no fresh, passing record arrives inside that window, the test flips to failing and Drata opens a task assigned to the control’s owner. This is why collector freshness monitoring is non-negotiable: to Drata, “the collector silently died” and “the control failed” look identical unless something independent (a Datadog heartbeat alert) catches the missing signal. The continuous history Drata accumulates — every daily pass, every flip, and its remediation — is exactly the artifact a Type II auditor reads.

The auditor’s workflow, and where continuous evidence changes it

An external CPA firm performs the SOC 2 audit; you cannot self-certify, and there is no “certificate” — the deliverable is an attestation report. The mechanics an engineer should understand:

Continuous vs point-in-time, quantified

The difference is not philosophical. A point-in-time control set answers one question — “is this true now” — and says nothing about the other 364 days. A continuous control set answers “was this true every day,” and it does so by keeping roughly 365 dated records per control instead of a single screenshot. For 64 controls that is about 23,000 evidence records a year, each timestamped and traceable to a first-party source — a volume no manual process can produce, and the exact volume a Type II report is an assertion about. The whole architecture exists to make that volume a background hum rather than a project.

Practice challenges

Work these in order — the first two build intuition, the middle two are the hands-on guardrail and IAM patterns, and the last two are the operational edges that separate a demo from a system that survives an audit. Try each before opening the solution.

1 — Which criterion, and is it mandatory? (Beginner). Your control list has “MFA is enforced on all administrative access” and “confidential customer data is encrypted at rest.” For each, name the TSC category and say whether it is always in scope.

<details><summary>Solution</summary>

MFA on admin access → Security / Common Criteria (CC6.1, logical access), which is always in scope — every SOC 2 report includes the Common Criteria. Encryption of confidential data at rest → primarily Confidentiality (C1.1), reinforced by CC6.6 under Common Criteria; Confidentiality is opt-in, included only if you commit to it. Why it matters: the Common Criteria are non-negotiable, so you always operate them; the other four categories you choose — and every one you choose is more evidence to sustain all year.

</details>

2 — The screenshot trap (Beginner). A manager proposes assigning an intern to screenshot the IAM page the week before fieldwork. Give the one-sentence reason this fails a Type II audit.

<details><summary>Solution</summary>

A screenshot proves the control’s state for a single instant, but a Type II report asks whether the control operated effectively across the entire observation period — so it says nothing about the other ~364 days and produces an exception the moment the auditor asks for the history. Why it matters: Type II is about the period, not the point; only continuously collected, dated evidence answers it.

</details>

3 — Make public buckets impossible (Intermediate). Instead of detecting public buckets after the fact, make them impossible org-wide. Which Organization Policy constraint, expressed as Terraform, and why is this stronger evidence than an SCC finding?

<details><summary>Solution</summary>

The boolean constraint constraints/storage.publicAccessPrevention, enforced at the org node:

resource "google_org_policy_policy" "no_public_buckets" {
  name   = "organizations/ORG_ID/policies/storage.publicAccessPrevention"
  parent = "organizations/ORG_ID"
  spec {
    rules {
      enforce = "TRUE"
    }
  }
}

Why it matters: this is a preventive control — the misconfiguration cannot occur — so the evidence is simply “the guardrail is enforced,” which is cleaner and cheaper to defend than a detective SCC finding that only proves you caught the public bucket after it already existed.

</details>

4 — Least privilege for the SCC collector (Intermediate). Your SCC evidence collector runs as a dedicated service account. Which single predefined role does it need, and which tempting role must you not grant?

<details><summary>Solution</summary>

Grant only roles/securitycenter.findingsViewer — read-only visibility into findings, nothing more. Do not grant roles/securitycenter.admin (or findingsEditor), which would let the collector mutate or resolve findings. Why it matters: a collector that can change the very findings it reports on could hide its own failures — the evidence source must be strictly read-only.

</details>

5 — Access-review evidence, partition-pruned (Advanced). Write the WHERE clause that pulls every IAM-policy change in H1 2026 from the BigQuery-exported Admin Activity audit logs, scanning only the relevant partitions.

<details><summary>Solution</summary>

WHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260630'
  AND protopayload_auditlog.methodName = 'SetIamPolicy'

Why it matters: _TABLE_SUFFIX prunes the date-sharded cloudaudit_googleapis_com_activity_* tables so you scan only the six months in scope (not a year of terabytes), and SetIamPolicy is the method name that records every binding change — together they are the exact population an auditor samples for the “access is reviewed” control.

</details>

6 — The silent collector (Advanced). A collector’s service account loses a permission and the job starts failing, but Drata still shows the last green record. Design the guard, and explain why a missing heartbeat must be treated as a fail, not a pass.

<details><summary>Solution</summary>

Have every collector emit a heartbeat metric on each successful run — e.g. a Datadog metric compliance.collector.last_run tagged by control — and alert when its age exceeds the expected interval plus a grace period; treat that alert as a compliance incident with an SLA. A missing heartbeat must count as a fail because Drata will otherwise keep displaying the stale green record while you are actually blind: a silently dead collector manufactures false confidence, which is worse than a known gap. Why it matters: absence of evidence can never be read as evidence of compliance — freshness monitoring is what makes the whole system trustworthy.

</details>

Common beginner mistakes

Glossary

Term Plain-language meaning
SOC 2 A widely-demanded security report, written by an independent auditor, describing how a service organization protects customer data. Not a certificate — an attestation report.
Type I / Type II Type I opines on whether controls are designed well at one point in time; Type II opines on whether they operated effectively across a period (3–12 months). Type II is the demanding one.
Trust Services Criteria (TSC) The AICPA’s five control categories a SOC 2 report can cover: Security (Common Criteria), Availability, Confidentiality, Processing Integrity, Privacy.
Common Criteria (CC1–CC9) The mandatory Security category, organized on the COSO framework; every SOC 2 report includes it. CC6 (access) and CC7 (operations) carry most cloud evidence.
AICPA / CPA firm The professional body that defines the TSC (AICPA), and the licensed accounting firm that performs the audit and issues the report. You cannot self-certify.
Attestation report The document a CPA firm issues — a description of your controls plus their opinion and any exceptions. There is no “SOC 2 certificate.”
Observation period The window of time (e.g., 12 months) a Type II report covers, over which controls must have operated continuously.
Exception An instance where a control did not operate as described during the period. Prospects’ security teams scrutinize these.
Bridge (gap) letter A short attestation covering the interval between a report’s period-end and the date a customer reads it, stating nothing material changed.
Continuous compliance Collecting control evidence automatically and continuously, so the report reflects the whole period rather than a pre-audit snapshot.
Evidence collector A small scheduled job that reads live state from one source, compares it to the control’s expected state, and emits a normalized, timestamped pass/fail record.
GRC platform / Drata Governance, Risk, and Compliance software that stores evidence, maps it to criteria, monitors controls continuously, and is the auditor’s evidence room. Drata is one such platform (Vanta is a close substitute).
Control / control owner A specific safeguard a criterion requires, and the named person accountable for keeping it green and remediating drift.
Preventive vs detective control Preventive stops the bad state from ever occurring (org policy); detective finds it after the fact (an SCC finding). Preventive evidence is stronger.
Security Command Center (SCC) Google Cloud’s security and risk platform; the Premium tier continuously scans for misconfigurations and threats and maps findings to standards including SOC 2.
Cloud Audit Logs GCP’s immutable record of administrative and data actions — Admin Activity, Data Access, System Event — the “who did what” trail.
Aggregated org sink A single organization-level log export that captures every project’s logs to one destination (a locked bucket and BigQuery).
Bucket-lock A Cloud Storage retention policy that, once locked, cannot be shortened or bypassed even by an owner — making the audit trail tamper-proof for the period.
Organization Policy Org-wide guardrails (constraints/*) enforced by GCP at the API, denying whole classes of misconfiguration — the preventive layer.
Policy Controller / Gatekeeper / OPA Managed Open Policy Agent (Gatekeeper) that enforces admission policy inside GKE, rejecting non-compliant workloads before they run.
IAM binding A grant of a role to an identity on a resource. Reading bindings org-wide is how the access-control evidence is produced.
Service account A non-human GCP identity that a workload (like a collector) runs as; scoped to least privilege and, ideally, keyless.
Workload Identity Federation Lets an external system (e.g., GitHub Actions) authenticate to GCP without a stored service-account key — keyless CI/CD.
CSPM / Wiz Cloud Security Posture Management — continuous, often agentless, posture and attack-path analysis. Wiz is used here as an independent second opinion alongside SCC.
Pub/Sub GCP’s messaging service; here it carries findings and control-flip events into the event-driven remediation flow.
Cloud Run / Cloud Scheduler Serverless container runtime (the collectors run as Cloud Run jobs) and the cron service that triggers them daily.
SCIM A provisioning standard that syncs user accounts from the identity provider (Okta/Entra) so leavers are deprovisioned everywhere at once.
SLO Service Level Objective — a target for availability/latency with an error budget; its history is the Availability-criterion evidence.
Sampling The auditor’s method of testing a subset of a population over the period. Continuous evidence makes the whole population available, so samples land on hard proof.
Evidence room The auditor-facing view (Drata) where every control, its status, and its dated history live, replacing emailed screenshots.
GCPSOC 2ComplianceSecurity Command CenterDrataPolicy-as-Code
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments