Google Cloud compliance monitoring:
20 read-only checks, 8 read-only roles.
Connect a Google Cloud project with a read-only service account and TryTrustable checks Cloud SQL, IAM, audit logging, Cloud Run, container scanning, monitoring, secret rotation and Security Command Center, then files each passing result as evidence.
What does the TryTrustable Google Cloud integration check?
The Google Cloud integration runs 20 read-only checks against one project: Cloud SQL encryption in transit, public exposure, backups, point-in-time recovery, deletion protection and high availability; IAM, covering service accounts with Owner or Editor, the number of owners, personal accounts and user-managed keys; Data Access audit logs and log retention; Cloud Run public ingress, runtime service accounts and warm API instances; container scanning; uptime checks and alerts; secret rotation; and Security Command Center.
The checks began as the ones we ran by hand against our own project during a SOC 2 readiness review, turned into something that runs on connect. They call Google's REST APIs directly, with no client library, and each one reads configuration and decides. A call Google refuses is reported with Google's reason, never as a pass.
| Check | What it reads | How it decides | Evidence filed against |
|---|---|---|---|
| Cloud SQL requires encrypted connections | GET sqladmin.googleapis.com/v1/projects/{p}/instances, settings.ipConfiguration.sslMode | Pass for an instance if sslMode is ENCRYPTED_ONLY or TRUSTED_CLIENT_CERTIFICATE_REQUIRED (or the older requireSsl is true). Every instance, replicas included. | SOC 2 CC6.6 SOC 2 CC6.7 ISO/IEC 27001 A.5.14 DPDP Act §8(5) |
| Cloud SQL is not open to the internet | The same instance list, ipv4Enabled and authorizedNetworks | Fail for an instance with a public IP whose authorised networks include 0.0.0.0/0, ::/0 or any other /0 range. | SOC 2 CC6.6 ISO/IEC 27001 A.8.20 ISO/IEC 27001 A.8.22 |
| Cloud SQL automated backups enabled | The same instance list, backupConfiguration.enabled | Pass if automated backups are on for every primary instance. Read replicas are skipped. | SOC 2 A1.2 ISO/IEC 27001 A.8.13 |
| Cloud SQL point-in-time recovery enabled | The same instance list, pointInTimeRecoveryEnabled or, for MySQL, binaryLogEnabled | Pass if every primary instance can be restored to a point in time. | SOC 2 A1.2 ISO/IEC 27001 A.8.13 |
| Cloud SQL deletion protection enabled | The same instance list, deletionProtectionEnabled | Pass if it is on for every primary instance. | SOC 2 A1.2 ISO/IEC 27001 A.5.33 |
| Cloud SQL configured for high availability | The same instance list, availabilityType | Pass if every primary instance is REGIONAL. Marked informational. | SOC 2 A1.2 ISO/IEC 27001 A.8.14 |
| Service accounts do not hold Owner or Editor | POST cloudresourcemanager.googleapis.com/v1/projects/{p}:getIamPolicy, the roles/owner and roles/editor bindings | Fail for each service account holding either role, with the default compute service account called out. Google-managed service agents are exempt. | SOC 2 CC6.3 ISO/IEC 27001 A.8.2 ISO/IEC 27001 A.5.15 DPDP Act §8(5) |
| Project owners are few and accountable | The same IAM policy, user: and group: members of roles/owner | Pass if there are between 2 and 4 user or group owners (the default range). Fewer cannot recover access; more is standing privilege. | SOC 2 CC6.3 ISO/IEC 27001 A.8.2 |
| No personal accounts hold Owner or Editor | The same IAM policy, user: members of Owner and Editor | Fail for each Owner or Editor in a consumer email domain (gmail.com, googlemail.com, yahoo.com, outlook.com, hotmail.com, live.com, icloud.com, me.com, aol.com, proton.me, protonmail.com). | SOC 2 CC6.2 ISO/IEC 27001 A.5.16 |
| Data Access audit logs enabled | The same IAM policy, auditConfigs | Pass if DATA_READ audit logs are on, directly or through allServices, for Cloud SQL, Secret Manager and Cloud Storage. | SOC 2 CC7.2 ISO/IEC 27001 A.8.15 DPDP Act §8(5) |
| No user-managed service-account keys | GET iam.googleapis.com/v1/projects/{p}/serviceAccounts, then .../serviceAccounts/{sa}/keys?keyTypes=USER_MANAGED for each | Fail for each service account with an enabled user-managed key; the key this connection authenticates with is identified if it is one of them. | SOC 2 CC6.1 |
| _Default log bucket retention meets policy | GET logging.googleapis.com/v2/projects/{p}/locations/-/buckets, retentionDays of _Default | Pass if _Default keeps logs for at least 365 days (the default threshold). The platform default of 30 days fails. | SOC 2 CC7.2 ISO/IEC 27001 A.8.15 |
| Only intended Cloud Run services are public | GET run.googleapis.com/v2/projects/{p}/locations/-/services and GET run.googleapis.com/v2/{service}:getIamPolicy | Fail for a service with ingress all that anyone can invoke (allUsers or allAuthenticatedUsers on roles/run.invoker, or invoker IAM disabled) unless it is declared public with the label trytrustable-public=true. | SOC 2 CC6.6 ISO/IEC 27001 A.8.20 ISO/IEC 27001 A.8.22 |
| Cloud Run services do not run as the default compute service account | The same service list, template.serviceAccount | Fail for a service with no service account set or running as *-compute@developer.gserviceaccount.com. | SOC 2 CC6.3 ISO/IEC 27001 A.8.2 |
| API services keep a warm instance | The same service list, minInstanceCount | For services identified as an API (an api segment in the name, or the label trytrustable-role=api), pass if at least one instance is kept warm. Marked informational. | ISO/IEC 27001 A.8.6 |
| Container images are scanned for vulnerabilities | GET serviceusage.googleapis.com/v1/projects/{p}/services/containerscanning.googleapis.com | Pass if the Container Scanning API is ENABLED. Per-repository opt-outs are not evaluated. | SOC 2 CC7.1 ISO/IEC 27001 A.8.8 |
| Uptime checks monitor the service | GET monitoring.googleapis.com/v3/projects/{p}/uptimeCheckConfigs | Pass if at least one uptime check exists. | SOC 2 CC7.2 ISO/IEC 27001 A.8.16 |
| Alert policies notify someone | GET monitoring.googleapis.com/v3/projects/{p}/alertPolicies | Pass if at least one enabled alert policy is routed to a notification channel. Whether one alerts on an uptime check is recorded with the evidence. | SOC 2 CC7.2 SOC 2 CC7.3 ISO/IEC 27001 A.8.16 |
| Secrets are rotated within policy | GET secretmanager.googleapis.com/v1/projects/{p}/secrets, then each secret's enabled versions (metadata only) | Pass if every secret's newest enabled version is at most 90 days old (the default). Secrets with no enabled version are not applicable. | SOC 2 CC6.1 |
| Security Command Center is active | GET securitycentermanagement.googleapis.com/v1/projects/{p}/locations/global/securityCenterServices/security-health-analytics | Pass if Security Health Analytics' effectiveEnablementState is ENABLED. Fail if it is not, or if Security Command Center has not been activated for the project. | SOC 2 CC7.1 ISO/IEC 27001 A.8.8 ISO/IEC 27001 A.5.7 |
A check over several resources passes only if every resource passes. One that could not be read makes the whole check could not verify, not a pass on the rest.
Each check returns one of four results: pass, fail, not applicable (nothing of that kind exists, or a plan limit makes the setting unavailable) or could not verify (the call was refused or failed). A check over several resources shows a value such as 6/8 passing and names every resource it looked at. Nothing is simulated, and a check that could not look is never shown as a pass.
Only passing checks become evidence: one evidence item for each reference in the last column, so a single pass can evidence SOC 2, ISO/IEC 27001 and the DPDP Act at once. Each item expires after 90 days and every sync renews it, so evidence from a connection that has stopped syncing stops counting. A failing result is shown on the connected account with the resources that caused it, and is not filed as evidence.
Which compliance controls does Google Cloud evidence?
Each check belongs to a shared control in the TryTrustable control library, and is filed only under requirements the library maps to that control. The same control answers the requirements below in other frameworks; the references are read from the library. The cross-framework mapping page explains how one result reaches several frameworks.
| Shared control | Checks that speak to it | SOC 2 | ISO/IEC 27001:2022 | DPDP Act | ISO/IEC 42001 |
|---|---|---|---|---|---|
| Encryption of data in transitCTL-ENCRYPT-TRANSIT | Cloud SQL requires encrypted connections | CC6.6, CC6.7 | A.5.14 | §8(5) | None |
| Network segmentationCTL-NET-SEG | Cloud SQL is not open to the internet; Only intended Cloud Run services are public | CC6.6 | A.8.20, A.8.21, A.8.22, A.8.31 | None | None |
| Backup and restore testingCTL-BACKUP | Cloud SQL automated backups enabled; Cloud SQL point-in-time recovery enabled; Cloud SQL deletion protection enabled | A1.1, A1.2, CC7.5, PI1.5 | A.5.30, A.5.33, A.8.13 | None | None |
| Business continuity and disaster recoveryCTL-BCDR | Cloud SQL configured for high availability; API services keep a warm instance | A1.2, A1.3, CC9.1 | A.5.29, A.5.30, A.7.11, A.8.6, A.8.14 | None | None |
| Periodic logical access reviewCTL-ACCESS-REVIEW | Service accounts do not hold Owner or Editor; Project owners are few and accountable; Cloud Run services do not run as the default compute service account | CC1.3, CC3.3, CC4.1, CC6.2, CC6.3 | A.5.3, A.5.15, A.5.18, A.6.5, A.8.2, A.8.3, A.8.4, A.8.18, A.8.34 | §8(5) | None |
| Single sign-on for workforce accessCTL-SSO | No personal accounts hold Owner or Editor | CC6.1, CC6.2 | A.5.15, A.5.16, A.8.5 | None | None |
| Centralised, tamper-evident loggingCTL-LOGGING | Data Access audit logs enabled; _Default log bucket retention meets policy; Uptime checks monitor the service; Alert policies notify someone | CC2.1, CC4.1, CC7.2, CC7.3, P6.2, P6.3, PI1.1, PI1.3, PI1.4 | A.5.25, A.5.28, A.7.4, A.8.15, A.8.16, A.8.17 | §8(5) | A.6.2.6, A.6.2.8 |
| Cryptographic key managementCTL-KEY-MGMT | No user-managed service-account keys; Secrets are rotated within policy | CC6.1 | None | None | None |
| Vulnerability scanning and remediationCTL-VULN-SCAN | Container images are scanned for vulnerabilities; Security Command Center is active | CC3.2, CC7.1 | A.5.7, A.8.8 | None | None |
Requirement references are read from the TryTrustable control library. A dash means the library maps no requirement in that framework to this control.
The high-availability and warm-API-instance checks are marked informational: they are often cost or architecture decisions, so a fail is shown as a gap to decide on rather than an audit exception.
What roles does the Google Cloud service account need?
8 predefined read roles on the project: roles/iam.securityReviewer, roles/cloudsql.viewer, roles/logging.viewer, roles/run.viewer, roles/monitoring.viewer, roles/secretmanager.viewer, roles/serviceusage.serviceUsageViewer, roles/securitycentermanagement.viewer. roles/viewer is deliberately not needed: it reads nearly every resource in the project, including Cloud Storage object listings and BigQuery table metadata, which these checks do not use.
| Role | Why it is needed |
|---|---|
roles/iam.securityReviewer | Reads the project IAM policy (bindings and auditConfigs), lists service accounts and their key metadata, and reads Cloud Run IAM policies. Contains only get, list and getIamPolicy permissions. |
roles/cloudsql.viewer | Lists Cloud SQL instances and their settings: SSL mode, authorised networks, backups, PITR, deletion protection, availability. No access to databases or data. |
roles/logging.viewer | Reads log bucket retention. It does not include roles/logging.privateLogViewer, so the contents of Data Access logs stay unreadable. |
roles/run.viewer | Lists Cloud Run services with their ingress, runtime service account and scaling settings. |
roles/monitoring.viewer | Lists uptime checks and alert policies. |
roles/secretmanager.viewer | Reads secret and version metadata (creation times, rotation schedule). It cannot read a secret value; that needs secretmanager.secretAccessor, which is never requested. |
roles/serviceusage.serviceUsageViewer | Reads whether the Container Scanning API is enabled. |
roles/securitycentermanagement.viewer | Reads whether Security Command Center Security Health Analytics is enabled for the project. |
From the connector source. roles/cloudasset.viewer is not requested: no check calls the Cloud Asset API, and a role granted for a call that is never made is standing access with no purpose.
How to connect Google Cloud
- In the project, create a service account for TryTrustable, for example
trytrustable-auditor - Grant it the 8 roles above on the project
- Create a JSON key for it
- In TryTrustable, open Integrations, choose Google Cloud and paste the key. The project checked is the one named in the key
- The first sync runs immediately. Passing checks land in the evidence ledger; the platform re-syncs every six hours by default
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/iam.securityReviewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/cloudsql.viewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/logging.viewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/run.viewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/monitoring.viewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/secretmanager.viewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/serviceusage.serviceUsageViewer
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:AUDITOR_EMAIL --role=roles/securitycentermanagement.viewerThe key is encrypted at rest with AES-256-GCM and is never written to logs. If Google rejects it, the connection reports itself unverified and produces no checks. Cloud Run services that are meant to be public can be declared with the label trytrustable-public=true, so the decision is recorded rather than reported as a finding.
What the Google Cloud integration does not do
It does not read databases, log contents, secret values or storage objects. It does not check Compute Engine, GKE, firewall rules, Cloud Storage bucket IAM or KMS. It covers one project per connection and makes no changes in it. Code-level evidence comes from the SDK and CI gate in your own pipeline.
The things people ask us
What roles does the Google Cloud service account need?
8 predefined read roles on the project: roles/iam.securityReviewer, roles/cloudsql.viewer, roles/logging.viewer, roles/run.viewer, roles/monitoring.viewer, roles/secretmanager.viewer, roles/serviceusage.serviceUsageViewer, roles/securitycentermanagement.viewer. roles/viewer is deliberately not needed: it reads nearly every resource in the project, including Cloud Storage object listings and BigQuery table metadata, which these checks do not use.
Does the Google Cloud integration read our data?
No. It reads configuration and metadata. roles/cloudsql.viewer gives no access to databases, roles/secretmanager.viewer cannot read a secret value, and roles/logging.viewer does not include the private log viewer role, so the contents of Data Access logs stay unreadable. Cloud Storage objects and BigQuery data are never requested.
Why does the service-account key check fail on our own key?
Because it is a user-managed key, and the check reports every one, naming the key the connection uses. That is deliberate: a long-lived exportable key is a finding whoever holds it. The connector also supports keyless impersonation, where our service account mints a 15-minute token for your auditor service account and nothing long-lived is stored. The connect screen does not offer that option yet; it takes a JSON key.
Why is the OAuth scope cloud-platform and not read-only?
The Cloud SQL Admin and Cloud Run APIs do not accept the read-only scope. What keeps the connection read-only is the IAM roles, none of which contains a write permission. Every call is a get, list or getIamPolicy.
What if we do not use Cloud SQL, Cloud Run or Secret Manager?
If the API is not enabled in the project, the project cannot have those resources, and the checks for them report not applicable rather than failing. Monitoring and logging are treated differently: a refused call there is a real gap, so it reports could not verify.
Can I connect more than one project?
Yes. Each connection is one project, taken from the key's project ID, and you can add a connection per project. There is no organisation- or folder-wide connection that discovers projects on its own.
How often are the Google Cloud checks re-run?
The first sync runs as soon as you connect. After that the scheduler re-syncs every connected account every six hours by default, and you can press Sync at any time. Scheduled and manual syncs run the same code.
See a Google Cloud project checked live.
Thirty minutes. We connect a read-only service account and show the results landing as evidence against SOC 2, ISO 27001 and the DPDP Act.