Security Architecture
Topic 55

Security Architecture

SecurityArchitecture

Security on GCP is not a service to add at the end — it is a set of architectural choices that pay off over the entire life of a system. The chapter on Security & Identity introduced the individual products: Cloud Identity, IAM, Secret Manager, Cloud KMS, IAP, Cloud Armor, Security Command Center, PAM. This topic is about composing them into an architecture where security is the default, not an exception. The recurring lesson: the controls you wire in on day one cost almost nothing; the controls you bolt on after the first incident cost dramatically more and never quite fit.

Five principles run through everything below: zero trust (never trust the network), defense in depth (layered controls so one failure does not own the system), least privilege (grant the minimum access for the shortest time), classify data so controls can be proportionate, and audit everything so the controls can be verified. Every section that follows is a concrete realization of these principles on GCP.

Zero Trust

Traditional security used the network as a trust boundary: anything inside the corporate VPC was trusted, anything outside was not. Zero trust discards that model. Every request, regardless of origin, must prove its identity, and authorization is evaluated based on the identity, the device, the request context, and the resource — never on network location alone.

The GCP shape of zero trust for end users is Identity-Aware Proxy in front of internal applications: the user must authenticate (via Cloud Identity federated to the corporate IdP), the device posture is evaluated, and IAP allows the request only if both pass. There is no VPN tunnel, no implicit trust from being on the office network. For workload-to-workload calls, the equivalent is service-account identity validated at the call site — a Cloud Run service authenticates the caller by its IAM identity, not by which VPC it came from.

VPC Service Controls add a perimeter that prevents authenticated identities from exfiltrating data even when they are otherwise authorized: a service account can read from BigQuery, but only when the request originates from inside the project boundary, and the data cannot leave that boundary. This is the layer that prevents a compromised credential from being used to copy data out, even if the credential itself is valid.

Defense in Depth

Layers, Each Catching What the Last Missed
Cloud Armor — edge WAF
Blocks volumetric and L7 attacks before they reach the load balancer.
Load Balancer — TLS termination
Single managed TLS endpoint; only well-formed requests pass.
IAP — per-request identity
Every request authorized against IAM, regardless of network position.
Application — input validation & authz
The app trusts nothing; checks permissions on every action.
Cloud KMS — encryption keys
Even on data exfiltration, ciphertext without the KEK is useless.

No single layer is the last line. Each reduces the blast radius of the one above it failing.

Defense in depth means that no single layer of control is the last line of defense. The composition for a typical web service: Cloud Armor at the edge for L7 filtering and WAF rules, Cloud Load Balancing with managed TLS, IAP for user authentication if internal, the application itself with input validation and per-request authorization, then the database with row-level security or per-tenant connections, and Cloud KMS wrapping the encryption keys for the data at rest.

Each layer reduces the blast radius of the previous one's failure. If Cloud Armor misses an attack signature, the application's input validation should catch it. If application auth has a bug, IAM permissions on the database should keep the damage contained. If a service account leaks, VPC Service Controls and KMS access policies make the credential less useful. No single layer is perfect; the composite is.

The cost of layered defense is operational, not technical. Each layer must be tuned, observed, and maintained. The right thing to add is not the most exotic control but the one that catches the most common failure modes — strong input validation and tight IAM are worth ten WAF rules.

Least Privilege

Every identity (user, group, service account) gets the minimum permissions needed to do its job, for the shortest duration that completes it. This is the principle that fails most often in real systems because the path of least resistance is to grant broad roles like roles/editor or roles/owner and move on.

On GCP this means: prefer predefined roles narrower than Editor (e.g., roles/storage.objectViewer rather than roles/storage.admin); when no predefined role fits, build a custom role with just the permissions needed; grant roles at the lowest scope that works (a single bucket, not the project); never grant Owner outside the org-admin pool.

For time-bounded elevation use Privileged Access Manager: an engineer requests an elevated role for a defined window with a justification, an approver grants it, and the role auto-expires. Standing access to dangerous roles vanishes. The audit trail captures both the request and the approval.

Workload identity has the same discipline: each Cloud Run service runs as its own service account with its own narrow set of permissions. The default Compute Engine service account, which has Editor on the whole project, is a vulnerability — replace it on every workload that runs your code.

Secrets Management Strategy

Secrets are anything an attacker would use to impersonate something — API keys, OAuth client secrets, database passwords, service account keys, signing keys. The rule is: secrets live in Secret Manager or Cloud KMS, never in code, never in environment variables baked into a container image, never in a configuration file checked into git.

The mature pattern is short-lived credentials issued from a trusted authority. For workload-to-workload calls on GCP, that authority is the metadata server — service accounts attached to workloads get scoped tokens automatically, no key file ever exists. For external workloads, Workload Identity Federation does the equivalent. Both eliminate the long-lived secret entirely; you cannot leak what does not exist.

When a long-lived secret is unavoidable (a third-party API key, a database password for a legacy service), store it in Secret Manager with a rotation schedule configured. Secret Manager does not rotate the secret itself — it publishes rotation notifications to Pub/Sub, and a small service you own performs the actual rotation. The application reads the latest version from Secret Manager on startup or on rotation events. The rotation cadence should match the value of the secret — a payment gateway key rotates more often than an internal-only API key.

Detect leaks proactively. Run the Sensitive Data Protection scanner across Cloud Storage buckets and BigQuery datasets to catch secrets that ended up in artifacts or logs. Configure Artifact Registry vulnerability scanning to flag images that contain credentials baked into layers.

Data Classification

Public
Default encryption, broad read. Marketing pages, public docs.
Internal
Google-managed keys, team-scoped IAM, admin audit logs. Most business data.
Confidential
Narrow IAM, Data Access audit logs on. Customer PII, financials.
Restricted
CMEK, minimal IAM, VPC Service Controls perimeter. Regulated secrets, keys.

Controls scale to data value. Classify first; then the encryption, IAM, audit, and network controls each follow from the tier.

Not all data deserves the same protection. A classification scheme — public, internal, confidential, restricted is a common one — lets the team apply controls proportionate to value. Restricted data (PII, payment card numbers, health records, secrets) gets the strictest controls; public data gets the loosest. Without classification, every project tries to apply restricted-tier controls to everything, fails, and ends up applying loose controls to everything instead.

Each tier maps to GCP controls. Restricted data lives in resources with customer-managed encryption keys (CMEK) in Cloud KMS, restricted IAM bindings, VPC Service Controls perimeters, and audit logging at the data-access tier in Cloud Logging. Confidential data may use Google-managed keys but still requires narrow IAM and audit. Public data still benefits from access logs but does not need encryption beyond the default.

Use the Sensitive Data Protection service (formerly Cloud DLP) to discover where restricted data actually lives. Engineers will inevitably copy a production extract into a "temporary" BigQuery table; an automated scan finds those and either redacts them or alerts the owner. Classification on paper is incomplete; classification verified by scanning is what counts.

Audit and Compliance

GCP emits audit logs automatically — Admin Activity logs for configuration changes are on by default and free; Data Access logs for reads of user data are off by default and billed, but should be enabled for restricted-tier resources. These logs flow to Cloud Logging and can be exported to BigQuery for long-term retention and SQL-based investigation. Without this trail, an incident investigation has no facts to work from.

For compliance frameworks (SOC 2, ISO 27001, HIPAA, PCI DSS, GDPR), the artifacts auditors want are: evidence of access reviews, evidence of vulnerability scans, evidence of change control, evidence of incident response. GCP supplies most of this through Security Command Center (continuous posture and finding management), Audit Logs (the access record), Cloud Build + Cloud Deploy attestations (change control), and Artifact Registry vulnerability scanning (CVE management). Wire these in from day one and the compliance audit is mostly a documentation exercise rather than a panic.

Security Command Center Premium adds Event Threat Detection and posture management — automated findings for risky configurations, suspicious activity, and misconfigured services. Triage discipline matters: the team must triage findings within a known window or the noise wins. A small number of high-severity findings closed weekly is worth more than a backlog of hundreds.

Network and Workload Hardening

Architectural choices at the network layer carry forward forever. The defaults that pay off: every workload sits inside a custom VPC (the auto-mode default network is fine for prototypes and dangerous for production); no public IPs on databases or internal services; egress to the internet routed through Cloud NAT with a controlled IP for allow-listing; Firewall rules default-deny with explicit allows; private endpoints (Private Service Connect, Private Google Access) for managed services so traffic never leaves the Google network.

Workload-level hardening: Cloud Run services with ingress: internal when they only serve internal callers; GKE clusters as private clusters with authorized networks for the control plane; Cloud SQL with private IP and IAM database authentication; Compute Engine instances with Shielded VM enabled. Each of these defaults moves the system from "publicly reachable until configured otherwise" to "private until explicitly exposed", which is the right polarity.

Security Anti-Patterns

Common security failure modes on GCP:

Security Anti-Patterns
  • Editor role for everyone — granting roles/editor at the project level because narrowing it is "too much work". Editor includes the ability to modify IAM bindings on most resources, which is effectively Owner. Use predefined roles and custom roles.
  • Service account keys checked into git — the most common credential leak. The fix is short-lived credentials via Workload Identity Federation; if a long-lived key is unavoidable, store it in Secret Manager and never commit it.
  • Default Compute Engine service account — every VM and Cloud Run service running as the project's default SA with Editor permissions. Replace it with a per-workload service account that has only what the workload needs.
  • Public databases — Cloud SQL or AlloyDB with a public IP and a hopeful firewall rule. The IP enumeration is constant; eventually a misconfigured rule lets traffic through. Use private IP and Cloud SQL Auth Proxy.
  • Trusting the VPC — assuming traffic from inside the VPC is safe because it came from a peer service. A compromised peer is exactly the scenario that needs IAM authorization on every call. Identity, not network position, is the authorization signal.
  • Secrets in environment variables baked into the image — visible to anyone who can pull the image, persistent in the registry forever, hard to rotate. Inject at runtime from Secret Manager.
  • Data Access logs disabled on restricted data — the default is off because the volume is high; for restricted data the discovery is exactly what makes an incident investigation possible. Enable it on the right resources, export to BigQuery for retention.
  • Security Command Center findings unaddressed — the dashboard is green-with-warnings forever; nobody triages. The findings stop being signals and start being noise. Treat findings like SLO burn — a weekly triage with closure as the success metric.
Best Practices
  • Default to identity, not network, as the authorization signal. IAP for users; service-account IAM for workloads; Workload Identity Federation for external systems.
  • Grant the narrowest role at the smallest scope for the shortest time. Use Privileged Access Manager for time-bounded elevation rather than standing grants.
  • Eliminate long-lived secrets where possible. Workload metadata tokens and federation cover most workload-to-workload cases without any secret ever existing.
  • Classify data first, then apply controls proportionate to the tier. Restricted data gets CMEK, VPC Service Controls, Data Access logs, and the tightest IAM.
  • Layer defenses: edge WAF (Cloud Armor), TLS-terminating load balancer, IAP for user traffic, application validation, narrow database IAM. No single layer is the last line.
  • Enable Admin Activity audit logs everywhere; enable Data Access logs on restricted resources; export to BigQuery for long-term retention and SQL-based investigation.
  • Run Security Command Center Premium and triage findings on a weekly cadence with closure as the success metric. A small triaged backlog is worth more than a large ignored one.
Comparable services AWS Security pillar · IAM + Security Hub + GuardDutyAzure Microsoft Defender for Cloud + Entra ID

Knowledge Check

A team is building an internal admin tool for company employees. Which authentication pattern is most aligned with zero trust on GCP?

  • Put the admin tool inside the corporate VPC and trust any request that originates from inside the network perimeter, since being on the internal network already proves the caller is a legitimate employee
  • Add a VPN tunnel between the office network and GCP, then expose the admin tool only to the VPN subnet
  • Front the tool with Identity-Aware Proxy, federate Cloud Identity to the corporate IdP, evaluate device posture, and let IAP allow each request based on identity + context — no network trust
  • Generate a static API key per employee and require them to include it in every request to the tool

A new team member needs to debug a production issue but has only Viewer at the project level. What is the right way to grant them temporary write access?

  • Permanently grant the new team member the broad Editor role at the project level so debugging is never blocked
  • Share a downloaded service account key carrying full Owner permissions with the new team member for the duration of the debug session, then simply ask them to delete the key file again once production is healthy
  • Use Privileged Access Manager — they request the elevated role with a justification, an approver grants it for a bounded window, the role auto-expires, and the audit trail captures the request and approval
  • Disable IAM authorization checks on the project for the duration of the debug window

A Cloud Run service needs to read from a Cloud Storage bucket. What is the right way to authenticate?

  • Generate a service account key with object-read access and store the full JSON key as a plaintext environment variable injected into the Cloud Run service container at deploy time
  • Use a shared API key stored in Secret Manager and have the service read it from there at startup
  • Run Cloud Run as a per-service service account with roles/storage.objectViewer on that specific bucket; the metadata server issues short-lived tokens — no key file ever exists
  • Make the Cloud Storage bucket publicly readable to simplify the access path from the service

A team is processing customer PII. Which combination of controls is appropriate for restricted-tier data?

  • Default Google-managed encryption and broad project-wide IAM bindings are sufficient on their own, because GCP already encrypts everything at rest by default
  • Customer-managed encryption keys in Cloud KMS, narrowly scoped IAM bindings, VPC Service Controls perimeters around the storing resource, Data Access audit logging exported to BigQuery, and discovery scans via Sensitive Data Protection
  • Public IP addresses on the database for fast direct access from anywhere, protected by a single firewall rule that allows only the company's office IP range, with the usual Google-managed default encryption at rest underneath the storage layer
  • The Editor role on the project for everyone who might ever need to touch the data, relying on the trust that they will all be careful

An engineer is preparing a SOC 2 audit. Which GCP control set covers the auditor's typical evidence requests?

  • A single static document describing the security policy in prose, reviewed and refreshed once annually by the team
  • Admin Activity + Data Access audit logs (the access record), Security Command Center findings and triage history (posture), Cloud Build + Cloud Deploy attestations (change control), Artifact Registry vulnerability scanning (CVE management) — wired in from day one, the audit becomes a documentation exercise
  • Disabling all logging across the project to minimize the surface area an auditor can ask probing questions about
  • Granting the external auditor the full Owner role on the project for the limited duration of the audit window, on the theory that broad access lets them gather whatever evidence they decide they need entirely on their own without ever having to file any further access requests with the platform team during the audit

A Cloud Run service runs as the default Compute Engine service account. What is the risk?

  • There is no real risk at all; running on the default Compute Engine service account is the officially recommended pattern
  • The default Compute Engine service account holds the Editor role on the project — a compromise of the workload gives the attacker broad write access across every resource in the project. Replace it with a per-workload service account holding only the permissions that workload needs.
  • The default service account has expired credentials, so the service will eventually fail to authenticate against any GCP API
  • The default Compute Engine service account cannot read from Cloud Storage at all by design; a separate custom service account must be created and granted storage roles before the workload can read any object at all, which is the reason teams keep hitting unexpected access-denied errors at runtime

Why is "defense in depth" not satisfied by adding Cloud Armor at the edge alone?

  • Cloud Armor at the edge adds request latency that breaks the application's strict performance budget
  • Cloud Armor is a paid product, and enabling it at the edge roughly doubles the application's monthly cost
  • A single layer of defense is fragile — if Cloud Armor misses a signature or is bypassed, there is nothing behind it. Defense in depth means app validation, narrow IAM on the database, KMS-wrapped keys, and VPC Service Controls layer on so no one failure owns the system
  • Cloud Armor only inspects and filters L4 network traffic such as TCP and UDP, so any L7 application-layer attack like SQL injection or cross-site scripting passes straight through the edge completely unprotected and reaches the backend application service entirely directly

You got correct