Security Notes
Cloud

GCP Security Fundamentals

12 min read 14 sections 7 model answers

Coming from AWS?Start with the Rosetta Stone below — most GCP security concepts have a near-direct AWS equivalent, and mapping them is the fastest way to get fluent (and a common interview ask for multi-cloud roles).


AWS ↔ GCP Rosetta Stone

   AWS                          GCP                         What it is
 ───────────────────────────────────────────────────────────────────────────────
   Account                      Project                     The billing/isolation unit
   Organization + OUs           Organization + Folders      Hierarchy for policy inheritance
   IAM user                     Google account (user:)      A human identity
   IAM role (assumed)           Service Account (+ impersonation)  Workload / assumable identity
   IAM policy (JSON)            IAM binding (member→role)   Grant: who gets which role
   SCP (Org guardrail)          Org Policy (constraints)    Deny-only org-wide guardrail
   Resource policy              IAM policy on the resource  Who can touch this resource
   Permission boundary          (no direct equiv)           — use Org Policy + custom roles
   IMDS 169.254.169.254         metadata.google.internal    Where a VM gets its creds (SSRF target!)
   Instance profile             VM's attached service account  How a VM gets an identity
   IRSA / Pod Identity (EKS)    Workload Identity (GKE)     Per-pod cloud identity, no key files
   CloudTrail                   Cloud Audit Logs            The API audit trail
   GuardDuty                    Security Command Center (SCC) / Event Threat Detection
   Security Hub                 Security Command Center      Posture + findings aggregation
   Macie                        SCC + DLP API               Sensitive-data discovery
   Secrets Manager              Secret Manager              Managed secret storage
   KMS                          Cloud KMS                   Managed encryption keys
   WAF + Shield                 Cloud Armor                 L7 WAF + DDoS
   VPC (SG/NACL)                VPC (firewall rules)        Network controls
   (no direct equiv)            VPC Service Controls        Data-exfiltration perimeter (GCP's killer feature)
   Chronicle? (no)              Chronicle / Google SecOps   Cloud-native SIEM (YARA-L)
Memory hook

the two biggest "GCP is different" facts. (1) The unit is the Project, not the account — projects are cheap and you spin up many; the org/folder/project tree is what policy inherits down. (2) GCP's signature control is VPC Service Controls — a perimeter that stops data exfiltration even by an identity that has valid IAM permission (e.g. someone copying BigQuery data to their personal GCP project). AWS has no clean equivalent, so it's a favourite GCP interview topic.


Resource Hierarchy

Organization
  └── Folders (optional grouping)
       └── Projects
            └── Resources (GCE, GCS, GKE, etc.)

Policies are inherited downward and cannot be restricted at lower levels (they can only add permissions, not remove inherited ones — except Org Policies which can deny).


IAM (Identity and Access Management)

Principals (Who)

TypeDescription
user:Google account
group:Google Group
serviceAccount:Non-human identity for workloads
domain:All users in a Google Workspace domain
allAuthenticatedUsersAny Google-authenticated user (dangerous)
allUsersPublic internet (very dangerous)

Roles (What)

Role TypeDescriptionExample
PrimitiveBroad (Owner, Editor, Viewer)Avoid in production
PredefinedService-specificroles/storage.objectViewer
CustomFine-grainedOnly allow specific permissions

IAM Policy Binding

bash
# Grant a role
gcloud projects add-iam-policy-binding <project-id> \
  --member="serviceAccount:app@project.iam.gserviceaccount.com" \
  --role="roles/storage.objectViewer"

# View current policy
gcloud projects get-iam-policy <project-id> --format=json
Memory hook

GCP privesc is usually service-account impersonation. Where AWS privesc is often "permission to modify IAM" (PassRole, AttachPolicy), the classic GCP path is impersonating a more powerful service account. If you hold iam.serviceAccountTokenCreator on a privileged SA, you can mint an access token as that SA and inherit its powers — no key file needed. Chain it: a low-priv identity → token-creator on an Editor SA → effectively Editor. So treat serviceAccountTokenCreator, serviceAccountKeyAdmin, and serviceAccountUser (actAs) as admin-adjacent permissions, exactly like AWS PassRole. The tool that maps these chains is the GCP equivalent of PMapper.

Dangerous GCP IAM Patterns

PatternRisk
roles/owner on projectFull control including billing
iam.serviceAccountTokenCreatorGenerate access tokens for any SA → full SA impersonation
iam.serviceAccountKeyAdminCreate/export SA keys
iam.serviceAccountUserAct as the SA (required for deployment)
roles/editor on projectNear-full access; can't change IAM but can read most data
iam.securityAdminCan set IAM policies → privilege escalation
Exported SA keys (JSON)Long-lived; rotate and avoid exporting

Service Account Best Practices

  • One SA per workload; don't share
  • Use Workload Identity for GKE (no key files)
  • Prefer short-lived tokens over exported keys
  • Audit with iam.serviceAccounts.actAs permission grant

Org Policy Service

Org Policies are deny-only guardrails applied at org, folder, or project level. They override IAM grants.

   IAM says    "WHO can do WHAT"      (grants permissions — the gas pedal)
   Org Policy  "WHAT is allowed AT ALL across the org"  (restricts — the guardrail)

   Effective access  =  (IAM grants)  ∩  (Org Policy allows)
                        a Project Owner STILL can't create a public IP
                        if an Org Policy denies external IPs.
Memory hook

IAM grants, Org Policy forbids — same split as AWS IAM-vs-SCP. This is the single most-asked GCP IAM question. IAM is additive (it only ever grants), so even a Project Owner is capped by Org Policy constraints they can't override locally. The killer example: an Org Policy disableServiceAccountKeyCreation means even an Owner cannot export an SA key — shutting down the most common GCP credential-leak vector org-wide. Mnemonic: IAM = the gas, Org Policy = the speed limiter.

bash
# List effective policies
gcloud resource-manager org-policies list --project=<project-id>

# Example: deny public IPs on GCE
# Constraint: constraints/compute.vmExternalIpAccess

Key constraints:

ConstraintEffect
constraints/iam.disableServiceAccountKeyCreationPrevent SA key exports
constraints/compute.vmExternalIpAccessNo external IPs on VMs
constraints/storage.uniformBucketLevelAccessEnforce uniform bucket IAM
constraints/iam.allowedPolicyMemberDomainsRestrict who can be granted IAM roles
constraints/gcp.resourceLocationsEnforce data residency
constraints/iam.disableWorkloadIdentityClusterCreationBlock legacy SA key use on GKE

VPC Service Controls

Creates an access perimeter around GCP resources. Traffic outside the perimeter (even from authenticated GCP identities) is blocked.

┌─── VPC Service Perimeter ────────────────────────┐
│  Project A       Project B                       │
│  BigQuery        Cloud Storage  ←─ Only these    │
│  Spanner                           projects can  │
│                                    access these  │
└─────────────────────────────────────────────────┘
         ↑ Blocked: GCP requests from outside perimeter
         Even if caller has IAM permission

Access LevelsDefine conditions under which outside access is allowed (corp IP range, device trust level via BeyondCorp, specific service accounts).

Use case: prevent data exfiltration from BigQuery to attacker-controlled GCP project.


Security Command Center (SCC)

GCP's CSPM + threat detection platform.

FeatureDescription
Security Health AnalyticsMisconfiguration findings (public storage buckets, firewall rules)
Event Threat DetectionNear-real-time threat detection from Cloud Logging/Activity
Container Threat DetectionRuntime threats in GKE
Web Security ScannerDAST for App Engine, GKE, GCE
Virtual Machine Threat DetectionMemory-level crypto miner detection

Key SCC finding categories

  • PUBLIC_BUCKET_ACL — GCS bucket is public
  • OPEN_FIREWALL — firewall allows 0.0.0.0/0
  • IAM_GRANTS_DOMAIN_EDITOR_ROLE — allAuthenticatedUsers has editor role
  • CRYPTO_MINING_EXECUTION — mining detected in GCE memory
  • CREDENTIAL_ACCESS_GET_SECRET_VALUE — Secret Manager secret accessed from unusual location

Cloud Audit Logs

Three types:

TypeWhat it logs
Admin ActivityWrites to metadata, IAM policy changes (always on, free)
Data AccessReads/writes to user data (opt-in; can be high volume)
System EventGCP-initiated changes (always on, free)
bash
# Query audit logs via gcloud
gcloud logging read \
  'protoPayload.serviceName="iam.googleapis.com"' \
  --project=<project-id> \
  --freshness=24h \
  --format=json

# Find who accessed a secret
gcloud logging read \
  'protoPayload.resourceName:"projects/<project>/secrets/<secret-name>"' \
  --freshness=7d

Workload Identity (GKE)

Eliminates SA key files for GKE workloads. Kubernetes SA token is exchanged for a GCP SA access token via the metadata server.

bash
# Create GCP SA
gcloud iam service-accounts create app-sa \
  --project=<project>

# Bind K8s SA to GCP SA
gcloud iam service-accounts add-iam-policy-binding \
  app-sa@<project>.iam.gserviceaccount.com \
  --role=roles/iam.workloadIdentityUser \
  --member="serviceAccount:<project>.svc.id.goog[<k8s-namespace>/<k8s-sa>]"

# Annotate K8s SA
kubectl annotate serviceaccount <k8s-sa> \
  iam.gke.io/gcp-service-account=app-sa@<project>.iam.gserviceaccount.com

Cloud Armor (WAF + DDoS)

  • Layer 7 WAF rules (OWASP ModSecurity CRS)
  • Preconfigured rules for SQLi, XSS, LFI, RFI, RCE
  • IP allow/deny lists
  • Rate limiting (per IP, per user)
  • Adaptive protection (ML-based DDoS detection)
  • Attaches to backend services via global load balancer

Secret Manager

bash
# Create secret
gcloud secrets create my-secret --data-file=./secret.txt

# Access secret
gcloud secrets versions access latest --secret=my-secret

# Audit secret access (requires data access audit logs enabled for secretmanager.googleapis.com)
  • Versioning, automatic rotation support
  • IAM-controlled: roles/secretmanager.secretAccessor
  • Integration: Cloud Run, Cloud Functions, GKE via Secret Store CSI Driver

Binary Authorization

Enforces that only trusted container images are deployed to GKE/Cloud Run.

yaml
# Policy: require attestation from a specific attestor
defaultAdmissionRule:
  evaluationMode: REQUIRE_ATTESTATION
  requireAttestationsBy:
    - projects/<project>/attestors/build-attestor
  • Attestors sign images using Sigstore/cosign or Cloud KMS
  • Enforced at pod admission (MutatingAdmissionWebhook)
  • Break-glass: emergency bypass with audit trail

Chronicle SIEM

Google's cloud-native SIEM (acquired 2019).

  • Ingests Cloud Audit Logs, VPC Flow Logs, GKE audit logs, third-party logs
  • Query language: YARA-L (similar to YARA but for logs)
  • Retroactive alerting: apply new detection rules to historical data
  • UDM (Unified Data Model) normalises logs from any source
# Example YARA-L rule: detect SA key creation
rule sa_key_creation {
  meta:
    author = "security-team"
  events:
    $e.metadata.event_type = "USER_RESOURCE_CREATION"
    $e.target.resource.type = "SERVICE_ACCOUNT_KEY"
  condition:
    $e
}

GCP Attack Techniques

TechniqueDescriptionTool
SA key exfiltrationEnumerate and export SA keysGCPloit
Metadata SSRFRead http://metadata.google.internal/ from SSRF → get SA token—
iam:actAs impersonationToken generation via generateAccessToken if has iam.serviceAccountTokenCreatorgcloud
GCE default SADefault SA has Editor on project; compromise GCE → compromise project—
Cloud Function code injectionUpdate CF code with cloudfunctions.functions.update → execute as CF SA—
VPC SC bypassExfiltrate via allowed API paths or service perimeter gaps—

Interview Questions: GCP Security

Q
Explain the difference between IAM and Org Policy in GCP.
Model answer

IAM answers "who can do what" — it grants roles to principals on resources, and it's purely additive, so it only ever adds permissions. Org Policy answers "what's allowed at all across the organization" — it's a set of deny-style constraints applied at the org, folder, or project level that cap what's possible regardless of IAM. So effective access is the intersection: even a Project Owner with full IAM can't do something an Org Policy forbids. The classic example is the constraint that disables service account key creation — with it set, even an Owner can't export an SA key, closing the biggest GCP credential-leak vector org-wide. It's the same grant-versus-guardrail split as AWS IAM versus SCPs: IAM is the gas pedal, Org Policy is the speed limiter.

Q
What is VPC Service Controls and when would you use it?
Model answer

VPC Service Controls draws a perimeter around a set of GCP resources and projects so that requests crossing that boundary are blocked even if the caller has valid IAM permission. It defends against data exfiltration: the scenario where a compromised credential or a malicious insider with legitimate access to, say, BigQuery tries to copy the data out to a personal or attacker-controlled GCP project. IAM alone wouldn't stop that because the identity is authorized; the perimeter does, by denying the cross-boundary API call. You define Access Levels for sanctioned exceptions — corporate IP ranges, trusted devices via BeyondCorp, specific service accounts. You'd use it around sensitive data stores like BigQuery, Cloud Storage, and Spanner. It's GCP's signature control with no clean AWS equivalent, which is why it comes up a lot.

Q
How does Workload Identity eliminate SA key files?
Model answer

Workload Identity lets a GKE pod assume a GCP service account without any exported key file. You bind a Kubernetes service account to a GCP service account, and at runtime the pod's Kubernetes token is exchanged through the metadata server for a short-lived GCP access token for that service account. So the pod gets scoped, automatically-rotating credentials instead of a long-lived JSON key sitting in the container or a secret — eliminating the single most common GCP credential-leak vector. It's the GCP analogue of EKS IRSA or Pod Identity, and the security win is the same: no static keys to steal, leak, or forget to rotate, and identity scoped to the specific workload rather than the node.

Q
A PUBLIC_BUCKET_ACL finding fires in SCC. Walk me through remediation.
Model answer

First I confirm and scope: identify the bucket, what data it holds, and how it was made public — an ACL granting allUsers or allAuthenticatedUsers. I check access logs to see whether anyone external actually read objects while it was exposed, since that determines if this is a misconfiguration or a data-exposure incident. Then I remediate: remove the public ACL bindings and enable uniform bucket-level access so per-object ACLs can't reintroduce it, ideally enforced org-wide via the Org Policy constraints for uniform bucket access and restricting allowed IAM member domains. If sensitive data was exposed, it becomes an incident with notification considerations. Finally I close the gap with prevention — Org Policy to block public buckets and an SCC/automation alert so the next public bucket is caught or auto-remediated immediately.

Q
Explain the three types of Cloud Audit Logs and when you'd enable Data Access logging.
Model answer

Admin Activity logs record configuration and metadata writes — IAM changes, resource creation — and are always on and free. System Event logs record GCP-initiated changes, also always on and free. Data Access logs record reads and writes to user data within services — like reading an object or querying a table — and are opt-in because they can be very high volume and costly. You enable Data Access logging on sensitive services where you need to know who read what — Secret Manager, BigQuery, Cloud Storage holding sensitive data — because without it you can answer "who changed the config" but not "who actually read the data," which is exactly the question that matters in a data-exfiltration investigation. It's the GCP parallel to AWS CloudTrail data events being off by default.

Q
How does Binary Authorization help supply-chain security in GKE?
Model answer

Binary Authorization is an admission control that only lets images meeting a policy run on GKE or Cloud Run — typically requiring a cryptographic attestation that the image came from your trusted build pipeline and passed required checks. At deploy time the admission controller verifies the image has valid attestations from designated attestors, which sign images using cosign or Cloud KMS, and rejects anything unsigned or from an untrusted source. This stops a tampered or rogue image — say one an attacker pushed to the registry — from silently running, and enforces that only images built and signed through your governed process reach production. There's an audited break-glass for emergencies. It's the runtime enforcement of provenance, the same idea as the SLSA/cosign controls on the CI/CD side.

Q
What's the risk of the GCE default service account having the Editor role?
Model answer

By default, Compute Engine VMs run as the default service account, which historically is granted the project Editor role — broad write access across most of the project. The risk is that compromising any VM, for instance via an application RCE or an SSRF that reads the metadata server, hands the attacker that VM's token, and with Editor that token can modify resources across the whole project — a single compromised box becomes project-wide compromise. It's the GCP version of an over-privileged EC2 instance role. The fixes are to not use the default SA, instead attaching a dedicated least-privilege service account per workload, restricting the metadata server exposure, scoping access scopes, and using an Org Policy to prevent default SA grants. Treat the VM's identity as something an attacker will steal and scope it accordingly.