# Belief Registry

## Claims

### alb-backend-protocol-independent-of-frontend [IN] OBSERVATION
The ALB backend protocol (HTTP, HTTPS, HTTP/2, H2C) is independent of the client-facing frontend protocol.

### alb-external-managed-vs-external-scheme [IN] OBSERVATION
Global and regional ALBs use load balancing scheme `EXTERNAL_MANAGED`; classic ALBs use `EXTERNAL`. `EXTERNAL_MANAGED` backend services can attach to `EXTERNAL` forwarding rules but not vice versa.

### alb-forwarding-rule-single-port [IN] OBSERVATION
Each ALB forwarding rule supports only one port (1–65535); use multiple forwarding rules for multiple ports.

### alb-h2c-not-supported-classic [IN] OBSERVATION
H2C (HTTP/2 cleartext) is not supported on classic Application Load Balancers.

### alb-health-check-ip-ranges [IN] OBSERVATION
GFE health check probes originate from IP ranges `130.211.0.0/22` and `35.191.0.0/16`.

### alb-proxy-only-subnet-regional-only [IN] OBSERVATION
A proxy-only subnet (purpose `REGIONAL_MANAGED_PROXY`) is required only for regional external ALBs, not for global or classic ALBs.

### alb-regional-for-data-residency [IN] OBSERVATION
Regional external ALB is the appropriate choice for compliance/data residency requirements (single geolocation).

### alb-three-modes-global-classic-regional [IN] OBSERVATION
The external Application Load Balancer operates in three modes: global external ALB, classic ALB, and regional external ALB; mode is immutable after creation.

### ar-access-scopes-can-restrict-beyond-iam [IN] OBSERVATION
Compute Engine VM access scopes can further restrict Artifact Registry access beyond IAM roles — the default `read-only` scope blocks writes even if the SA has Writer role; `cloud-platform` scope is needed for push.

### ar-auth-configure-docker-per-hostname [IN] OBSERVATION
The `gcloud auth configure-docker HOSTNAME` command configures the Docker credential helper for a specific Artifact Registry hostname (e.g., `us-west1-docker.pkg.dev`).

### ar-cleanup-background-job-one-day [IN] OBSERVATION
Artifact Registry cleanup policy changes take effect within approximately one day via a background job.

### ar-cleanup-deletes-count-against-quota [IN] OBSERVATION
Artifact Registry cleanup deletions count against the per-project delete request quota.

### ar-cleanup-dry-run-requires-data-access-logs [IN] OBSERVATION
Artifact Registry cleanup dry run results appear in Data Access audit logs, which must be explicitly enabled with "data write" type to see results.

### ar-cleanup-keep-overrides-delete [IN] OBSERVATION
Artifact Registry cleanup keep policies always override delete policies when an artifact matches both.

### ar-cleanup-no-tag-support-treated-untagged [IN] OBSERVATION
Artifact formats that don't support tags are treated as `untagged` for cleanup policy evaluation.

### ar-cleanup-requires-admin-role [IN] OBSERVATION
Artifact Registry cleanup policies require `roles/artifactregistry.admin` (needs `artifactregistry.repositories.update` and `artifactregistry.versions.delete` permissions).

### ar-cleanup-standard-repos-only [IN] OBSERVATION
Artifact Registry cleanup policies can only be applied to standard repositories, not virtual repositories or at the project level.

### ar-cleanup-tagstate-tagged-required-for-prefixes [IN] OBSERVATION
In Artifact Registry cleanup policies, `tagState` must be `TAGGED` to use `tagPrefixes` in conditions.

### ar-cloud-build-default-read-write [IN] OBSERVATION
Cloud Build's default service account has read/write access to Artifact Registry.

### ar-cloudrun-cross-project-service-agent [IN] OBSERVATION
Cloud Run cross-project Artifact Registry access requires granting roles to the Cloud Run Service Agent (`service-PROJECT-NUMBER@serverless-robot-prod.iam.gserviceaccount.com`), not just the runtime service account.

### ar-cmek-encryption-supported [IN] OBSERVATION
Artifact Registry supports CMEK encryption via Cloud KMS (Google-managed encryption by default), and organization policy can enforce CMEK.

### ar-createonpush-roles-for-gcr-migration [IN] OBSERVATION
The `createOnPush` Artifact Registry roles (`roles/artifactregistry.createOnPushWriter` and `createOnPushRepoAdmin`) are specifically for Container Registry to Artifact Registry migration, allowing gcr.io repo creation on push.

### ar-cross-project-requires-explicit-grant [IN] OBSERVATION
Artifact Registry cross-project access is not automatic — roles must be explicitly granted in the Artifact Registry project.

### ar-default-compute-sa-read-only [IN] OBSERVATION
Compute Engine, GKE, and Cloud Run default service accounts get read-only access to Artifact Registry by default.

### ar-docker-image-path-format [IN] OBSERVATION
Artifact Registry Docker image paths follow the format `LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG`.

### ar-iam-roles-project-or-repository-level [IN] OBSERVATION
Artifact Registry IAM roles can be granted at two levels: project-wide (applies to all repositories) or repository-specific.

### ar-image-streaming-requires-same-region [IN] OBSERVATION
Artifact Registry image streaming only works when images are in the same region (or corresponding multi-region) as workloads.

### ar-no-egress-charge-same-region [IN] OBSERVATION
No egress charge from Artifact Registry to Google Cloud services in the same region.

### ar-orgs-after-may-2024-no-auto-editor [IN] OBSERVATION
Organizations created after May 3, 2024 enforce `iam.automaticIamGrantsForDefaultServiceAccounts` by default, preventing automatic Editor role grants to default service accounts.

### ar-public-repo-allUsers-reader-plus-quota [IN] OBSERVATION
Making an Artifact Registry repository public requires granting `roles/artifactregistry.reader` to `allUsers` and capping per-user quotas to prevent abuse.

### ar-remote-repos-cache-upstream-dependencies [IN] OBSERVATION
Artifact Registry remote repositories are read-only caching proxies for upstream public sources (Docker Hub, Maven Central, PyPI), enabling vulnerability scanning and provenance tracking on third-party dependencies.

### ar-replaces-container-registry [IN] OBSERVATION
Artifact Registry is Google Cloud's recommended registry, replacing Container Registry, with support for both container images and language packages (Go, Java, Node.js, Python, Ruby, Helm).

### ar-repo-format-immutable-after-creation [IN] OBSERVATION
Artifact Registry repository format (`--repository-format=docker`) is specified at creation and cannot be changed afterward.

### ar-repo-mode-immutable-after-creation [IN] OBSERVATION
Artifact Registry repository mode (standard, remote, or virtual) cannot be changed after creation.

### ar-repository-configuration-immutable-at-creation [IN] OBSERVATION
Artifact Registry repository format and mode are both immutable after creation — a repository's package type (Docker, Maven, npm) and operational mode (standard, remote, virtual) are permanent architectural decisions that cannot be corrected without recreating the repository and migrating all artifacts.

### ar-tags-attach-to-repos-not-artifacts [IN] OBSERVATION
Resource Manager tags attach to Artifact Registry repositories only, not individual artifacts, for conditional IAM access control.

### ar-virtual-repo-requires-sa-grant-to-upstreams [IN] OBSERVATION
Virtual repositories require explicit grants for the Artifact Registry service account to access upstream repositories.

### ar-virtual-repo-roles-cascade-all-upstreams [IN] OBSERVATION
Virtual repository IAM roles apply to all upstream repositories regardless of individual upstream repo permissions.

### ar-virtual-repos-priority-based-resolution [IN] OBSERVATION
Artifact Registry virtual repositories aggregate multiple repos behind a single endpoint with priority-based resolution order, mitigating dependency confusion attacks by prioritizing private over public upstream repos.

### auto-mode-vpc-creates-slash-20-subnets [IN] OBSERVATION
Auto mode VPC networks automatically create one /20 subnet per region from the 10.128.0.0/9 block.

### cannot-create-static-route-within-subnet-range [IN] OBSERVATION
A static route cannot be created with a destination that matches or fits within an existing subnet route range, and vice versa (unless using hybrid subnets).

### classic-vpn-no-ipv6-support [IN] OBSERVATION
Classic VPN does not support IPv6 — only HA VPN supports dual-stack and IPv6-only configurations.

### cloud-armor-adaptive-protection-requires-enterprise [IN] OBSERVATION
Adaptive Protection requires a Cloud Armor Enterprise subscription and is enabled per-security policy.

### cloud-armor-auto-ddos-global-external-alb [IN] OBSERVATION
DDoS protection is automatic (no configuration needed) for global external Application Load Balancers, classic Application Load Balancers, and external proxy Network Load Balancers.

### cloud-armor-edge-first-layered-defense [IN] OBSERVATION
Cloud Armor provides edge-first layered defense with four independent mechanisms: automatic DDoS protection at the Google Cloud edge for global external ALBs, prioritized rule evaluation ensuring highest-priority matches win, OWASP CRS 3.3.2-based WAF rules for application-layer filtering, and Enterprise-tier protection covering HTTP/HTTPS/HTTP2/QUIC protocols.

### cloud-armor-enterprise-ddos-protocols [IN] OBSERVATION
Cloud Armor Enterprise DDoS protection supports HTTP, HTTPS, HTTP/2, and QUIC protocols.

### cloud-armor-operates-at-edge [IN] OBSERVATION
Cloud Armor operates at the Google Cloud edge, filtering traffic before it reaches backend resources or enters VPC networks.

### cloud-armor-prioritized-rules [IN] OBSERVATION
Cloud Armor security policies use prioritized rules — the highest-priority matching rule wins.

### cloud-armor-supports-hybrid-multicloud [IN] OBSERVATION
Cloud Armor supports hybrid and multi-cloud deployments — it is not limited to GCP-hosted backends.

### cloud-armor-waf-owasp-crs-332 [IN] OBSERVATION
Cloud Armor preconfigured WAF rules are based on OWASP Core Rule Set 3.3.2 (CRS) and do not support XML body parsing.

### cloud-dns-admin-cannot-set-iam-policy [IN] OBSERVATION
`roles/dns.admin` can manage DNS records but cannot set IAM policies on zones (lacks `setIamPolicy` permission).

### cloud-dns-alias-records-skipped-bind-export [IN] OBSERVATION
ALIAS records are skipped when exporting Cloud DNS zones to BIND format.

### cloud-dns-at-symbol-literal [IN] OBSERVATION
The `@` symbol in Cloud DNS Console is treated literally, not as an apex alias — leave the DNS name field blank for apex records.

### cloud-dns-bind-import-trailing-dots [IN] OBSERVATION
BIND zone file imports require trailing dots on fully qualified domain names to avoid relative-name interpretation.

### cloud-dns-cname-exclusivity [IN] OBSERVATION
If a CNAME record exists at a DNS name, no other record type can coexist at that name.

### cloud-dns-configuration-cascading-side-effects [IN] OBSERVATION
Cloud DNS configuration changes have cascading side effects that extend beyond the modified resource: enabling an outbound server policy silently disables resolution of all private zones, forwarding zones, and peering zones; DNSSEC disabling must follow a registrar-first sequence or cause resolution failures for the entire zone; and CNAME exclusivity silently prevents coexistence with any other record type at the same name — making DNS changes among the highest-blast-radius operations in GCP networking.

### cloud-dns-cross-project-binding-same-org [IN] OBSERVATION
Cross-project binding zones work only within the same organization.

### cloud-dns-disable-dnssec-registrar-first [IN] OBSERVATION
Before disabling DNSSEC on a Cloud DNS managed zone, DNSSEC must be deactivated at the domain registrar first to avoid resolution failures.

### cloud-dns-dns64-well-known-prefix [IN] OBSERVATION
DNS64 synthesizes IPv6 addresses using the Well-Known Prefix `64:ff9b::/96` per RFC 6052 and requires NAT64 via Cloud NAT.

### cloud-dns-dnssec-authentication-not-encryption [IN] OBSERVATION
DNSSEC provides authentication against spoofing and cache poisoning, not encryption.

### cloud-dns-must-empty-zone-before-delete [IN] OBSERVATION
All records except SOA and NS must be removed before a Cloud DNS zone can be deleted via gcloud.

### cloud-dns-no-forwarding-for-public-zones [IN] OBSERVATION
Cloud DNS does not support DNS forwarding for public zones — public zones must be authoritative.

### cloud-dns-ns-soa-auto-created-cannot-delete [IN] OBSERVATION
NS and SOA records at the zone apex are auto-created and cannot be deleted via the API; they are removed only when the zone is deleted (per RFC 1034).

### cloud-dns-outbound-policy-disables-private-zones [IN] OBSERVATION
Using a Cloud DNS outbound server policy disables resolution of all Cloud DNS private zones, forwarding zones, peering zones, and Compute Engine internal DNS zones.

### cloud-dns-reverse-lookup-zones-non-rfc1918 [IN] OBSERVATION
Managed reverse lookup zones are needed for non-RFC 1918 PTR records on Compute Engine VMs.

### cloud-dns-security-limited-and-operationally-fragile [IN] OBSERVATION
Cloud DNS security is limited in scope (DNSSEC provides authentication against spoofing and cache poisoning only, not encryption) and operationally fragile (configuration changes have cascading side effects where enabling outbound server policies silently disables private zones, CNAME exclusivity creates implicit constraints) — security-relevant DNS changes can silently break zone resolution.

### cloud-dns-service-directory-zones-no-direct-records [IN] OBSERVATION
Service Directory zones cannot have records added directly — data comes from the Service Directory namespace.

### cloud-dns-shared-vpc-zones-in-host-project [IN] OBSERVATION
Shared VPC private/forwarding/peering zones must be created in the host project (or use cross-project binding in service projects).

### cloud-dns-transactions-atomic [IN] OBSERVATION
Cloud DNS transactions group multiple record changes into an atomic unit — the entire transaction succeeds or fails.

### cloud-dns-uses-anycast [IN] OBSERVATION
Cloud DNS uses anycast to serve zones from multiple global locations for high availability and low latency.

### cloud-hsm-fips-140-2-level-3 [IN] OBSERVATION
Cloud HSM keys are certified to FIPS 140-2 Level 3.

### cloud-hsm-quota-charged-to-key-project [IN] OBSERVATION
HSM QPM quota is consumed in the project containing the HSM keys, not necessarily the project making the cryptographic request.

### cloud-hsm-single-tenant-same-location-as-keyring [IN] OBSERVATION
Single-tenant HSM instances must be in the same location as the key ring that contains the keys.

### cloud-hsm-two-protection-levels [IN] OBSERVATION
Cloud HSM offers two protection levels: `hsm` (multi-tenant shared infrastructure) and `hsm-single-tenant` (dedicated HSM instance).

### cloud-hsm-uses-kms-frontend [IN] OBSERVATION
Cloud HSM uses Cloud KMS as its frontend — all HSM operations go through the KMS API, not a separate API.

### cloud-nat-gateway-public-or-private-not-both [IN] OBSERVATION
A single Cloud NAT gateway can be either Public NAT or Private NAT, never both; two separate gateways can serve the same subnet.

### cloud-nat-google-apis-use-pga-not-nat [IN] OBSERVATION
Traffic to Google APIs uses Private Google Access, not Public NAT, even when Public NAT is configured.

### cloud-nat-not-proxy-vm-based [IN] OBSERVATION
Cloud NAT is not based on proxy VMs; it is software-defined via the Andromeda networking stack and does not reduce network bandwidth per VM.

### cloud-nat-outbound-only-no-unsolicited-inbound [IN] OBSERVATION
Cloud NAT does not allow unsolicited inbound connections; it only handles outbound NAT and established inbound response packets.

### cloud-nat-private-nat-overlapping-ip-ranges [IN] OBSERVATION
Private NAT addresses the overlapping IP range problem between VPC networks, using NCC spokes for connectivity.

### cloud-nat-regional-resource-on-cloud-router [IN] OBSERVATION
Cloud NAT gateway is a regional resource configured on a Cloud Router.

### cloud-nat-serverless-requires-vpc-egress [IN] OBSERVATION
Serverless resources (Cloud Run, Cloud Run functions, App Engine) require Direct VPC egress or Serverless VPC Access to use Cloud NAT.

### cloud-nat-software-defined-regional-gateway [IN] OBSERVATION
Cloud NAT is a software-defined regional gateway on Cloud Router (not proxy VMs), routing internet egress while directing Google API traffic through Private Google Access instead, and requiring VPC egress configuration for serverless resources.

### cloud-source-repositories-deprecated-june-2024 [IN] OBSERVATION
Cloud Source Repositories is unavailable to new customers after June 17, 2024.

### cloud-vpn-cannot-route-public-internet [IN] OBSERVATION
Cloud VPN cannot be used to route traffic to the public internet — it is designed exclusively for private network communication.

### cloud-vpn-cipher-options-immutable [IN] OBSERVATION
Cloud VPN cipher configuration options are set at tunnel creation time and cannot be modified afterward — the tunnel must be deleted and recreated.

### cloud-vpn-ikev2-required-for-ipv6 [IN] OBSERVATION
IKEv2 is required for IPv6 traffic over Cloud VPN; IKEv1 does not support IPv6.

### cloud-vpn-regional-resource [IN] OBSERVATION
Cloud VPN is a regional resource — you select a region, not a zone, when creating a VPN gateway.

### cloud-vpn-site-to-site-only [IN] OBSERVATION
Cloud VPN is site-to-site only — it does not support client-to-gateway (dial-in) VPN connections.

### cloud-vpn-tunnel-250k-pps-max [IN] OBSERVATION
Each Cloud VPN tunnel supports up to 250,000 packets per second (combined ingress/egress), equivalent to 1–3 Gbps depending on packet size.

### cloudbuild-allow-exit-codes-precedence-over-allow-failure [IN] OBSERVATION
Cloud Build `allowExitCodes` takes precedence over `allowFailure`; if all steps have `allowFailure: true` and all fail, build status is still Successful.

### cloudbuild-binary-authorization-integration [IN] OBSERVATION
Cloud Build integrates with Binary Authorization to check build attestations and block unauthorized deployments to Cloud Run/GKE.

### cloudbuild-both-pool-types-scale-to-zero [IN] OBSERVATION
Both Cloud Build default and private pools are fully managed, pay-per-build-minute, and auto-scale to zero.

### cloudbuild-cmek-automatic-ephemeral [IN] OBSERVATION
Cloud Build CMEK compliance is automatic with no user configuration; an ephemeral encryption key is generated per build and destroyed after completion.

### cloudbuild-default-machine-e2-standard-2 [IN] OBSERVATION
Cloud Build default machine type is `E2_STANDARD_2` (2 CPUs); max disk size is 4000 GB.

### cloudbuild-default-pool-max-concurrency-30 [IN] OBSERVATION
Cloud Build default pool max concurrency is 30; private pool supports 100+.

### cloudbuild-default-timeout-60min-max-24h [IN] OBSERVATION
Cloud Build default build timeout is 60 minutes; maximum is 24 hours (format: duration with `s` suffix).

### cloudbuild-docker-engine-version-20-10-24 [IN] OBSERVATION
Cloud Build currently uses Docker engine version 20.10.24.

### cloudbuild-ephemeral-build-environment [IN] OBSERVATION
Cloud Build provisions a fresh VM per build and destroys it after completion — no residual state persists.

### cloudbuild-global-region-default-pool-only [IN] OBSERVATION
Cloud Build `global` region uses default pools; specifying a specific region requires a private pool in that region.

### cloudbuild-ignored-files-win-over-included [IN] OBSERVATION
In Cloud Build triggers, if a file matches both included and ignored file filters, the build is not invoked (ignored wins).

### cloudbuild-logs-default-both-logging-and-gcs [IN] OBSERVATION
Cloud Build logs go to both Cloud Logging and Cloud Storage by default; `logging: GCS_ONLY` stores only in GCS.

### cloudbuild-max-300-steps-100-args [IN] OBSERVATION
Cloud Build config supports maximum 300 build steps per config file and up to 100 arguments per step.

### cloudbuild-private-pool-64-machine-types [IN] OBSERVATION
Cloud Build private pools support 64 machine types compared to 5 for default pools.

### cloudbuild-private-pool-disable-public-ip [IN] OBSERVATION
Private pools can disable public IPs and provide static internal IP ranges; default pools cannot.

### cloudbuild-private-pool-region-fixed-at-creation [IN] OBSERVATION
Private pool builds run in the region where the pool is created, not where the build is submitted.

### cloudbuild-private-pool-vpc-peering-access [IN] OBSERVATION
Cloud Build private pools connect to customer VPC networks via VPC peering (private services access) to reach private resources.

### cloudbuild-queue-ttl-default-3600s [IN] OBSERVATION
Cloud Build `queueTtl` defaults to 3600s (1 hour) and ticks from `createTime`, while `timeout` ticks from `startTime`.

### cloudbuild-script-mutually-exclusive-args-entrypoint [IN] OBSERVATION
Cloud Build step `script` field is mutually exclusive with `args` and `entrypoint`.

### cloudbuild-shallow-clone-by-default [IN] OBSERVATION
Cloud Build performs a shallow clone (single commit) by default; must use `git fetch --unshallow` build step for full history.

### cloudbuild-skip-ci-commit-message [IN] OBSERVATION
Including `[skip ci]` or `[ci skip]` in a commit message prevents Cloud Build trigger invocation.

### cloudbuild-slsa-level-3-containers [IN] OBSERVATION
Cloud Build meets SLSA level 3 requirements for container images with verifiable build provenance.

### cloudbuild-steps-run-on-cloudbuild-network [IN] OBSERVATION
Cloud Build steps run in Docker containers connected via the `cloudbuild` local Docker network, enabling inter-step communication.

### cloudbuild-steps-serial-by-default [IN] OBSERVATION
Cloud Build steps run serially by default; use `id` and `waitFor` fields for parallel execution (`waitFor: ['-']` starts immediately).

### cloudbuild-supply-chain-security-ephemeral-attested [IN] OBSERVATION
Cloud Build achieves supply chain security through three mechanisms: ephemeral build VMs with no residual state, SLSA level 3 attestation providing verifiable container provenance, and trigger service account precedence preventing config-level privilege escalation.

### cloudbuild-trigger-branch-tag-re2-regex [IN] OBSERVATION
Cloud Build trigger branch and tag patterns use RE2 regex syntax; forward slashes cannot be used in tags.

### cloudbuild-trigger-sa-overrides-config-sa [IN] OBSERVATION
Cloud Build trigger service account overrides any service account specified in the build config file.

### cloudbuild-user-substitution-keys-underscore-prefix [IN] OBSERVATION
Cloud Build user-defined substitution keys must start with an underscore (`_`); `dynamicSubstitutions` must be `true` for bash parameter expansions with trigger-invoked builds.

### cloudbuild-workspace-auto-mounted [IN] OBSERVATION
The `/workspace` volume is automatically mounted in all Cloud Build steps; additional volumes must be explicitly declared.

### cloudrun-authentication-services-not-jobs [IN] OBSERVATION
Cloud Run authentication model applies to services only, not jobs.

### cloudrun-autoscaler-targets-60pct [IN] OBSERVATION
Cloud Run autoscaler targets 60% CPU utilization and 60% of maximum concurrency, both measured over a one-minute window.

### cloudrun-billing-100ms-granularity [IN] OBSERVATION
Cloud Run usage is billed rounded up to the nearest 100 milliseconds; jobs have a minimum billing of 1 minute.

### cloudrun-caches-image-at-deploy-time [IN] OBSERVATION
Cloud Run imports and caches the container image at deploy time; images are not pulled from the registry when new instances start.

### cloudrun-compute-flexible-cuds-shared [IN] OBSERVATION
Compute Flexible CUDs apply across Cloud Run, GKE, and Compute Engine; 3-year flexible CUD offers ~46% savings on CPU.

### cloudrun-concurrency-1-hurts-spike-scaling [IN] OBSERVATION
Setting Cloud Run concurrency to 1 negatively impacts scaling performance during traffic spikes due to cold start overhead per request.

### cloudrun-concurrency-applies-to-services-only [IN] OBSERVATION
The Cloud Run concurrency setting applies only to services (request-driven), not to jobs.

### cloudrun-concurrency-default-80x-vcpus [IN] OBSERVATION
Cloud Run default concurrency is 80× the number of vCPUs when deployed via gcloud/Terraform (new services only); 80 when deployed via Console.

### cloudrun-concurrency-is-ceiling-not-target [IN] OBSERVATION
The Cloud Run concurrency setting is a maximum limit (ceiling), not a guarantee — Cloud Run may send fewer requests if CPU is already highly utilized.

### cloudrun-concurrency-max-1000 [IN] OBSERVATION
Cloud Run maximum configurable concurrent requests per instance is 1000.

### cloudrun-container-image-deterministic-at-deploy [IN] OBSERVATION
Cloud Run achieves deterministic container execution by resolving image tags to digests and caching images at deploy time — revisions always serve the exact image deployed regardless of subsequent tag mutations in the registry or registry outages after deployment.

### cloudrun-cross-project-secret-uses-project-number [IN] OBSERVATION
Cross-project secret references in Cloud Run use `projects/PROJECT_NUMBER/secrets/SECRET_NAME` format (project number, not ID, in YAML/gcloud; Terraform uses project ID).

### cloudrun-default-invoke-roles [IN] OBSERVATION
Only four default roles can invoke a Cloud Run service: Project Owner, Project Editor, Cloud Run Admin, and Cloud Run Invoker (`roles/run.invoker`).

### cloudrun-deploy-required-roles [IN] OBSERVATION
Deploying to Cloud Run requires `roles/run.developer`, `roles/iam.serviceAccountUser`, and `roles/artifactregistry.reader`; cross-project additionally needs `roles/iam.serviceAccountTokenCreator`.

### cloudrun-direct-vpc-egress-more-ip-addresses [IN] OBSERVATION
Direct VPC egress uses more IP addresses than Serverless VPC Access connectors in most cases.

### cloudrun-direct-vpc-egress-network-tags-per-service [IN] OBSERVATION
Direct VPC egress supports network tags per service/job revision for fine-grained firewall rules; connectors share tags across all services using the same connector.

### cloudrun-direct-vpc-egress-recommended [IN] OBSERVATION
Direct VPC egress is the recommended method for Cloud Run outbound traffic to a VPC, requiring no connector VMs, with lower latency and scales to zero cost.

### cloudrun-docker-hub-cached-1-hour [IN] OBSERVATION
Docker Hub images used by Cloud Run are cached for up to 1 hour.

### cloudrun-filesystem-ephemeral-in-memory [IN] OBSERVATION
Cloud Run container instances have an ephemeral in-memory writable file system overlay that does not persist across shutdowns.

### cloudrun-free-tier-per-billing-account [IN] OBSERVATION
The Cloud Run free tier is per billing account (not per project), aggregated across projects, and resets monthly.

### cloudrun-gpu-no-cud-discounts [IN] OBSERVATION
Cloud Run GPU workloads do not qualify for committed use discount (CUD) pricing.

### cloudrun-iam-denied-requests-not-billed [IN] OBSERVATION
Requests denied by IAM policy are not billed in Cloud Run.

### cloudrun-idle-instance-retention-15min [IN] OBSERVATION
Cloud Run idle instances may remain up to 15 minutes (10 minutes for GPU-enabled instances) after handling requests to absorb traffic spikes.

### cloudrun-image-layer-size-limit-9-9gb [IN] OBSERVATION
Cloud Run has a 9.9 GB max container image layer size when deploying from Docker Hub or Artifact Registry remote repository with an external registry.

### cloudrun-internet-egress-requires-vpc-plus-nat-chain [IN] OBSERVATION
Cloud Run internet egress for VPC-connected workloads requires chaining two regional constructs: Direct VPC egress (preferred over connector VMs) for outbound-only VPC access, then Cloud NAT on Cloud Router for internet-bound traffic — neither alone is sufficient for serverless-to-internet connectivity.

### cloudrun-jobs-env-vars-task-index-count [IN] OBSERVATION
Cloud Run jobs automatically inject `CLOUD_RUN_TASK_INDEX` (0-based) and `CLOUD_RUN_TASK_COUNT` environment variables per task.

### cloudrun-jobs-max-10000-tasks [IN] OBSERVATION
A Cloud Run job supports 1–10,000 independent tasks that can run in parallel; default is 1 task.

### cloudrun-jobs-name-49-chars-immutable [IN] OBSERVATION
Cloud Run job names must be 49 characters or less, unique per region and project, and cannot be changed after creation.

### cloudrun-jobs-retries-default-3-max-10 [IN] OBSERVATION
Cloud Run jobs default to 3 retries per failed task, configurable from 0 to 10.

### cloudrun-jobs-second-gen-execution-env [IN] OBSERVATION
Cloud Run jobs always use the second generation execution environment.

### cloudrun-jobs-task-timeout-default-10m-max-168h [IN] OBSERVATION
Cloud Run job default task timeout is 10 minutes; maximum is 168 hours (7 days); GPU tasks have a maximum timeout of 1 hour.

### cloudrun-jobs-up-to-10-containers-per-instance [IN] OBSERVATION
Cloud Run jobs support up to 10 containers per instance (including main container) as sidecars, sharing network namespace.

### cloudrun-max-instances-per-revision [IN] OBSERVATION
Cloud Run max instances is a per-revision limit, not per service; traffic splits and deployments can cause total instances to exceed the per-revision limit.

### cloudrun-pending-requests-timeout-429 [IN] OBSERVATION
When Cloud Run max instances is reached, requests queue for up to 3.5× average container startup time or 10 seconds (whichever is greater); excess requests return HTTP 429.

### cloudrun-pricing-tier1-vs-tier2-regions [IN] OBSERVATION
Cloud Run pricing depends on region tier: Tier 1 (cheaper, includes us-central1, europe-west1) and Tier 2 (more expensive, includes Sydney, London, Frankfurt, São Paulo).

### cloudrun-regional-redundant-across-zones [IN] OBSERVATION
Cloud Run is regional — infrastructure runs in a specific region, redundantly available across all zones within that region.

### cloudrun-request-based-billing-is-default [IN] OBSERVATION
Request-based billing is the default for Cloud Run services; instance-based billing must be opted into.

### cloudrun-revisions-immutable-tag-resolved-to-digest [IN] OBSERVATION
Cloud Run revisions are immutable; image tags are resolved to a digest at deploy time, and the revision always serves that specific digest.

### cloudrun-scale-from-zero-requires-request [IN] OBSERVATION
Cloud Run scaling from zero can only be triggered by a request, not by CPU; CPU-only workloads with instance-based billing cannot self-wake without min instances > 0 or a wake-up request.

### cloudrun-secret-env-var-failure-blocks-startup [IN] OBSERVATION
If a Cloud Run environment variable secret fails to load, the instance will not start; volume mount failures only surface at read time.

### cloudrun-secret-env-var-resolved-at-startup [IN] OBSERVATION
Cloud Run environment variable secrets are resolved once at instance startup time; Google recommends pinning to a specific version rather than `latest`.

### cloudrun-secret-fail-fast-startup [IN] OBSERVATION
Cloud Run's Secret Manager integration creates fail-fast startup semantics: the recommended production pattern (API access with pinned versions) defers resolution to runtime, but env-var-bound secrets that fail to load prevent instance startup entirely — forcing a choice between startup reliability and the best-practice access pattern.

### cloudrun-secret-lifecycle-startup-rotation-tension [IN] OBSERVATION
Cloud Run services reference Secret Manager secrets at startup, failing fast if secrets are unavailable. When secrets are rotated, running instances retain the old version until new instances are created, creating a window where old and new secret versions coexist across the fleet.

### cloudrun-secret-requires-secret-accessor-role [IN] OBSERVATION
The Cloud Run service account needs `roles/secretmanager.secretAccessor` on each referenced secret, verified at deployment time.

### cloudrun-secret-volume-mount-fetches-on-read [IN] OBSERVATION
Cloud Run volume-mounted secrets fetch the secret value from Secret Manager on every read, making them compatible with secret rotation.

### cloudrun-secret-volume-ownership-gen-difference [IN] OBSERVATION
In Cloud Run first-gen single-container, the container identity owns the secret volume; in second-gen and first-gen multi-container, root owns the volume.

### cloudrun-service-name-49-char-limit-immutable [IN] OBSERVATION
Cloud Run service names must be 49 characters or less, unique per region and project, and cannot be changed after creation.

### cloudrun-services-private-by-default [IN] OBSERVATION
Cloud Run services are deployed as private by default, requiring authentication credentials in requests.

### cloudrun-services-replace-overwrites-entire-config [IN] OBSERVATION
`gcloud run services replace` overwrites the entire service configuration — changes made via Console or gcloud CLI can be lost.

### cloudrun-services-run-app-endpoint [IN] OBSERVATION
Cloud Run services provide a unique HTTPS endpoint on `*.run.app` with managed TLS, WebSockets, HTTP/2, and gRPC support.

### cloudrun-sidecar-cpu-summed [IN] OBSERVATION
For Cloud Run instances with sidecars (multiple containers), instance CPU allocation is the sum of all container CPU limits.

### cloudrun-source-deploy-uses-buildpacks [IN] OBSERVATION
Cloud Run source-based deployment uses Google Cloud buildpacks (open source) and supports Go, Node.js, Python, Java, .NET, and Ruby.

### cloudrun-three-resource-types [IN] OBSERVATION
Cloud Run has three resource types: services (HTTP request handling), jobs (batch tasks to completion), and worker pools (pull-based background processing, in Preview).

### cloudrun-two-billing-modes [IN] OBSERVATION
Cloud Run services have two billing modes: request-based (charged only during request processing + per-request fee) and instance-based (charged for full instance lifetime, no per-request fee).

### cloudrun-update-vs-set-vs-clear-secrets [IN] OBSERVATION
`--update-secrets` adds/updates secrets; `--set-secrets` replaces all secrets; `--clear-secrets` removes all; `--remove-secrets` removes specific ones.

### cloudrun-vcpu-hotspot-single-threaded [IN] OBSERVATION
Single-threaded apps on multi-vCPU Cloud Run instances cause vCPU hotspots where average CPU looks low but one core is maxed, misleading the CPU autoscaler.

### cloudrun-vpc-connector-uses-compute-engine-vms [IN] OBSERVATION
Serverless VPC Access connectors require provisioned Compute Engine VM instances that add cost and maintenance overhead.

### cloudrun-vpc-egress-direct-over-connector [IN] OBSERVATION
Cloud Run VPC egress should use Direct VPC egress over Serverless VPC Access connectors: direct egress requires no connector VMs (avoiding Compute Engine cost and maintenance), has lower latency, and both methods handle only outbound traffic.

### cloudrun-vpc-egress-outbound-only [IN] OBSERVATION
Both Direct VPC egress and Serverless VPC Access connectors handle only outbound traffic from Cloud Run; inbound from VPC routes through a load balancer.

### cloudrun-worker-pools-no-autoscale-no-url [IN] OBSERVATION
Cloud Run worker pools do not autoscale automatically (require manual scaling or custom autoscaler) and have no public HTTP endpoint or URL.

### cloudrun-worker-pools-split-instances-not-traffic [IN] OBSERVATION
Cloud Run worker pools manage rollouts by splitting instances between revisions, not by splitting traffic.

### cloudsql-auth-proxy-recommended-connection [IN] OBSERVATION
Cloud SQL Auth Proxy is the recommended secure connection method for applications connecting to Cloud SQL instances.

### cloudsql-backups-encrypted-by-default [IN] OBSERVATION
Cloud SQL backups are encrypted by default using Google-managed or Customer-Managed Encryption Keys (CMEK).

### cloudsql-backups-incremental-after-first [IN] OBSERVATION
All Cloud SQL backups after the first are incremental; when the oldest backup is deleted, the next oldest expands into a full backup.

### cloudsql-cascading-replicas-4-levels-8-siblings [IN] OBSERVATION
Cascading replicas support up to 4 levels in the hierarchy (including primary) and up to 8 siblings per parent.

### cloudsql-deleted-instance-recovery-4-days [IN] OBSERVATION
Cloud SQL retains deleted instance backups for 4 days; Customer Care can restore with original IP address.

### cloudsql-enhanced-backups-use-backup-dr-service [IN] OBSERVATION
Enhanced backups use Backup and DR Service for centralized management; standard backups are stored in the same project as the instance.

### cloudsql-enterprise-plus-sub-second-maintenance [IN] OBSERVATION
Cloud SQL Enterprise Plus edition supports sub-second downtime during maintenance (for MySQL and PostgreSQL).

### cloudsql-final-backup-default-retention-30-days [IN] OBSERVATION
Cloud SQL final backup default retention is 30 days; customizable 1–365 days (standard) or 1 day–10 years (enhanced).

### cloudsql-ha-costs-double [IN] OBSERVATION
Cloud SQL HA instances cost 2x a standalone instance (CPU, RAM, and storage).

### cloudsql-ha-doubles-cost-with-idle-standby [IN] OBSERVATION
Cloud SQL HA doubles infrastructure cost for automatic failover but the standby instance is idle — it cannot serve read queries, making read replicas in a third zone necessary for both read scaling and maximum resilience.

### cloudsql-ha-failover-60-seconds [IN] OBSERVATION
Cloud SQL HA failover takes approximately 60 seconds of downtime.

### cloudsql-ha-primary-destroyed-on-failover [IN] OBSERVATION
After Cloud SQL HA failover, the original primary is destroyed and recreated as the new standby.

### cloudsql-ha-read-replicas-third-zone-best-practice [IN] OBSERVATION
Best practice is to place Cloud SQL read replicas in a third zone, different from both the primary and standby zones.

### cloudsql-ha-replicas-complementary-not-alternative [IN] OBSERVATION
Cloud SQL HA and read replicas are complementary, not interchangeable: HA doubles cost with an idle standby for automatic failover, while replicas are strictly read-only without failover capability or independent backups — achieving both availability and read scaling requires deploying both patterns, ideally with replicas in a third zone.

### cloudsql-ha-same-ip-after-failover [IN] OBSERVATION
Cloud SQL HA uses a shared static IP; applications reconnect using the same IP/connection string after failover.

### cloudsql-ha-standby-different-zone-same-region [IN] OBSERVATION
Cloud SQL HA uses a standby VM in a different zone within the same region (not a different region).

### cloudsql-ha-standby-no-read-queries [IN] OBSERVATION
The Cloud SQL HA standby instance cannot serve read queries.

### cloudsql-ha-synchronous-replication [IN] OBSERVATION
Cloud SQL HA uses synchronous replication to regional persistent disk, not asynchronous replication.

### cloudsql-instance-vm-plus-persistent-disk [IN] OBSERVATION
Each Cloud SQL instance runs on a dedicated VM with an attached persistent disk and a static IP address.

### cloudsql-legacy-ha-deprecated-jan-2025 [IN] OBSERVATION
Cloud SQL legacy HA (failover replica-based) was deprecated January 13, 2025; automatic migration to regional persistent disk HA began May 1, 2025.

### cloudsql-ondemand-backups-retained-indefinitely [IN] OBSERVATION
On-demand Cloud SQL backups (standard option) are retained indefinitely until explicitly deleted.

### cloudsql-private-ip-cannot-be-removed [IN] OBSERVATION
Private IP cannot be removed from a Cloud SQL instance once configured.

### cloudsql-private-ip-existing-instance-restart [IN] OBSERVATION
Configuring private IP on an existing Cloud SQL instance causes a restart with a few minutes of downtime.

### cloudsql-private-ip-inherits-peering-constraints [IN] OBSERVATION
Cloud SQL private IP connectivity inherits all VPC peering limitations: non-transitivity restricts multi-network reach, non-RFC1918 ranges need manual authorization, and the required private services access creates an implicit peering dependency.

### cloudsql-private-ip-non-rfc1918-not-auto-authorized [IN] OBSERVATION
Non-RFC 1918 address ranges are not automatically authorized for Cloud SQL private IP connections and are not learned via peering by default.

### cloudsql-private-ip-replica-inherits-peering [IN] OBSERVATION
A Cloud SQL replica inherits its private IP status and VPC peering configuration from the primary instance.

### cloudsql-private-ip-requires-compute-network-admin [IN] OBSERVATION
Cloud SQL private IP setup requires `roles/compute.networkAdmin` for managing private services access and the Service Networking API must be enabled.

### cloudsql-private-ip-requires-vpc [IN] OBSERVATION
Cloud SQL private IP connectivity requires a VPC network; public IP is internet-accessible.

### cloudsql-private-ip-slash24-per-service [IN] OBSERVATION
Each Google Cloud service creates a /24 subnet from the customer's allocated IP range; a /24 supports approximately 50 Cloud SQL instances.

### cloudsql-private-ip-uses-private-services-access [IN] OBSERVATION
Cloud SQL private IP uses private services access to create private connections between a customer's VPC and Google's service producer VPC.

### cloudsql-private-ip-vpc-peering-not-transitive [IN] OBSERVATION
VPC Network Peering used by Cloud SQL private IP is not transitive — only directly peered networks can communicate.

### cloudsql-private-networking-doubly-constrained-by-peering [IN] OBSERVATION
Cloud SQL private IP connectivity inherits VPC peering constraints (non-transitivity, 25 peering limit, non-RFC1918 allocation restrictions) from private services access, adding networking complexity beyond what the database service itself requires.

### cloudsql-production-architecture-requires-triple-investment [IN] OBSERVATION
Production Cloud SQL architecture requires concurrent investment across three dimensions: HA doubles cost with an idle standby that cannot serve reads, read replicas add scaling but block backup restores and cannot failover, and private networking inherits VPC peering constraints (non-transitivity, no overlapping subnets) — making the path from standalone instance to production-ready database a multiplicative increase in cost, complexity, and networking constraints.

### cloudsql-production-high-cost-floor-low-scaling-ceiling [IN] OBSERVATION
Cloud SQL production architecture has simultaneously high cost floor and low scaling ceiling: the triple investment baseline (2x HA cost with idle standby, read replicas for scaling, private networking with peering constraints) creates a significant minimum infrastructure cost, while read scaling is capped at 10 direct replicas that cannot be independently backed up and provide no failover — bounding both the entry cost and maximum throughput of a production deployment.

### cloudsql-replicas-cannot-delete-primary-with-replicas [IN] OBSERVATION
Cannot delete a Cloud SQL primary instance without first promoting or deleting all its replicas.

### cloudsql-replicas-cannot-restore-backup-with-replicas [IN] OBSERVATION
Cannot restore a Cloud SQL primary from backup while replicas exist.

### cloudsql-replicas-constrained-read-scaling [IN] OBSERVATION
Cloud SQL read replicas provide constrained read scaling: maximum 10 direct replicas per primary, replicas cannot be backed up independently, replicas are strictly read-only with no failover capability, and creating replicas requires backups and binary logging enabled on the primary.

### cloudsql-replicas-gtid-mandatory [IN] OBSERVATION
Cloud SQL uses GTID-based replication for all replication; it cannot be disabled.

### cloudsql-replicas-max-10-direct [IN] OBSERVATION
Maximum of 10 direct read replicas per Cloud SQL primary instance; cascading replicas allow scaling beyond this limit.

### cloudsql-replicas-no-backup-support [IN] OBSERVATION
Cloud SQL replicas do not support backups; backups are maintained on the primary instance only. Promoted replicas need their own backup configuration.

### cloudsql-replicas-no-backups-on-replicas [IN] OBSERVATION
Backups cannot be configured on Cloud SQL read replicas.

### cloudsql-replicas-read-only-no-failover [IN] OBSERVATION
Cloud SQL read replicas are read-only and do not provide failover — HA configuration is required for failover.

### cloudsql-replicas-require-backups-and-binlog [IN] OBSERVATION
Creating a read replica requires automated backups enabled, binary logging (PITR) enabled, and at least one backup after binary logging was enabled.

### cloudsql-restore-requires-same-db-version [IN] OBSERVATION
Cloud SQL restores can only target instances with the same database version as when the backup was taken.

### cloudsql-supports-three-engines [IN] OBSERVATION
Cloud SQL supports exactly three database engines: MySQL, PostgreSQL, and SQL Server.

### cloudsql-three-update-types [IN] OBSERVATION
Cloud SQL has three system update types: hardware updates (no downtime, live migration), online updates (no downtime), and maintenance updates (require restart, cause downtime).

### cmek-autokey-creates-hsm-keys-by-default [IN] OBSERVATION
Cloud KMS Autokey automatically creates Cloud HSM keys by default; Autokey keys are functionally identical to manually created Cloud HSM keys.

### cmek-crypto-shredding-destroys-data [IN] OBSERVATION
Destroying a CMEK makes all data encrypted by it permanently inaccessible, enabling crypto-shredding for off-boarding or security remediation.

### cmek-customer-owns-keys-envelope-encryption [IN] OBSERVATION
CMEK uses server-side, symmetric, envelope encryption with customer-controlled 256-bit AES-GCM keys; key material never leaves the Cloud KMS system boundary.

### cmek-key-ring-location-near-resources-separate-project [IN] OBSERVATION
CMEK key ring location should be geographically near protected resources; using a separate project for keys supports separation of duties.

### cmek-revoking-access-or-disabling-key-makes-data-inaccessible [IN] OBSERVATION
Revoking the service agent's CryptoKey Encrypter/Decrypter role, or disabling/destroying the CMEK key, makes data inaccessible — some services can experience permanent data loss if the key remains inaccessible too long.

### cmek-service-agent-encrypts-not-end-user [IN] OBSERVATION
Each project's service agent performs CMEK encrypt/decrypt operations; end users do not need the CryptoKey Encrypter/Decrypter role to access CMEK-protected resources.

### dedicated-interconnect-99-9-sla-requires-2-connections-same-metro [IN] OBSERVATION
Dedicated Interconnect 99.9% SLA requires at least 2 connections in the same metro but in different edge availability domains.

### dedicated-interconnect-99-99-sla-requires-4-connections-2-metros [IN] OBSERVATION
Dedicated Interconnect 99.99% SLA requires at least 4 connections: 2 in each of 2 different metros, each pair in different edge availability domains.

### dedicated-interconnect-circuit-types-10g-100g-400g [IN] OBSERVATION
Dedicated Interconnect supports 10-Gbps (10GBASE-LR), 100-Gbps (100GBASE-LR4), and 400-Gbps (400GBASE-LR4) circuits, all single-mode fiber with max 10 km fiber length.

### dedicated-interconnect-google-api-traffic-always-1440-mtu [IN] OBSERVATION
Google API client library traffic always uses 1440 MTU regardless of the VLAN attachment MTU setting on Dedicated Interconnect.

### dedicated-interconnect-jumbo-frames-unencrypted-only [IN] OBSERVATION
Jumbo frames (8896 MTU) on Dedicated Interconnect are only supported on unencrypted VLAN attachments.

### dedicated-interconnect-lacp-required [IN] OBSERVATION
LACP is required for Dedicated Interconnect even for a single circuit.

### dedicated-interconnect-link-type-immutable [IN] OBSERVATION
Dedicated Interconnect link type (e.g., 10G, 100G, 400G) cannot be changed after connection creation — a new connection must be created.

### dedicated-interconnect-max-8-circuits-per-connection [IN] OBSERVATION
Dedicated Interconnect supports 1–8 circuits per connection, yielding max 80 Gbps (10G), 800 Gbps (100G), or 3200 Gbps (400G) per connection.

### default-route-deletion-does-not-fully-isolate [IN] OBSERVATION
Deleting the system-generated default route (0.0.0.0/0) does not fully isolate a VPC from the internet because external passthrough NLB paths are independent of it.

### dynamic-routing-mode-regional-vs-global [IN] OBSERVATION
Dynamic routing mode (regional vs global) determines whether Cloud Router dynamic routes apply in one region or all regions.

### ekm-coordinated-keys-require-vpc-connection [IN] OBSERVATION
Coordinated (Cloud KMS-managed) EKM keys require a VPC connection; manual mode is required for internet connections.

### ekm-double-encryption-symmetric-keys [IN] OBSERVATION
Cloud EKM symmetric encryption uses both internal key material (Cloud KMS) and external key material (EKM) — losing either makes data permanently unrecoverable.

### ekm-external-key-material-never-leaves-customer [IN] OBSERVATION
Cloud EKM external key material never leaves the customer's EKM and is never sent to Google.

### ekm-key-access-justifications-reason-codes [IN] OBSERVATION
Key Access Justifications optionally integrates with Cloud EKM so each request includes a reason code, and the EKM can allow or deny based on justification.

### ekm-no-auto-rotation-manual-keys [IN] OBSERVATION
Automatic rotation is not supported for manually managed external keys; only coordinated EKM keys support automatic rotation.

### ekm-protection-levels-external-vs-external-vpc [IN] OBSERVATION
Cloud EKM has two protection levels: EXTERNAL (internet) and EXTERNAL_VPC (VPC); VPC mode is available in regional locations only, not multi-regional.

### ext-nlb-backends-same-region-project-different-vpc [IN] OBSERVATION
External passthrough NLB backends must be in the same region and project but can be in different VPC networks.

### ext-nlb-direct-server-return [IN] OBSERVATION
External passthrough Network Load Balancers use direct server return (DSR) — responses bypass the load balancer and go directly from backend VMs to clients.

### ext-nlb-ipv6-requires-premium-tier [IN] OBSERVATION
External passthrough NLB IPv6 support requires Premium Tier and uses `/96` ranges from external dual-stack subnets.

### ext-nlb-l3-default-one-per-ip [IN] OBSERVATION
Only one `L3_DEFAULT` forwarding rule is allowed per IP address; it acts as a fallback when more specific forwarding rules exist.

### ext-nlb-neg-any-nic-ig-nic0-only [IN] OBSERVATION
External passthrough NLB instance groups always use `nic0`; zonal NEGs (`GCE_VM_IP`) can target any network interface.

### ext-nlb-traffic-steering-source-ip-ranges [IN] OBSERVATION
External passthrough NLB traffic steering uses `sourceIPRanges` on forwarding rules (up to 64 ranges) with a mandatory parent forwarding rule.

### external-ipv6-requires-premium-tier [IN] OBSERVATION
External IPv6 addresses on VPC subnets require Premium Tier networking.

### gce-arm-instances-no-smt-vcpu-equals-core [IN] OBSERVATION
Arm-based instances (N4A, C4A, T2A) have no SMT — each vCPU equals one physical core.

### gce-autohealing-health-checks-more-conservative [IN] OBSERVATION
MIG autohealing health checks should be more conservative than load balancing health checks; autohealing triggers VM recreation while LB health checks only route traffic away.

### gce-bare-metal-identified-by-metal-suffix [IN] OBSERVATION
Bare metal instances are identified by machine type names ending in `-metal` and run without a hypervisor.

### gce-community-images-no-google-support [IN] OBSERVATION
Community-supported OS images (Fedora, FreeBSD, openSUSE) have no licensing charges but no Google support.

### gce-container-on-mig-uses-cos-with-docker [IN] OBSERVATION
Container deployment on MIGs uses Container-Optimized OS with Docker, provisioned automatically when a container image is specified in the instance template.

### gce-custom-images-incur-storage-charges [IN] OBSERVATION
Custom OS images incur image storage charges in the project that owns them.

### gce-custom-images-storage-charges-only [IN] OBSERVATION
Custom OS images only incur storage charges; premium OS images have additional cost

### gce-custom-machine-types-n-e-series-only [IN] OBSERVATION
Custom machine types are only available for N and E series, with a 5% price premium over predefined types.

### gce-disk-billed-provisioned-capacity-creation-to-deletion [IN] OBSERVATION
Block storage is billed for provisioned capacity from creation to deletion, even if the disk is unattached or the VM is stopped.

### gce-durable-disks-attach-detach-no-downtime [IN] OBSERVATION
Durable disks can be attached to and detached from running instances without downtime.

### gce-durable-disks-encrypted-at-rest-and-transit [IN] OBSERVATION
Durable block storage is encrypted at rest and in transit by default, with support for customer-managed encryption keys.

### gce-durable-disks-network-attached [IN] OBSERVATION
Durable block storage (Hyperdisk and Persistent Disk) are network-attached devices transmitting data over Google's networks, not physically attached like Local SSD.

### gce-e2-lowest-cost-auto-selected-processor [IN] OBSERVATION
E2 is the lowest-cost machine series; the processor (Intel or AMD) is auto-selected by Google.

### gce-ephemeral-compute-storage-workload-tier [IN] OBSERVATION
GCE provides a fully ephemeral high-performance workload tier by combining Spot/preemptible VMs (possible preemption, no live migration, configurable stop-or-delete) with Local SSD (data lost on any VM lifecycle event, cannot be boot volume), creating a distinct operational model suitable only for stateless batch processing, cache warming, or ML training with external checkpointing.

### gce-five-machine-families [IN] OBSERVATION
Compute Engine has five machine families: General-purpose, Compute-optimized, Storage-optimized, Memory-optimized, and Accelerator-optimized.

### gce-google-recommends-hyperdisk-over-pd [IN] OBSERVATION
Google recommends Hyperdisk over Persistent Disk for new workloads; Persistent Disk is not available with the latest machine series.

### gce-gpu-series-mapping [IN] OBSERVATION
GPU mapping: A4/A4X → B200/B300, A3 → H100/H200, A2 → A100, G2 → L4, G4 → RTX PRO 6000.

### gce-hpc-images-in-cloud-hpc-image-public [IN] OBSERVATION
HPC-optimized images are located in the `cloud-hpc-image-public` project.

### gce-hyperdisk-performance-independent-of-size [IN] OBSERVATION
Hyperdisk performance (IOPS, throughput) can be configured independently of disk size, unlike Persistent Disk where performance is tied to provisioned capacity.

### gce-hyperdisk-supports-dynamic-resize [IN] OBSERVATION
Hyperdisk supports dynamic resize and configurable performance; it is faster than Persistent Disk

### gce-image-families-point-to-latest-non-deprecated [IN] OBSERVATION
Image families always point to the latest non-deprecated image version; rollback works by deprecating the current latest image.

### gce-instance-default-timezone-utc [IN] OBSERVATION
All Compute Engine instances default to UTC time zone regardless of region.

### gce-instance-nic-unique-vpc-constraint [IN] OBSERVATION
Each instance network interface must be in a subnet of a unique VPC network — two NICs cannot be in the same VPC.

### gce-instances-are-zonal-resources [IN] OBSERVATION
Compute Engine instances are zonal resources — a zone must be specified at creation time.

### gce-local-ssd-cannot-be-boot-volume [IN] OBSERVATION
Local SSD cannot be used as a boot volume; boot volumes require durable block storage (Hyperdisk or Persistent Disk).

### gce-local-ssd-data-lost-on-stop [IN] OBSERVATION
Local SSD data is lost on VM stop, suspend, restart, crash, or host failure — it is ephemeral storage.

### gce-local-ssd-ephemeral-high-performance-tier [IN] OBSERVATION
Local SSDs in GCE are ephemeral storage that cannot serve as boot volumes — data is lost on instance stop, providing a storage tier with strict lifecycle coupling to the instance.

### gce-machine-type-naming-convention [IN] OBSERVATION
Machine type naming follows `{series}-{ratio}-{vcpus}` pattern, with optional `-lssd` (local SSD) or `-metal` (bare metal) suffixes.

### gce-metadata-client-cert-valid-7-days [IN] OBSERVATION
The HTTPS MDS client identity certificate is valid for 7 days and must be refreshed

### gce-metadata-custom-keys-case-sensitive [IN] OBSERVATION
GCE custom metadata keys are case-sensitive

### gce-metadata-host-local-always-accessible-with-rotation [IN] OBSERVATION
The GCE metadata server is always accessible regardless of firewall rules, never routes requests off the physical host, but HTTPS access requires client certificate rotation every 7 days — security depends on timely credential refresh, not network controls.

### gce-metadata-https-requires-shielded-vm [IN] OBSERVATION
HTTPS metadata server endpoints are only available on Shielded VMs

### gce-metadata-linux-cert-path [IN] OBSERVATION
On Linux, GCE HTTPS MDS certificates are stored at /run/google-mds-mtls/ (root.crt and client.key)

### gce-metadata-requests-never-leave-host [IN] OBSERVATION
Requests to the GCE metadata server never leave the physical host running the VM

### gce-metadata-root-cert-rotated-on-stop-start [IN] OBSERVATION
The HTTPS MDS self-signed root certificate (valid 50 years) is rotated on every instance stop/start cycle

### gce-metadata-server-link-local-ipv4 [IN] OBSERVATION
The GCE metadata server is accessible at the link-local IPv4 address 169.254.169.254

### gce-metadata-zonal-overrides-project [IN] OBSERVATION
When the same custom metadata key exists at both project and zonal levels, the zonal value takes precedence for VMs in that zone

### gce-mig-default-limits-1000-zonal-2000-regional [IN] OBSERVATION
Default VM limits are 1,000 for zonal MIGs and 2,000 for regional MIGs.

### gce-minimum-slo-99-9-percent [IN] OBSERVATION
Compute Engine has a minimum uptime SLO of 99.9%

### gce-no-extra-charge-for-instance-groups [IN] OBSERVATION
There is no additional charge for instance groups themselves; billing is only for the underlying resources.

### gce-oracle-linux-partner-supported-no-license-charge [IN] OBSERVATION
Oracle Linux on GCE is partner-supported (by Oracle, not Google) with no licensing charges.

### gce-os-login-integrates-ssh-with-iam [IN] OBSERVATION
OS Login integrates SSH key management with IAM roles, providing admin vs non-admin access control.

### gce-predefined-memory-ratios [IN] OBSERVATION
Predefined machine type memory ratios: highcpu ~2GB/vCPU, standard ~4GB/vCPU, highmem ~8GB/vCPU, megamem ~14GB/vCPU, ultramem 24-31GB/vCPU, hypermem ~16GB/vCPU.

### gce-preemptible-30-second-shutdown-window [IN] OBSERVATION
Preemptible VMs receive an ACPI G2 Soft Off signal giving up to 30 seconds (best effort) for shutdown scripts before forced termination

### gce-preemptible-gpu-no-advance-notice [IN] OBSERVATION
Standard GPU instances get 1-hour advance notice before maintenance; preemptible GPU instances do not

### gce-preemptible-max-24-hours [IN] OBSERVATION
Compute Engine always terminates preemptible VMs after 24 hours of continuous running

### gce-preemptible-no-billing-first-minute [IN] OBSERVATION
Preemptible VMs are not billed for instance usage if preempted within 1 minute of creation (premium OS charges still apply)

### gce-preemptible-no-live-migration [IN] OBSERVATION
Preemptible VMs cannot live migrate and cannot be set to automatically restart on maintenance events

### gce-preemptible-premium-os-not-discounted [IN] OBSERVATION
Premium OS image costs are not discounted on preemptible VMs

### gce-preemptible-stop-resets-timer-reboot-does-not [IN] OBSERVATION
Stopping and starting a preemptible VM resets the 24-hour counter; rebooting or resetting does not

### gce-public-images-available-all-projects [IN] OBSERVATION
Public OS images are available to all GCP projects by default with no special configuration needed.

### gce-queue-based-autoscaling-zonal-mig-only [IN] OBSERVATION
Queue-based autoscaling using Pub/Sub is only available for zonal MIGs, not regional MIGs.

### gce-regional-mig-protects-against-zonal-failure [IN] OBSERVATION
Regional MIGs deploy instances across multiple zones in a region, protecting against zonal failure; zonal MIGs do not.

### gce-sole-tenant-billed-for-node-not-vms [IN] OBSERVATION
Sole-tenant nodes are billed for node vCPU/memory with no extra charge for VMs on the node; GPUs and Local SSD billed separately

### gce-sole-tenant-cpu-overcommit-n1-n2-n2d-n4-only [IN] OBSERVATION
CPU overcommit on sole-tenant nodes is supported only on N1, N2, N2D, and N4 series

### gce-sole-tenant-dedicated-but-constrained [IN] OBSERVATION
GCE sole-tenant nodes provide physical server isolation with significant operational constraints: one-to-one physical server mapping ensures no co-tenancy, but nodes are billed at node level regardless of VM utilization, preemptible VMs are not supported, and maintenance windows are immutable 4-hour blocks fixed at creation.

### gce-sole-tenant-holdback-nodes-1-per-20 [IN] OBSERVATION
Migrate-within-node-group policy requires 1 holdback node per 20 nodes, with a minimum of 2 nodes in the group

### gce-sole-tenant-maintenance-window-4-hours-immutable [IN] OBSERVATION
Sole-tenant maintenance windows are 4-hour blocks set at node group creation and cannot be changed afterward

### gce-sole-tenant-no-preemptible-vms [IN] OBSERVATION
Preemptible VMs are not supported on sole-tenant nodes

### gce-sole-tenant-node-one-to-one-physical-server [IN] OBSERVATION
Each sole-tenant node maps one-to-one to a physical server dedicated to a single project's VMs

### gce-sole-tenant-three-maintenance-policies [IN] OBSERVATION
Sole-tenant nodes support three host maintenance policies: default (migrate to any node), restart in place (same physical server, ~1hr downtime), and migrate within node group

### gce-spot-preemptible-operational-constraints [IN] OBSERVATION
Preemptible VMs have strict operational constraints: 24-hour maximum lifetime, no live migration, and no automatic restart on maintenance. Spot VMs offer similar cost savings (up to 91% discount) with flexible termination actions (stop or delete) but no mandatory maximum runtime.

### gce-spot-preemptible-quota-mandatory-once-granted [IN] OBSERVATION
Once dedicated preemptible quota is granted in a region, Spot VMs in that region must use it and cannot fall back to standard quota

### gce-spot-vm-no-mandatory-max-runtime [IN] OBSERVATION
Unlike preemptible VMs (24-hour limit), Spot VMs have no mandatory maximum runtime

### gce-spot-vm-prices-change-up-to-once-per-day [IN] OBSERVATION
Spot VM prices can change up to once per day

### gce-spot-vm-termination-action-stop-or-delete [IN] OBSERVATION
Spot VM termination action is configurable: STOP (default, VM goes to TERMINATED) or DELETE (VM is removed)

### gce-spot-vm-unsupported-a4x-bare-metal [IN] OBSERVATION
Spot VMs are not supported on A4X machine series or bare metal instances

### gce-spot-vm-up-to-91-percent-discount [IN] OBSERVATION
Spot VMs offer up to 91% discount compared to standard VM pricing

### gce-stateful-mig-preserves-name-disks-metadata [IN] OBSERVATION
Stateful MIGs preserve instance name, attached persistent disks, and metadata across restart, recreation, and update events.

### gce-unmanaged-ig-no-automation [IN] OBSERVATION
Unmanaged instance groups do not support autoscaling, autohealing, rolling updates, multi-zone deployment, or instance templates — they only serve as load balancing targets.

### gce-uses-kvm-hypervisor [IN] OBSERVATION
Compute Engine VMs run on a KVM hypervisor

### gce-x4-memory-optimized-up-to-32tb [IN] OBSERVATION
Memory-optimized X4 machine type scales up to 32 TB of memory and 1,920 vCPUs (bare metal).

### gce-z3-up-to-72tib-titanium-ssd [IN] OBSERVATION
Z3 storage-optimized series provides up to 72 TiB Titanium SSD on bare metal.

### gclb-backend-services-over-target-pools [IN] OBSERVATION
For new external passthrough NLB deployments, backend services are recommended over target pools.

### gclb-cloud-armor-advanced-ddos-passthrough-only [IN] OBSERVATION
Cloud Armor advanced network DDoS protection is only available for external passthrough Network Load Balancers.

### gclb-no-prewarming-required [IN] OBSERVATION
Google Cloud Load Balancing requires no pre-warming — scales from zero to full traffic in seconds and handles instantaneous traffic spikes.

### gclb-passthrough-preserves-source-ip [IN] OBSERVATION
Passthrough load balancers preserve client source IP; proxy load balancers do not (backends see the proxy's IP).

### gclb-underlying-technologies [IN] OBSERVATION
Google Cloud LBs use: GFE for classic ALB/proxy NLB, Envoy-based GFE for global external ALB/proxy NLB, Envoy for regional/cross-region LBs, Maglev for external passthrough NLB, and Andromeda for internal passthrough NLB.

### gcp-assured-workloads-compliance [IN] OBSERVATION
Assured Workloads is the key GCP product for regulatory and compliance needs.

### gcp-data-services-require-per-service-protection-engineering [IN] OBSERVATION
GCP data protection is a per-service engineering effort, not a platform abstraction: Cloud SQL requires triple investment (HA + replicas + private networking) with each dimension independently constrained, while GCS requires defense in depth across three orthogonal dimensions (object immutability with versioned recovery, namespace security with organizational controls, four-tier encryption) — neither service's protection model transfers to the other.

### gcp-immutability-comprehensive-networking-and-services [IN] OBSERVATION
GCP immutability is comprehensive across both networking infrastructure (HA VPN stack type, Cloud VPN ciphers, Dedicated Interconnect link type, IPv6 access type) and service infrastructure (Artifact Registry format/mode, KMS key rings, Workload Identity pool format, Cloud SQL private IP), requiring correctness-at-creation across all resource layers since no corrective post-creation path exists for any of these configurations.

### gcp-immutable-infrastructure-decisions-require-upfront-design [IN] OBSERVATION
Multiple GCP services enforce immutable-after-creation configuration that cannot be corrected without resource recreation: Artifact Registry locks format and mode, KMS cannot delete key rings or change key type/purpose/protection, GKE Workload Identity pool is not deletable, and Cloud SQL private IP cannot be removed — establishing a cross-service pattern where initial design mistakes are permanently embedded in the resource hierarchy.

### gcp-networking-immutable-after-creation [IN] OBSERVATION
GCP networking configuration is broadly immutable after resource creation: HA VPN gateway stack type (IPv4/IPv6), Cloud VPN cipher options, Dedicated Interconnect link type (10G/100G/400G), and subnet IPv6 access type (internal/external) all require resource deletion and recreation to change, making network architecture decisions permanent commitments that cannot be corrected in place.

### gcp-observability-blind-spots-at-security-boundaries [IN] OBSERVATION
GCP observability has systematic blind spots at security boundaries despite robust defaults: VPC Flow Logs miss ingress-denied packets while capturing egress-denied ones (creating a firewall visibility gap exactly at the attack surface), AND Cloud Logging export has temporal gaps (sinks not retroactive, Cloud Storage sink latency in hours) — the combination means network-layer security incidents at the ingress boundary may have neither real-time flow data nor timely log exports for forensic reconstruction.

### gcp-observability-default-infrastructure-is-robust [IN] OBSERVATION
GCP provides robust default observability without explicit instrumentation: Cloud Monitoring auto-collects metrics for most services without agents, Cloud Logging routes entries through per-resource Log Routers with immutable `_Required` sinks for compliance, and VPC Flow Logs introduce no performance impact — baseline visibility is available out-of-box, and the compliance audit trail cannot be disabled.

### gcp-perf-autoscaling-dual-purpose [IN] OBSERVATION
Autoscaling serves dual purposes: performance predictability (prevents overload) and cost reduction (removes idle resources).

### gcp-perf-optimization-four-stages [IN] OBSERVATION
The performance optimization cycle has four stages: define requirements, design and deploy, monitor and analyze, optimize — and it is continuous.

### gcp-perf-requirements-per-layer [IN] OBSERVATION
Performance requirements should be defined per layer of the application stack, not just at the application level.

### gcp-private-data-services-universal-connectivity-tax [IN] OBSERVATION
GCP private data services like Cloud SQL and Memorystore require private IP connectivity that inherits VPC peering constraints (non-transitivity, peering limits), creating a connectivity overhead for each private data service adopted.

### gcp-reliability-four-focus-areas [IN] OBSERVATION
The reliability pillar has four focus areas: Scoping, Observation, Response, and Learning.

### gcp-reliability-nine-core-principles [IN] OBSERVATION
The reliability pillar has nine core principles including: define reliability based on UX goals, set realistic targets, resource redundancy, horizontal scalability, observability, graceful degradation, test recovery from failures, test recovery from data loss, and conduct postmortems.

### gcp-reliability-organizational-concern [IN] OBSERVATION
Reliability is an organizational concern shared by dev, product, ops, platform eng, SRE, and business teams — not just engineering.

### gcp-reliability-vs-resilience-definitions [IN] OBSERVATION
Reliability is consistent performance of intended functions plus uninterrupted service; resilience is the ability to withstand and recover from failures (a subset of reliability).

### gcp-secret-rotation-achieves-zero-downtime [IN] OBSERVATION
KMS key rotation and Secret Manager version pinning together enable zero-downtime secret and key rotation: KMS rotation creates new versions without re-encrypting existing data (ciphertext self-identifies its key version), and the recommended Secret Manager access pattern (API-direct with pinned version numbers) allows applications to transition between secret versions without restart — achieving non-disruptive credential rotation across the platform.

### gcp-security-eight-focus-areas [IN] OBSERVATION
The security pillar has eight focus areas: infrastructure security, IAM, data security, AI/ML security, SecOps, application security, governance/risk/compliance, and logging/auditing/monitoring.

### gcp-security-seven-core-principles [IN] OBSERVATION
The security pillar has seven core principles: security by design, zero trust, shift-left security, preemptive cyber defense, use AI securely, use AI for security, and regulatory/compliance/privacy.

### gcp-security-shared-responsibility-model [IN] OBSERVATION
Cloud security uses a shared responsibility model — Google secures infrastructure; the customer secures workloads, data, and access.

### gcp-shift-left-tools [IN] OBSERVATION
Shift-left security tools in GCP include Cloud Build, Binary Authorization, and Artifact Registry.

### gcp-waf-applies-to-hybrid-multicloud [IN] OBSERVATION
The Well-Architected Framework applies to cloud-native, migration, hybrid, and multi-cloud scenarios — not just greenfield cloud builds.

### gcp-waf-decoupled-architecture-benefits [IN] OBSERVATION
Decoupled architectures enable independent upgrades, security controls, reliability goals, health monitoring, and granular cost/performance control.

### gcp-waf-perspectives-cross-pillar [IN] OBSERVATION
Well-Architected Framework Perspectives are cross-pillar views for specific technologies, domains, or sectors — they are not additional pillars.

### gcp-waf-six-pillars [IN] OBSERVATION
The Google Cloud Well-Architected Framework has six pillars: Operational Excellence, Security/Privacy/Compliance, Reliability, Cost Optimization, Performance Optimization, and Sustainability.

### gcp-waf-stateless-architecture-benefits [IN] OBSERVATION
Stateless architecture enables reliability and scalability by allowing applications to scale quickly with minimum boot dependencies and withstand hard restarts.

### gcp-zero-trust-iap-chrome-enterprise [IN] OBSERVATION
Zero trust is implemented via Chrome Enterprise Premium and Identity-Aware Proxy (IAP).

### gcs-all-classes-11-nines-durability [IN] OBSERVATION
All Cloud Storage classes share 99.999999999% (eleven 9s) annual durability.

### gcs-archive-millisecond-access [IN] OBSERVATION
Archive storage class provides millisecond-latency access, unlike competing cloud providers' cold tiers which may take hours/days.

### gcs-bucket-dot-names-require-domain-verification [IN] OBSERVATION
Bucket names containing dots require domain ownership verification.

### gcs-bucket-name-location-immutable [IN] OBSERVATION
Bucket name and location are set at creation and cannot be changed afterward.

### gcs-bucket-names-globally-unique-public [IN] OBSERVATION
GCS bucket names are in a single global namespace — every name must be globally unique and is publicly visible.

### gcs-bucket-naming-rules [IN] OBSERVATION
Bucket names must be 3–63 characters, lowercase letters/numbers/dashes/underscores/dots only, cannot begin with `goog`, cannot contain `google`, and cannot be an IP address in dotted-decimal notation.

### gcs-buckets-cannot-be-nested [IN] OBSERVATION
GCS buckets cannot be nested inside other buckets.

### gcs-change-object-class-two-methods [IN] OBSERVATION
Two ways to change an object's storage class: rewrite the object or use Object Lifecycle Management.

### gcs-changing-default-class-not-retroactive [IN] OBSERVATION
Changing a bucket's default storage class does not affect existing objects — they retain their original class.

### gcs-client-side-encryption-double-layer [IN] OBSERVATION
Client-side encrypted data is also encrypted server-side, resulting in layered encryption.

### gcs-cmek-three-backends [IN] OBSERVATION
CMEK supports three key storage backends: software, HSM, and external (EKM).

### gcs-cmek-vs-csek-storage [IN] OBSERVATION
CMEK keys are stored in Cloud KMS (Google stores them, customer manages them); CSEK keys are provided per-request and never stored by Google.

### gcs-credential-access-boundaries-downscope [IN] OBSERVATION
Credential Access Boundaries downscope OAuth 2.0 tokens to limit access to specific buckets and permission sets.

### gcs-data-protection-requires-defense-in-depth [IN] OBSERVATION
GCS data protection requires defense in depth across three independent dimensions: object-level protection (immutable objects with versioned recovery but noncurrent versions readable and bucket deletion unprotected), namespace-level security (globally unique bucket names enabling enumeration with parallel IAM/ACL surfaces), and encryption tiering (four levels from Google-managed to client-side with increasing control and decreasing unconditional durability) — each dimension addresses a different threat model and no single mechanism provides complete protection.

### gcs-default-encryption-always-on [IN] OBSERVATION
All GCS data is encrypted at rest by default using Google-managed keys at no additional charge.

### gcs-default-storage-class-standard [IN] OBSERVATION
The default storage class for a bucket is Standard if not specified at creation.

### gcs-deleted-bucket-name-reuse-risk [IN] OBSERVATION
After bucket deletion, anyone can reuse the name (usually within seconds); deleting the project may hold the name for weeks or longer.

### gcs-disabling-versioning-keeps-noncurrent [IN] OBSERVATION
Disabling Object Versioning stops new noncurrent versions from accumulating but does not delete existing noncurrent versions.

### gcs-encryption-control-order [IN] OBSERVATION
The four GCS encryption options in order of increasing customer control: Default → CMEK → CSEK → Client-side.

### gcs-encryption-four-tier-defense [IN] OBSERVATION
GCS provides a four-tier encryption model (default, CMEK, CSEK, client-side) with increasing customer control, all built on always-on default encryption — but customer-managed keys (CSEK/client-side) shift the key loss risk entirely to the customer.

### gcs-flat-namespace-no-real-folders [IN] OBSERVATION
Flat namespace GCS buckets have no real folders — folders are simulated via `/` delimiters in object names.

### gcs-fuse-mount-as-filesystem [IN] OBSERVATION
Cloud Storage FUSE enables mounting buckets as local file systems for standard file I/O.

### gcs-generation-zero-means-latest [IN] OBSERVATION
Generation number `#0` in a Cloud Storage resource name refers to the most recent version of an object.

### gcs-hns-8x-higher-qps [IN] OBSERVATION
Hierarchical namespace (HNS) enabled buckets provide up to 8x higher initial QPS for reads/writes compared to flat-namespace buckets.

### gcs-iam-acl-parallel [IN] OBSERVATION
IAM and ACLs operate in parallel on GCS — if either system grants access, the user gets access.

### gcs-lifecycle-abort-multipart-limited-conditions [IN] OBSERVATION
AbortIncompleteMultipartUpload lifecycle action can only use `age`, `matchesPrefix`, and `matchesSuffix` conditions.

### gcs-lifecycle-age-zero-midnight-utc [IN] OBSERVATION
Lifecycle condition `age: 0` is satisfied at midnight UTC after object creation, not immediately.

### gcs-lifecycle-config-24h-propagation [IN] OBSERVATION
Lifecycle configuration changes can take up to 24 hours to take effect.

### gcs-lifecycle-delete-beats-setstorageclass [IN] OBSERVATION
When both Delete and SetStorageClass lifecycle rules match simultaneously, Delete takes precedence.

### gcs-lifecycle-economics-vs-evaluation-complexity [IN] OBSERVATION
GCS lifecycle management creates an economics-complexity tension: storage class pricing strongly incentivizes automated transitions (no retrieval fees for Standard/Rapid, no rewrite on SetStorageClass, minimum durations creating cost penalties for wrong placement), but lifecycle rule evaluation has complex precedence (Delete beats SetStorageClass), timing (age 0 means midnight UTC, not creation time), and hold semantics (holds block deletion even when conditions match) that can produce unexpected results.

### gcs-lifecycle-holds-block-delete [IN] OBSERVATION
Objects under holds or retention policies are not deleted by lifecycle rules even if conditions are met.

### gcs-lifecycle-precedence-timing-complexity [IN] OBSERVATION
GCS lifecycle rules have complex evaluation semantics: Delete takes precedence over SetStorageClass when both match, holds and retention policies block lifecycle deletions, age-0 triggers at midnight UTC (not immediately), and each rule uses multi-condition AND logic.

### gcs-lifecycle-rule-one-action-multiple-conditions [IN] OBSERVATION
Each lifecycle rule has exactly one action and one or more conditions; an object must match all conditions in a rule for the action to fire.

### gcs-lifecycle-setstorageclass-no-rewrite [IN] OBSERVATION
SetStorageClass lifecycle action does not rewrite the object — no retrieval fees, early deletion fees, or inter-region replication charges.

### gcs-lost-csek-key-permanent-data-loss [IN] OBSERVATION
Losing a CSEK or client-side encryption key results in unrecoverable data; objects remain stored and billed until explicitly deleted.

### gcs-managed-folders-permissions-only [IN] OBSERVATION
Managed folders are resource overlays used solely for granting/revoking IAM permissions, not true directory structures.

### gcs-namespace-security-requires-organizational-controls [IN] OBSERVATION
GCS bucket namespace has a multi-layered security surface beyond IAM: bucket names are globally unique and publicly visible (enabling enumeration), deleted bucket names can be immediately reused by anyone (enabling squatting), and IAM and ACLs operate in parallel where either granting access is sufficient — requiring organizational controls (naming conventions, deletion policies, uniform bucket-level access) to prevent namespace-level exposure.

### gcs-no-retrieval-fees-rapid-standard [IN] OBSERVATION
Rapid and Standard storage classes have no retrieval fees; Nearline, Coldline, and Archive have retrieval fees.

### gcs-noncurrent-objects-readable-soft-deleted-not [IN] OBSERVATION
Noncurrent versioned objects are readable; soft-deleted objects are not — this is a key differentiator between the features.

### gcs-object-identity-name-plus-generation [IN] OBSERVATION
An object is uniquely identified within a bucket by its name combined with a generation number.

### gcs-object-immutability-with-versioned-recovery [IN] OBSERVATION
GCS objects are immutable with atomic replacement; versioning and soft delete (default 7 days) provide recovery, but noncurrent versions are readable while soft-deleted objects are not — and both features require careful timing (30-second wait after config changes).

### gcs-object-name-max-1024-bytes [IN] OBSERVATION
Object name maximum size is 1024 bytes in flat namespace, or 512 bytes each for folder name and base name in hierarchical namespace (HNS).

### gcs-object-one-update-per-second-limit [IN] OBSERVATION
GCS enforces a once-per-second rate limit for replacing the same object; exceeding this yields `429 Too Many Requests`.

### gcs-objects-are-immutable [IN] OBSERVATION
Cloud Storage objects are immutable pieces of data stored in buckets.

### gcs-objects-immutable [IN] OBSERVATION
GCS objects are immutable — they cannot be modified in place; replacement is atomic with the old version served until the new upload completes.

### gcs-performance-engineering-requires-name-and-class-awareness [IN] OBSERVATION
GCS performance engineering requires simultaneous awareness of naming patterns and storage class constraints: sequential object names cause backend hotspotting, hierarchical namespace buckets provide up to 8x higher QPS, individual objects enforce a once-per-second update limit, and Rapid class is restricted to zonal-only buckets with storage size quotas.

### gcs-public-access-prevention-blocks-allusers [IN] OBSERVATION
Public access prevention blocks access via `allUsers` and `allAuthenticatedUsers` principals.

### gcs-rapid-class-zonal-only [IN] OBSERVATION
Rapid storage class is zone-only and requires a Rapid Bucket; has storage size quotas unlike other classes.

### gcs-resource-name-format [IN] OBSERVATION
Cloud Storage resource names use format `projects/_/buckets/BUCKET_NAME/objects/OBJECT_NAME`.

### gcs-sequential-names-cause-hotspotting [IN] OBSERVATION
Sequential object names during large-scale uploads cause hot-spotting on backend servers.

### gcs-server-side-encryption-always-on [IN] OBSERVATION
Server-side encryption is enabled by default on all Cloud Storage objects; CMEK and CSEK are supplemental options.

### gcs-signed-urls-no-account-required [IN] OBSERVATION
Signed URLs provide time-limited read/write access to GCS objects without requiring the recipient to have a Google account.

### gcs-soft-delete-default-7-days [IN] OBSERVATION
Soft delete is enabled by default on all Cloud Storage buckets with a 7-day retention period.

### gcs-soft-delete-recommended-over-versioning [IN] OBSERVATION
Google recommends soft delete over Object Versioning for protection against accidental/malicious deletions.

### gcs-storage-class-economics-favor-lifecycle-automation [IN] OBSERVATION
GCS storage class economics create a natural incentive for lifecycle automation: Standard and Rapid classes have no retrieval fees while Nearline/Coldline/Archive impose both retrieval fees and minimum storage durations (30/90/365 days), and the SetStorageClass lifecycle action avoids rewrite costs (no retrieval fees, no early deletion fees, no inter-region replication) — making automated downward class transitions via lifecycle rules strictly cheaper than manual object rewrites or delayed transitions.

### gcs-storage-class-minimum-durations [IN] OBSERVATION
Minimum storage durations: none for Rapid and Standard, 30 days for Nearline, 90 days for Coldline, 365 days for Archive.

### gcs-three-dimensional-operational-complexity [IN] OBSERVATION
GCS operational management requires simultaneous engineering across three largely independent dimensions: storage class economics with lifecycle automation (retrieval fee incentives vs minimum duration penalties), defense-in-depth data protection (object immutability, namespace security, four-tier encryption), and lifecycle rule evaluation complexity (Delete-over-SetStorageClass precedence, hold interactions, 24-hour propagation delay) — optimizing one dimension can conflict with another.

### gcs-unconditional-eleven-nines-durability [IN] OBSERVATION
GCS provides unconditional eleven-nines durability across all storage classes with millisecond access latency — including Archive class, which unlike competing cloud cold tiers requires no retrieval delay.

### gcs-uniform-access-90-day-revert [IN] OBSERVATION
After enabling uniform bucket-level access, there is a 90-day window to revert to fine-grained access; after that, uniform is permanent.

### gcs-uniform-access-recommended [IN] OBSERVATION
Uniform bucket-level access (IAM-only) is the recommended access model for GCS buckets; it disables ACLs.

### gcs-versioning-is-bucket-level [IN] OBSERVATION
Object Versioning is enabled per bucket, not per object; it affects all objects in the bucket.

### gcs-versioning-no-bucket-deletion-protection [IN] OBSERVATION
Object Versioning does not protect against bucket deletion; only soft delete provides that protection.

### gcs-versioning-wait-30-seconds [IN] OBSERVATION
Wait at least 30 seconds after changing versioning configuration before performing delete/replace operations.

### gke-3000-sa-limit-metadata-server-oom [IN] OBSERVATION
GKE clusters with more than 3,000 Kubernetes service accounts may cause metadata server pod OOM kills.

### gke-alpha-clusters-standard-only [IN] OBSERVATION
GKE alpha clusters for testing unstable Kubernetes features are available in Standard mode only.

### gke-apparmor-default-selinux-not-supported [IN] OBSERVATION
AppArmor default Docker profile is applied by the container runtime on all GKE containers; SELinux is not supported on GKE.

### gke-artifact-registry-dependency [IN] OBSERVATION
GKE cluster creation and upgrades pull container images from Artifact Registry (`pkg.dev` or `gcr.io`); an outage there can block new cluster creation and upgrades.

### gke-autopilot-always-cos-and-workload-identity [IN] OBSERVATION
GKE Autopilot always uses Container-Optimized OS and always has Workload Identity Federation enabled.

### gke-autopilot-always-cos-containerd [IN] OBSERVATION
GKE Autopilot nodes always use `cos_containerd` OS; Standard mode offers multiple OS choices.

### gke-autopilot-always-regional [IN] OBSERVATION
GKE Autopilot clusters are always regional and always enrolled in a release channel (default: Regular).

### gke-autopilot-billing-per-pod-request [IN] OBSERVATION
GKE Autopilot bills per Pod resource request; Standard mode bills per node regardless of Pod utilization.

### gke-autopilot-builtin-compute-classes [IN] OBSERVATION
GKE Autopilot provides built-in ComputeClasses: `Balanced`, `Scale-Out`, and `autopilot-spot`.

### gke-autopilot-dataplane-v2-default [IN] OBSERVATION
GKE Dataplane V2 is enabled by default in Autopilot clusters, enabling network policy enforcement and observability.

### gke-autopilot-extended-duration-7-days [IN] OBSERVATION
Extended-duration Pods in Autopilot are protected from eviction for up to 7 days using the annotation `cluster-autoscaler.kubernetes.io/safe-to-evict: "false"`.

### gke-autopilot-fully-managed-opinionated-model [IN] OBSERVATION
GKE Autopilot provides a fully managed, opinionated operational model: always regional (never zonal), always cos_containerd (no OS choice), Google-managed control plane, with scale-to-zero capability — reducing operational surface area but removing infrastructure customization options available in Standard mode.

### gke-autopilot-nodes-not-visible [IN] OBSERVATION
In GKE Autopilot mode, underlying Compute Engine VMs are not visible in gcloud CLI or Cloud console and cannot be accessed via SSH.

### gke-autopilot-safe-for-multi-team-production [IN] OBSERVATION
GKE Autopilot is safe for multi-team production clusters with fully managed infrastructure, pod-level billing granularity, and opinionated security baselines.

### gke-autopilot-sla-covers-control-plane-and-compute [IN] OBSERVATION
GKE Autopilot SLA covers both the control plane and Pod compute capacity.

### gke-autopilot-two-billing-models [IN] OBSERVATION
GKE Autopilot has two billing models: pod-based billing for general-purpose workloads and node-based billing for workloads selecting specific hardware.

### gke-autopilot-zero-node-scaling [IN] OBSERVATION
GKE Autopilot clusters can scale to zero nodes when no workloads are running.

### gke-beta-apis-available-1-24-plus [IN] OBSERVATION
GKE beta Kubernetes APIs are available in version 1.24 and later.

### gke-binary-authorization-cv-monitors-running-containers [IN] OBSERVATION
Binary Authorization continuous validation (CV) continuously monitors running container images against policies.

### gke-cannot-configure-individual-nodes-in-pool [IN] OBSERVATION
All nodes in a GKE node pool are identical; individual nodes cannot be configured independently within a pool.

### gke-cluster-deletion-no-graceful-drain [IN] OBSERVATION
GKE cluster deletion does not drain nodes gracefully; `kubectl drain` must be used manually before deleting.

### gke-cluster-state-etcd-or-spanner [IN] OBSERVATION
GKE cluster state can be stored in etcd or Spanner, but the etcd API is always exposed regardless of backend.

### gke-clusterip-provides-virtual-ip-and-dns [IN] OBSERVATION
ClusterIP Service type provides a stable virtual IP and DNS name for internal Pod-to-Pod communication within a GKE cluster.

### gke-control-plane-always-managed [IN] OBSERVATION
The GKE control plane is always managed by Google — customers cannot SSH into or directly access it.

### gke-control-plane-always-managed-by-google [IN] OBSERVATION
The GKE control plane is always fully managed by Google Cloud in both Autopilot and Standard modes.

### gke-credential-rotation-rotates-certs-ca-ip [IN] OBSERVATION
GKE credential rotation rotates SSL certificates, cluster CA, and control plane IP address.

### gke-critical-kube-system-pods-need-schedulable-pool [IN] OBSERVATION
Critical kube-system Pods (kube-dns, konnectivity-agent) must always have a schedulable node pool; removing all untainted pools causes DNS and control plane failures.

### gke-dataplane-v2-ebpf-dual-benefit [IN] OBSERVATION
GKE Dataplane V2 is eBPF-based and provides both high performance networking and built-in network policy enforcement.

### gke-default-node-pool-3-nodes-per-zone [IN] OBSERVATION
The default GKE node pool creates 3 nodes per compute zone using `cos_containerd` image and a general-purpose machine type.

### gke-federated-token-default-lifetime-1-hour [IN] OBSERVATION
Workload Identity Federation federated access tokens have a default lifetime of 1 hour; client libraries refresh within 3 min 45 sec of expiry.

### gke-gateway-api-replaces-ingress [IN] OBSERVATION
Gateway API is GKE's recommended approach for advanced L7 traffic management, replacing Ingress for new deployments.

### gke-host-network-pods-bypass-workload-identity [IN] OBSERVATION
Pods with `hostNetwork: true` bypass Workload Identity Federation and use the Compute Engine metadata server directly.

### gke-hubble-diagnoses-dropped-packets [IN] OBSERVATION
Hubble (via Dataplane V2 observability) is the tool for diagnosing dropped packets and misconfigured network policies; uses `hubble_drop_total` metric.

### gke-identity-sameness-risk-same-ns-sa [IN] OBSERVATION
Same namespace + service account name across GKE clusters in the same project results in the same IAM identity; mitigate with separate projects or distinct namespace names.

### gke-legacy-abac-should-be-disabled [IN] OBSERVATION
Legacy ABAC should be disabled on GKE clusters; RBAC and IAM should be the only authorization mechanisms.

### gke-loadbalancer-creates-passthrough-nlb [IN] OBSERVATION
LoadBalancer Service type provisions a regional external passthrough Network Load Balancer with a public IP.

### gke-mcs-cross-region-failover [IN] OBSERVATION
Multi-cluster Services (MCS) enables cross-cluster and cross-region failover with a single global DNS name and health-aware routing.

### gke-metadata-server-500-concurrent-connections [IN] OBSERVATION
The GKE metadata server has a limit of 500 concurrent connections per node.

### gke-multi-zonal-replicates-pools-across-zones [IN] OBSERVATION
In multi-zonal GKE clusters, node pools are automatically replicated across all zones, which has quota implications.

### gke-network-policies-default-allow-all [IN] OBSERVATION
GKE network policies default to allow-all; once any policy is applied to a namespace, unmatched traffic is denied.

### gke-node-pool-label-cloud-google-com [IN] OBSERVATION
Every node in a GKE node pool is labeled with `cloud.google.com/gke-nodepool` set to the pool's name.

### gke-node-sa-still-used-for-image-pulls [IN] OBSERVATION
The node pool's IAM service account is still used for container image pulls even with Workload Identity Federation enabled.

### gke-nodelocal-dnscache-reduces-latency [IN] OBSERVATION
NodeLocal DNSCache caches DNS queries on each node to reduce DNS latency at scale in GKE clusters.

### gke-nodes-are-compute-engine-vms [IN] OBSERVATION
GKE nodes are Compute Engine virtual machine instances.

### gke-pdb-deletion-cap-one-hour [IN] OBSERVATION
GKE PodDisruptionBudget respect during node pool deletion must be explicitly configured and is capped at one hour.

### gke-principal-vs-principalset-prefix [IN] OBSERVATION
`principal://` references a single IAM resource; `principalSet://` references a set of resources (namespace, cluster) in Workload Identity Federation.

### gke-release-channels-govern-auto-upgrades [IN] OBSERVATION
GKE release channels govern automatic Kubernetes version upgrades; without a release channel (Standard only), no automatic upgrades occur.

### gke-sandbox-gvisor-incompatible-with-node-sa [IN] OBSERVATION
GKE Sandbox (gVisor) is incompatible with node service account authentication but compatible with Workload Identity Federation.

### gke-shared-vpc-host-service-pattern [IN] OBSERVATION
Shared VPC is the multi-tenant networking pattern where the host project owns networking resources and service projects run GKE clusters.

### gke-workload-identity-pool-format-not-deletable [IN] OBSERVATION
The workload identity pool format is `PROJECT_ID.svc.id.goog` and is not deletable even after all clusters are removed.

### gke-workload-identity-recommended-for-api-access [IN] OBSERVATION
Workload Identity Federation for GKE is the recommended method for Pods to access Google Cloud APIs, over node service accounts or JSON keys.

### gke-workload-identity-requires-namespace-discipline [IN] OBSERVATION
GKE Workload Identity Federation is the recommended API access pattern but requires namespace and service account naming discipline: same namespace + SA name across clusters creates identity collisions, and the pool format is permanent (not deletable).

### ha-vpn-9999-sla-requires-both-interfaces [IN] OBSERVATION
HA VPN 99.99% SLA requires tunnels from both HA VPN interfaces (interface 0 and interface 1) to peer gateway interfaces — a single tunnel on one interface is insufficient.

### ha-vpn-active-passive-recommended-single-gateway [IN] OBSERVATION
Active-passive routing is recommended for a single HA VPN gateway (consistent bandwidth); active-active is recommended for multiple gateways to avoid bandwidth loss from unused passive tunnels.

### ha-vpn-failover-40-60-seconds [IN] OBSERVATION
HA VPN failover takes 40–60 seconds of expected packet loss when a tunnel goes down as Cloud Router withdraws learned routes.

### ha-vpn-full-mesh-not-required-gcp-side [IN] OBSERVATION
Full mesh is not required on the GCP side for 99.99% SLA — only one tunnel per HA VPN interface to the corresponding peer interface; full mesh may only be required by the peer vendor.

### ha-vpn-over-interconnect-internal-ips [IN] OBSERVATION
HA VPN over Cloud Interconnect allows using regional internal IP addresses for both HA VPN and peer gateways.

### ha-vpn-requires-bgp-no-static [IN] OBSERVATION
HA VPN tunnels must use BGP (dynamic routing) — static routing is not supported for HA VPN.

### ha-vpn-stack-type-immutable-after-creation [IN] OBSERVATION
HA VPN gateway stack type (IPV4_ONLY, IPV4_IPV6, IPV6_ONLY) cannot be changed after creation — the gateway must be deleted and recreated.

### ha-vpn-vpc-to-vpc-same-region-9999-cross-region-999 [IN] OBSERVATION
VPC-to-VPC HA VPN gateways in the same region achieve 99.99% SLA; gateways in different regions achieve only 99.9% SLA.

### iam-api-eventually-consistent [IN] OBSERVATION
The IAM API is eventually consistent — writes may not be immediately visible to reads or access checks.

### iam-basic-roles-not-for-production [IN] OBSERVATION
Basic roles (Owner, Editor, Viewer) should not be used in production; they include thousands of permissions across all GCP services.

### iam-compute-access-scopes-legacy [IN] OBSERVATION
Access scopes on Compute Engine are a legacy mechanism — both scopes and IAM roles must allow access for an API call to succeed.

### iam-conditional-binding-no-override-unconditional [IN] OBSERVATION
A conditional role binding does NOT override an unconditional binding for the same role — the unconditional binding still grants access.

### iam-conditions-not-with-basic-roles [IN] OBSERVATION
IAM conditions cannot be used with basic roles (Owner/Editor/Viewer) or with allUsers/allAuthenticatedUsers.

### iam-conditions-use-cel [IN] OBSERVATION
IAM Conditions use Common Expression Language (CEL) for attribute-based access control expressions.

### iam-defense-in-depth-requires-policy-and-sa-hardening [IN] OBSERVATION
GCP IAM security requires defense in depth across two independent dimensions: correct policy evaluation understanding (deny-first with fail-closed conditions, inheritance unions, conditional bindings that don't override unconditional) for authoring policies, and active service account hardening (revoking default editor role, controlling impersonation, managing dual principal/resource nature) for closing privilege escalation — neither alone is sufficient.

### iam-deny-conditions-fail-closed [IN] OBSERVATION
If a deny policy condition evaluates to true OR cannot be evaluated, the deny rule applies (fail-closed behavior).

### iam-deny-conditions-only-resource-tags [IN] OBSERVATION
Deny policy conditions only support resource tag functions, not the full set of condition attributes available in allow policies.

### iam-deny-overrides-allow [IN] OBSERVATION
Deny policies override allow policies — a principal can be denied access even if allowed by an allow policy.

### iam-effective-policy-is-union [IN] OBSERVATION
The effective allow policy for a resource is the union of its own policy plus all ancestor policies in the resource hierarchy.

### iam-gcs-conditions-require-uniform-access [IN] OBSERVATION
Cloud Storage buckets require uniform bucket-level access enabled to use IAM conditions.

### iam-grant-roles-to-groups [IN] OBSERVATION
Best practice is to grant IAM roles to Google Groups rather than individual users for easier management.

### iam-key-rotation-order [IN] OBSERVATION
Service account key rotation follows a strict order: create new key → switch apps → disable old key → delete old key.

### iam-max-100-conditional-bindings [IN] OBSERVATION
Best practice is no more than 100 conditional role bindings per allow policy to avoid size limits.

### iam-permission-format [IN] OBSERVATION
IAM permissions follow the format service.resource.verb (e.g., resourcemanager.projects.list) and cannot be granted directly — only through roles.

### iam-policy-evaluation-layered-fail-closed-deny [IN] OBSERVATION
IAM policy evaluation is a layered system with fail-closed deny semantics: deny policies trigger on unevaluable conditions, conditional allow bindings never override unconditional bindings for the same role, and all policies inherit top-down through the org/folder/project/resource hierarchy.

### iam-policy-inheritance-top-down [IN] OBSERVATION
IAM allow policies on parent resources (org → folder → project → resource) are automatically inherited by all child resources.

### iam-prefer-alternatives-to-sa-keys [IN] OBSERVATION
Service account keys are a security risk; prefer Workload Identity, attached service accounts, or federated identity over key-based authentication.

### iam-role-naming-convention [IN] OBSERVATION
IAM role names follow the convention roles/<service>.<roleName> (e.g., roles/storage.admin).

### iam-sa-100-per-project-quota [IN] OBSERVATION
Default quota is 100 service accounts per project; can request an increase.

### iam-sa-default-gets-editor [IN] OBSERVATION
Default service accounts (Compute Engine, App Engine) automatically receive roles/editor — a security anti-pattern that should be disabled via org policy.

### iam-sa-dual-nature [IN] OBSERVATION
Service accounts are both principals (can be granted roles on resources) and resources (other principals can be granted roles on them).

### iam-sa-impersonation-requires-token-creator [IN] OBSERVATION
Service account impersonation requires roles/iam.serviceAccountTokenCreator on the target service account.

### iam-sa-not-in-workspace-domain [IN] OBSERVATION
Service accounts do not belong to Google Workspace domains — Workspace domain-wide shares do not include them.

### iam-sa-recreate-loses-bindings [IN] OBSERVATION
Deleting and recreating a service account with the same email does not restore old role bindings because bindings use internal unique IDs, not email addresses.

### iam-service-account-security-requires-hardening [IN] OBSERVATION
Service accounts require active security hardening: they have dual nature (principal and resource), default accounts receive overly broad editor role, impersonation needs explicit token creator role, and they are invisible to Workspace domain-wide shares.

### iam-service-account-user-privilege-escalation [IN] OBSERVATION
The Service Account User role (roles/iam.serviceAccountUser) is a privilege escalation vector — anyone with this role inherits the service account's full access.

### interconnect-50-percent-capacity-rule [IN] OBSERVATION
Cloud Interconnect protects up to 50% of aggregate capacity; provision 2x required bandwidth across redundant connections for full protection.

### interconnect-active-active-recommended [IN] OBSERVATION
Active-active is the recommended VLAN attachment configuration for Cloud Interconnect; active/passive risks undetected misconfigurations.

### interconnect-dedicated-up-to-100-gbps [IN] OBSERVATION
Dedicated Interconnect supports up to 100 Gbps connections at colocation facilities.

### interconnect-ecmp-requires-flow-based-hashing [IN] OBSERVATION
ECMP across active-active Cloud Interconnect VLAN attachments requires flow-based hashing on on-premises devices; per-packet load balancing is unsupported and causes TCP connection closures.

### interconnect-encryption-requires-overlay-protocol [IN] OBSERVATION
Cloud Interconnect does not encrypt traffic by default; achieving confidentiality requires an overlay protocol — either MACsec for link-layer encryption between router and Google edge, or HA VPN tunnels over Interconnect using regional internal IP addresses for end-to-end IPsec encryption.

### interconnect-four-connection-types [IN] OBSERVATION
Cloud Interconnect offers four connection types: Dedicated, Partner, Cross-Cloud, and Cross-Site Interconnect.

### interconnect-ha-vpn-gateway-mtu-1440 [IN] OBSERVATION
HA VPN over Cloud Interconnect uses a reduced gateway MTU of 1440 bytes.

### interconnect-ip-spaces-must-not-overlap [IN] OBSERVATION
IP address spaces between on-premises and VPC networks must not overlap when using Cloud Interconnect.

### interconnect-no-encryption-by-default [IN] OBSERVATION
Cloud Interconnect does not encrypt traffic by default; encryption requires MACsec (router-to-edge) or HA VPN over Cloud Interconnect (IPsec on VLAN attachments).

### interconnect-physical-connections-cannot-move-or-rename [IN] OBSERVATION
Physical Cloud Interconnect connections cannot be moved between projects or renamed after creation.

### interconnect-production-requires-redundancy-and-encryption [IN] OBSERVATION
Production-grade Cloud Interconnect requires two independent engineering efforts: 2x bandwidth overprovisioning with global dynamic BGP routing for redundancy, AND an encryption overlay (MACsec or HA VPN over internal IPs) for confidentiality — neither alone is sufficient for production readiness.

### interconnect-reduces-egress-costs [IN] OBSERVATION
Cloud Interconnect can reduce egress costs, unlike Cloud VPN alone which does not reduce egress costs.

### interconnect-redundancy-requires-overprovisioning-and-global-routing [IN] OBSERVATION
Cloud Interconnect redundancy requires provisioning 2x bandwidth (50% capacity rule), dynamic BGP routing via Cloud Router, and global dynamic routing mode for cross-region failover — creating a three-layer resilience model.

### interconnect-regional-failover-requires-global-dynamic-routing [IN] OBSERVATION
Cloud Interconnect traffic prefers the lowest-metric local region; cross-region failover only occurs when all local VLAN attachments are down and requires global dynamic routing.

### interconnect-sla-tiers-99-99-99-9-none [IN] OBSERVATION
Cloud Interconnect offers three SLA tiers: 99.99% (critical production), 99.9% (non-critical production), and no SLA.

### interconnect-uses-cloud-router-bgp [IN] OBSERVATION
Cloud Interconnect uses Cloud Router for dynamic (BGP) routing between on-premises and VPC networks.

### interconnect-vlan-custom-ip-prefix-lengths [IN] OBSERVATION
Custom IP ranges on VLAN attachments require /29 or /30 for IPv4 and /125 or /126 for IPv6; private IPv4 addresses cannot be used with custom IP range flags.

### interconnect-vlan-mtu-must-match-vpc-mtu [IN] OBSERVATION
Cloud Interconnect VLAN attachment MTU should match VPC network MTU; mismatches drop non-TCP packets regardless of DF bit setting.

### internal-nlb-backend-must-bind-forwarding-rule-ip [IN] OBSERVATION
Internal passthrough NLB backend VMs must bind to the forwarding rule IP or `0.0.0.0`/`::` because the destination IP on received packets is the forwarding rule's IP, not the backend's own IP.

### internal-nlb-cannot-mix-ig-and-neg [IN] OBSERVATION
Internal passthrough NLB cannot mix instance group and zonal NEG (`GCE_VM_IP`) backends on the same backend service.

### internal-nlb-forwarding-rules-immutable [IN] OBSERVATION
Internal passthrough NLB forwarding rules are immutable after creation — must delete and recreate to change ports or IP.

### internal-nlb-global-access-disabled-by-default [IN] OBSERVATION
Internal passthrough NLB global access is disabled by default; without it, only same-region clients can connect. On-prem clients via VPN/Interconnect must match the LB region unless global access is enabled.

### internal-nlb-l3-default-requires-ports-all [IN] OBSERVATION
Internal passthrough NLB `L3_DEFAULT` forwarding rule protocol enables non-TCP/UDP protocols (ICMP, SCTP, ESP, AH, GRE) and requires `--ports=ALL`.

### internal-nlb-neg-ipv4-only [IN] OBSERVATION
Internal passthrough NLB zonal NEGs (`GCE_VM_IP`) only support IPv4; instance groups support both IPv4 and IPv6.

### internal-nlb-regional-passthrough [IN] OBSERVATION
The internal passthrough Network Load Balancer is regional, Layer 4, built on Andromeda, preserves client source IP, and does not terminate SSL/TLS.

### internal-nlb-scheme-internal [IN] OBSERVATION
Internal passthrough NLB uses load balancing scheme `INTERNAL`, distinguishing it from external passthrough NLB which uses `EXTERNAL`.

### ipv6-access-type-cannot-change-after-creation [IN] OBSERVATION
A subnet's IPv6 access type (internal or external) cannot be changed after subnet creation.

### ipv6-subnets-require-custom-mode [IN] OBSERVATION
IPv6 subnets are only supported on custom mode VPC networks, not auto mode or legacy networks.

### keyless-identity-eliminates-credential-overhead [IN] OBSERVATION
Keyless identity patterns (WIF for external workloads + GKE Workload Identity for pods) fully eliminate credential management overhead by replacing service account keys with federated token exchange across all workload types.

### kms-admin-role-no-encrypt-decrypt [IN] OBSERVATION
The `roles/cloudkms.admin` role does NOT grant encrypt or decrypt permissions; separate granular roles exist for encrypt-only, decrypt-only, and combined encrypter-decrypter.

### kms-all-states-except-destroyed-incur-costs [IN] OBSERVATION
All Cloud KMS key version states except Destroyed incur costs, including Disabled and Scheduled for destruction.

### kms-auto-rotation-symmetric-only [IN] OBSERVATION
Cloud KMS automatic key rotation is supported for symmetric keys only; asymmetric keys must be rotated manually.

### kms-autokey-provisions-on-demand [IN] OBSERVATION
Cloud KMS Autokey automates provisioning of key rings, keys, and service accounts on demand during resource creation, requiring no pre-provisioning.

### kms-cmek-40-plus-services [IN] OBSERVATION
Over 40 GCP services support Customer-Managed Encryption Keys (CMEK) with software and HSM keys; over 30 services support EKM keys.

### kms-crc32c-integrity-verification-recommended [IN] OBSERVATION
CRC32C integrity verification is recommended (not mandatory) for Cloud KMS encrypt and decrypt operations to detect in-transit data corruption.

### kms-crypto-shredding-destroy-cmek [IN] OBSERVATION
Crypto-shredding in GCP works by destroying the CMEK that protects data, rendering the data selectively unreadable.

### kms-csek-not-a-kms-feature [IN] OBSERVATION
Customer-Supplied Encryption Keys (CSEK) are not a Cloud KMS feature — they are supported only by Cloud Storage and Compute Engine, where the customer provides key material at use time.

### kms-destroy-duration-only-at-creation [IN] OBSERVATION
The `destroy_scheduled_duration` for a Cloud KMS key is only configurable at key creation time and cannot be changed afterward.

### kms-destroy-scheduled-default-30-days [IN] OBSERVATION
Default scheduled-for-destruction duration for Cloud KMS key versions is 30 days; minimum is 24 hours (0 for import-only keys); maximum is 120 days.

### kms-destroying-active-version-permanent-data-loss [IN] OBSERVATION
Destroying a Cloud KMS key version that is still in use causes permanent, irrecoverable data loss.

### kms-ekm-keys-never-sent-to-google [IN] OBSERVATION
Cloud EKM keys reside in an external key manager and are never sent to Google.

### kms-encrypt-uses-primary-version-automatically [IN] OBSERVATION
Encrypt requests target the crypto key (not a specific version) — Cloud KMS uses the primary version automatically; decrypt also targets the key and determines the version from ciphertext metadata.

### kms-governance-couples-duty-separation-with-safe-rotation [IN] OBSERVATION
Cloud KMS governance provides complementary safety guarantees: strict separation of duties ensures administrators cannot perform cryptographic operations (and vice versa) while key rotation is operationally safe because it creates new versions without re-encrypting existing data and the version is embedded in ciphertext for transparent decryption — together enabling key governance where operational mistakes in rotation cannot cause data loss and administrative access cannot enable data exfiltration.

### kms-iam-at-key-level-not-version [IN] OBSERVATION
IAM access control operates at the key level, not the key version level — you cannot control access to individual key versions.

### kms-key-material-purge-45-days-after-destroy [IN] OBSERVATION
After a Cloud KMS key version is destroyed, it takes 45 days for key material to be purged from all Google active and backup systems.

### kms-key-rings-cannot-be-deleted [IN] OBSERVATION
Cloud KMS key rings and EKM connections cannot be deleted, and deleted key names cannot be reused.

### kms-key-rings-location-bound-immovable [IN] OBSERVATION
Cloud KMS key rings are bound to a specific location and cannot be moved after creation.

### kms-key-type-purpose-protection-immutable [IN] OBSERVATION
Cloud KMS key type, purpose, and protection level are all immutable after creation.

### kms-manual-rotation-preserves-auto-schedule [IN] OBSERVATION
Manual key rotation does not pause or modify an existing automatic rotation schedule.

### kms-only-primary-version-encrypts [IN] OBSERVATION
For symmetric encryption keys, only the primary version can encrypt data; any enabled version can decrypt, but non-primary enabled versions cannot encrypt.

### kms-only-symmetric-has-primary-version [IN] OBSERVATION
Only symmetric encryption keys have a primary version; asymmetric keys require specifying the version explicitly.

### kms-probabilistic-encryption [IN] OBSERVATION
Cloud KMS uses probabilistic encryption — identical plaintext encrypted with the same key version produces different ciphertext each time.

### kms-raw-key-material-never-exportable [IN] OBSERVATION
Cloud KMS raw symmetric key material can never be viewed or exported; encrypt/decrypt operations happen within the service.

### kms-raw-key-material-never-viewable [IN] OBSERVATION
Cloud KMS raw key material is never viewable or exportable by any Google Cloud principal.

### kms-rest-api-requires-base64-encoding [IN] OBSERVATION
Cloud KMS REST API requires plaintext to be base64-encoded before calling encrypt, and decrypt responses are also base64-encoded.

### kms-rotation-decoupled-from-reencryption [IN] OBSERVATION
KMS key rotation creates new versions without re-encrypting existing data; the version is embedded in ciphertext for symmetric keys, automatic rotation only works for symmetric keys, and manual rotation preserves auto schedules — making re-encryption a separate operational responsibility.

### kms-rotation-does-not-reencrypt-data [IN] OBSERVATION
Rotating a Cloud KMS key creates a new key version but does not re-encrypt previously encrypted data — re-encryption must be done explicitly.

### kms-separation-of-duties-admin-vs-crypto [IN] OBSERVATION
Cloud KMS enforces strict separation of duties between administration and cryptographic operations: the admin role cannot encrypt or decrypt, IAM access control operates at the key level (not individual versions), and raw key material is never viewable or exportable — no single role or access path can both manage keys and use them, and the key material itself is inaccessible regardless of permissions.

### kms-software-fips-140-2-level-1 [IN] OBSERVATION
Cloud KMS software protection level keys are FIPS 140-2 Level 1 certified.

### kms-symmetric-version-embedded-in-ciphertext [IN] OBSERVATION
For symmetric Cloud KMS keys, the version used for encryption is embedded in the ciphertext, so decryption automatically selects the correct version.

### logging-alerting-vs-metrics-usage [IN] OBSERVATION
Log-based alerting policies are for rare important events (pattern matching), while log-based metrics combined with alerting policies are for monitoring trends and thresholds.

### logging-auto-collection-no-setup [IN] OBSERVATION
Cloud Logging automatically collects logs from Google Cloud resources without requiring manual setup for default collection.

### logging-cloud-storage-sink-latency-hours [IN] OBSERVATION
New Cloud Storage log sinks can take several hours to begin routing because log entries to Cloud Storage are processed hourly.

### logging-default-routing-two-tier-architecture [IN] OBSERVATION
Cloud Logging's two default sinks implement a deliberate two-tier routing architecture: `_Required` is completely immutable and always routes compliance-critical audit logs (Admin Activity, System Events), while `_Default` can be modified, disabled, or redirected — guaranteeing compliance log capture at the infrastructure level while giving operators full control over operational log routing and cost.

### logging-default-sink-modifiable [IN] OBSERVATION
The `_Default` sink is system-created but can be modified, disabled, or have its destination changed and exclusion filters added.

### logging-error-reporting-same-project-only [IN] OBSERVATION
Error Reporting only analyzes log entries stored in log buckets within the same project where Error Reporting runs.

### logging-exclusion-filters-post-ingestion [IN] OBSERVATION
Exclusion filters do not reduce `entries.write` API quota consumption because they are applied after the Logging API has already received the entries.

### logging-export-has-temporal-reliability-gaps [IN] OBSERVATION
Cloud Logging export has temporal reliability gaps despite the robust two-tier default architecture: sinks are not retroactive (entries received before sink creation or during misconfiguration are permanently lost), Cloud Storage sink destinations can delay initial routing by several hours, and only the immutable `_Required` sink guarantees uninterrupted routing — making log completeness in custom destinations a best-effort property, not a guarantee.

### logging-five-sink-destinations [IN] OBSERVATION
Log sink supported destinations are: log bucket, BigQuery dataset, Cloud Storage bucket, Pub/Sub topic, and Google Cloud project.

### logging-intercepting-aggregated-sink-blocks-child [IN] OBSERVATION
Intercepting aggregated sinks prevent child resource sinks from processing matched entries, except the child's `_Required` sink which always processes originating entries.

### logging-linked-bigquery-datasets-read-only [IN] OBSERVATION
Linked BigQuery datasets created from log buckets are read-only and must never be set as a sink destination.

### logging-log-router-per-resource [IN] OBSERVATION
Each Google Cloud project, billing account, folder, and organization has its own Log Router that temporarily buffers and routes log entries through sinks.

### logging-ops-agent-recommended-for-vms [IN] OBSERVATION
The Ops Agent is the recommended agent for collecting application and third-party logs on Compute Engine VMs.

### logging-required-sink-immutable [IN] OBSERVATION
The `_Required` sink is system-created and immutable — it cannot be modified or deleted — and routes Admin Activity, System Event, and Access Transparency audit logs to the `_Required` log bucket.

### logging-sink-one-hop-limit [IN] OBSERVATION
When a sink routes log entries to a Google Cloud project as destination, sinks in that destination project cannot reroute the entries to another project (one-hop limit).

### logging-sinks-not-retroactive [IN] OBSERVATION
Log sinks cannot retroactively route entries received before creation or during misconfiguration; the "Copy logs" feature can retroactively copy from a log bucket to Cloud Storage.

### logging-timestamp-discard-rules [IN] OBSERVATION
Log entries with timestamps older than the retention period or more than 24 hours in the future are discarded by the Log Router.

### logging-two-query-interfaces [IN] OBSERVATION
Cloud Logging provides two query interfaces: Logs Explorer for troubleshooting individual entries, and Log Analytics for SQL-based trend analysis.

### memorystore-cluster-instance-hierarchy [IN] OBSERVATION
Memorystore for Redis Cluster has a hierarchical resource structure: Instance → Shards → Nodes (primary + replicas), where "instance" and "cluster" are interchangeable terms.

### memorystore-cluster-redis-7x [IN] OBSERVATION
Memorystore for Redis Cluster is based on open-source Redis 7.x and supports a subset of the total Redis command library (not all commands available).

### memorystore-cluster-shard-replicas [IN] OBSERVATION
Each Memorystore for Redis Cluster shard has exactly 1 primary node and up to 5 replica nodes, with replicas automatically distributed across zones for HA.

### memorystore-cluster-vpc-prerequisite [IN] OBSERVATION
VPC networking must be configured before creating a Memorystore for Redis Cluster instance.

### memorystore-redis-async-replication [IN] OBSERVATION
Memorystore for Redis uses asynchronous replication — acknowledged writes may be lost during failover because replicas can lag behind the primary.

### memorystore-redis-basic-tier-no-replication [IN] OBSERVATION
Memorystore for Redis Basic Tier has no replication, no automatic failover, and is a standalone cache instance.

### memorystore-redis-constrained-operational-model [IN] OBSERVATION
Memorystore for Redis operates under a constrained model compared to self-managed Redis: private IP only (requiring VPC connectors for serverless access), RDB-only persistence (no AOF, creating a data loss window between snapshots), 300 GB maximum instance size, and Basic Tier entirely lacking replication — workloads requiring AOF durability, public access, or instances larger than 300 GB cannot use the managed service.

### memorystore-redis-failover-least-lag [IN] OBSERVATION
During automatic failover, Memorystore for Redis promotes the replica with the least replication lag.

### memorystore-redis-failover-same-ip [IN] OBSERVATION
The connection string and IP address remain the same after a Memorystore for Redis failover — no application changes are needed.

### memorystore-redis-ha-requires-standard-tier [IN] OBSERVATION
Memorystore for Redis Standard Tier (not Basic) is required for high availability and data replication.

### memorystore-redis-io-threads-m3-plus-redis6 [IN] OBSERVATION
Memorystore for Redis I/O threads require M3 or higher capacity tier and Redis 6.x or later.

### memorystore-redis-manual-failover-no-read-replicas [IN] OBSERVATION
Manual failover via API is not supported for Memorystore for Redis instances with read replicas enabled.

### memorystore-redis-max-instance-size-300gb [IN] OBSERVATION
Memorystore for Redis maximum instance size is 300 GB for both Basic and Standard tiers.

### memorystore-redis-max-read-replicas-5 [IN] OBSERVATION
Memorystore for Redis supports up to 5 read replicas on Standard Tier only, each adding 16 Gbps read throughput.

### memorystore-redis-no-aof-persistence [IN] OBSERVATION
Memorystore for Redis does not support AOF persistence; only RDB snapshots are available for data persistence.

### memorystore-redis-private-ip-only [IN] OBSERVATION
Memorystore for Redis instances use private IPs only and are not exposed to the public internet; clients must connect via the same VPC network.

### memorystore-redis-read-replicas-1-to-5 [IN] OBSERVATION
Memorystore for Redis supports 1 to 5 read replicas when readReplicaMode is enabled, providing both read distribution and HA failover targets.

### memorystore-redis-serverless-vpc-connector-required [IN] OBSERVATION
Serverless environments (App Engine, Cloud Run, Cloud Run functions) require a Serverless VPC Access connector to reach Memorystore for Redis.

### memorystore-redis-standard-tier-sla-99-9 [IN] OBSERVATION
Memorystore for Redis Standard Tier provides a 99.9% availability SLA with cross-zone replication and automatic failover.

### monitoring-auto-collects-gcp-metrics-no-agent [IN] OBSERVATION
Cloud Monitoring automatically collects metrics for most GCP services without requiring an agent.

### monitoring-cloud-endpoints-serviceruntime-api [IN] OBSERVATION
Cloud Endpoints metrics use the `serviceruntime` metric type and write against the `api` monitored-resource type.

### monitoring-forecast-window-1h-to-7d [IN] OBSERVATION
Cloud Monitoring forecasted metric-value condition has a forecast window ranging from 1 hour to 7 days.

### monitoring-gke-legacy-vs-new-metric-prefix [IN] OBSERVATION
Legacy GKE metrics use the `container.googleapis.com` prefix; newer GKE metrics use the `kubernetes.io` prefix.

### monitoring-log-vs-sql-alerts-scope [IN] OBSERVATION
Log-based alerts monitor individual log entries; SQL-based alerts monitor aggregations across multiple log entries.

### monitoring-metric-absence-max-retest-23-5-hours [IN] OBSERVATION
Cloud Monitoring metric-absence condition has a maximum retest window of 23.5 hours.

### monitoring-metric-incidents-auto-close [IN] OBSERVATION
Cloud Monitoring automatically closes incidents and sends closure notifications when metric-based policy conditions are no longer met.

### monitoring-metric-type-naming-convention [IN] OBSERVATION
Cloud Monitoring metric type names are prefixed by service name (e.g., `compute.googleapis.com/instance/cpu/utilization`).

### monitoring-metrics-scope-multi-project-aws [IN] OBSERVATION
A Cloud Monitoring metrics scope allows monitoring multiple GCP projects and AWS accounts from a single scoping project.

### monitoring-one-time-series-per-label-combination [IN] OBSERVATION
Cloud Monitoring writes one time series per unique combination of resource labels and metric labels.

### monitoring-ops-agent-for-app-metrics-on-gce [IN] OBSERVATION
The Ops Agent must be installed on Compute Engine VMs to collect application and third-party metrics (Apache, Nginx, MongoDB, PostgreSQL).

### monitoring-promql-supported-in-alerting [IN] OBSERVATION
PromQL can be used in Cloud Monitoring alerting policy conditions for complex expressions and dynamic thresholds.

### monitoring-snooze-temporarily-disables-policy [IN] OBSERVATION
Cloud Monitoring alerting policies monitor continuously; a snooze temporarily disables a policy for a defined period.

### monitoring-three-alerting-policy-types [IN] OBSERVATION
Cloud Monitoring supports three alerting policy types: metric-based, log-based, and SQL-based (SQL-based is Public Preview).

### monitoring-three-metric-kinds [IN] OBSERVATION
Cloud Monitoring has three metric kinds: GAUGE (value at a point in time), CUMULATIVE (accumulated over time), and DELTA (change over a period).

### monitoring-vm-manager-osconfig-prefix [IN] OBSERVATION
VM Manager metrics use the `osconfig.googleapis.com` prefix, not `compute.googleapis.com`.

### multi-network-connectivity-constrained-both-models [IN] OBSERVATION
GCP multi-network connectivity is fundamentally constrained regardless of model: Shared VPC requires same-organization hierarchy with single-host attachment and doesn't migrate existing resources, while VPC peering is non-transitive, prohibits subnet overlap, and never exchanges IAM or dynamic routes — forcing an architecture-level choice between organizational coupling (Shared VPC) and connectivity limitations (peering) with no unconstrained option.

### partner-interconnect-50mbps-to-50gbps [IN] OBSERVATION
Partner Interconnect supports VLAN attachment capacities from 50 Mbps to 50 Gbps.

### partner-interconnect-99-99-sla-requirements [IN] OBSERVATION
Partner Interconnect 99.99% SLA requires 4 VLAN attachments across 2 metros, one per edge availability domain, with 2 Cloud Routers (one per region) and global routing enabled on the VPC.

### partner-interconnect-layer2-vs-layer3 [IN] OBSERVATION
Partner Interconnect Layer 2 requires customer-configured BGP; Layer 3 has fully automated BGP handled by the service provider and supports pre-activation.

### partner-interconnect-med-values-layer3-limitation [IN] OBSERVATION
MED values cannot be sent or learned over Layer 3 Partner Interconnect connections because MED values cannot pass through autonomous systems.

### partner-interconnect-sla-covers-vpc-to-provider-only [IN] OBSERVATION
Google's SLA for Partner Interconnect covers only connectivity between VPC and the service provider's network, not the service-provider-to-customer leg.

### partner-interconnect-via-service-provider [IN] OBSERVATION
Partner Interconnect uses a third-party service provider as an intermediary, suited for when a data center cannot reach a Dedicated Interconnect colocation facility or bandwidth needs are below 10 Gbps.

### peering-dynamic-routes-use-exporting-vpc-mode [IN] OBSERVATION
Peering dynamic routes apply based on the dynamic routing mode of the exporting VPC network, not the importing one.

### pga-disabled-blocks-api-access [IN] OBSERVATION
When PGA is disabled on a subnet, internal-only VMs on that subnet cannot reach Google APIs or services.

### pga-enabled-per-subnet [IN] OBSERVATION
Private Google Access (PGA) is enabled per subnet, not per VM or per VPC.

### pga-only-affects-internal-only-vms [IN] OBSERVATION
Private Google Access only affects VMs without external IP addresses; VMs with external IPs can already reach Google APIs normally and are unaffected by PGA.

### pga-requires-dns-routing-firewall [IN] OBSERVATION
Private Google Access requires correct DNS, routing, and firewall configuration in the VPC network to function.

### pga-source-ip-primary-or-alias [IN] OBSERVATION
PGA traffic can use the VM's primary internal IP or an alias IP range as the source IP.

### pga-vs-psa-vs-psc-distinction [IN] OBSERVATION
Private Google Access reaches Google APIs, Private Services Access connects to services via Service Networking API/peering (e.g., Cloud SQL private IP), and Private Service Connect provides endpoint-based managed service access.

### policy-based-routes-never-exchanged-via-peering [IN] OBSERVATION
Policy-based routes are never exchanged via VPC Network Peering.

### prohibited-subnet-ranges [IN] OBSERVATION
Prohibited VPC subnet ranges include: Google public IPs, 0.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 224.0.0.0/4, 255.255.255.255/32, and Private Google Access VIPs (199.36.153.4/30, 199.36.153.8/30).

### pubsub-at-least-once-delivery [IN] OBSERVATION
Pub/Sub guarantees at-least-once delivery — duplicates are possible, and publish-side duplicates can have different `publishTime` values with the same `messageId`.

### pubsub-attribute-key-no-goog-prefix [IN] OBSERVATION
Pub/Sub message attribute keys must not start with `goog` (reserved prefix).

### pubsub-bigquery-export-uses-topic-schema [IN] OBSERVATION
BigQuery export subscriptions can leverage the topic's schema, which is not available with the basic Dataflow template.

### pubsub-dead-letter-attempt-count-approximate [IN] OBSERVATION
Delivery attempt counting for dead-letter topics is best-effort and approximate — messages may be forwarded after fewer or more attempts than configured.

### pubsub-dead-letter-cross-project-supported [IN] OBSERVATION
Dead-letter topics can reside in a different project from the subscription using `--dead-letter-topic-project`.

### pubsub-dead-letter-iam-requirements [IN] OBSERVATION
The Pub/Sub service account needs `roles/pubsub.publisher` on the dead-letter topic and `roles/pubsub.subscriber` on the source subscription, granted after creating the dead-letter topic.

### pubsub-dead-letter-is-subscription-property [IN] OBSERVATION
Dead lettering is configured as a subscription property, not on the source topic.

### pubsub-dead-letter-max-delivery-attempts-range [IN] OBSERVATION
The `max-delivery-attempts` parameter ranges from 5 (default) to 100.

### pubsub-dead-letter-must-have-subscription [IN] OBSERVATION
The dead-letter topic must have its own subscription to consume forwarded messages; otherwise forwarded messages are lost.

### pubsub-dead-letter-pull-inactive-counter-reset [IN] OBSERVATION
For pull subscriptions with inactive subscribers, the tracked delivery attempt count may reset to zero, causing more deliveries than the configured maximum.

### pubsub-exactly-once-default-ack-deadline-60s [IN] OBSERVATION
The default ack deadline for exactly-once subscriptions is 60 seconds (vs. the normal default).

### pubsub-exactly-once-expired-ack-returns-invalid-argument [IN] OBSERVATION
Expired ack IDs return INVALID_ARGUMENT for exactly-once subscriptions (unlike regular subscriptions which return OK).

### pubsub-exactly-once-ordering-throughput-limit [IN] OBSERVATION
When combining ordering keys with exactly-once delivery, acks must be in-order and throughput drops to approximately thousands of messages per second.

### pubsub-exactly-once-publish-duplicates-still-possible [IN] OBSERVATION
Publish-side duplicates can still occur even with exactly-once delivery enabled (publisher retries can cause duplicate messages).

### pubsub-exactly-once-pull-only [IN] OBSERVATION
Exactly-once delivery is only supported on pull subscriptions (including StreamingPull), not push or export subscriptions.

### pubsub-exactly-once-regional-scope [IN] OBSERVATION
The exactly-once delivery guarantee only applies when subscribers connect to the service in the same region; multi-region subscribers may still receive duplicates.

### pubsub-export-replaces-dataflow-no-transform [IN] OBSERVATION
Export subscriptions replace Dataflow pipelines when no transformation is needed before writing to BigQuery or Cloud Storage.

### pubsub-max-100-attributes-per-message [IN] OBSERVATION
A Pub/Sub message supports a maximum of 100 attributes, with keys ≤256 bytes and values ≤1024 bytes.

### pubsub-message-requires-data-or-attribute [IN] OBSERVATION
A Pub/Sub message must contain at least one of: non-empty data, ordering key, or attributes — all are not required simultaneously.

### pubsub-ordering-constrains-throughput-and-recovery [IN] OBSERVATION
Pub/Sub message ordering imposes cascading operational constraints: it is immutable after subscription creation, caps throughput at 1 MBps per key, and redelivery of one message forces redelivery of all subsequent messages for that key.

### pubsub-ordering-immutable-at-creation [IN] OBSERVATION
Message ordering is set at subscription creation and cannot be changed afterward.

### pubsub-ordering-key-fail-requires-resume-publish [IN] OBSERVATION
If a message with an ordering key fails to publish, subsequent messages with that same key fail until `resumePublish()` is called in the client library.

### pubsub-ordering-key-throughput-limit-1mbps [IN] OBSERVATION
Publish throughput per ordering key is limited to 1 MBps.

### pubsub-ordering-keys-not-partitions [IN] OBSERVATION
Ordering keys are not equivalent to partitions; they are expected to have much higher cardinality than partitions in partition-based systems.

### pubsub-ordering-not-for-dataflow [IN] OBSERVATION
Message ordering should not be enabled for Dataflow subscriptions — Dataflow has its own ordering mechanism via windowing and ordering keys can reduce pipeline performance.

### pubsub-ordering-push-one-outstanding-per-key [IN] OBSERVATION
Push subscriptions allow only one outstanding message per ordering key, resulting in the worst throughput for ordered workloads.

### pubsub-ordering-redelivery-cascades-subsequent [IN] OBSERVATION
Redelivery of one message causes all subsequent messages for that ordering key to be redelivered, even previously acknowledged ones.

### pubsub-per-message-parallelism [IN] OBSERVATION
Pub/Sub uses per-message parallelism (leasing individual messages), not partition-based parallelism like Kafka/Pulsar.

### pubsub-publisher-iam-role [IN] OBSERVATION
`roles/pubsub.publisher` is the minimum IAM role needed to publish messages to a topic.

### pubsub-pull-load-balances-across-subscribers [IN] OBSERVATION
Multiple pull subscribers on the same subscription each receive a subset of messages (load balancing behavior).

### pubsub-pull-supports-dynamic-ack-deadline [IN] OBSERVATION
Pull subscriptions support dynamic acknowledgment deadline extension, allowing arbitrarily long processing times.

### pubsub-push-delivers-http-post [IN] OBSERVATION
Pub/Sub push delivery sends messages as HTTP POST requests to webhooks.

### pubsub-push-one-message-per-request [IN] OBSERVATION
Push subscriptions deliver one message per request and cap outstanding messages; flow control is server-managed.

### pubsub-push-requires-valid-ssl-cert [IN] OBSERVATION
Push endpoints must have DNS-resolvable names and valid SSL certificates (non-self-signed).

### pubsub-rest-api-data-base64-encoded [IN] OBSERVATION
Pub/Sub REST API message data must be base64-encoded.

### pubsub-service-to-service-not-client [IN] OBSERVATION
Pub/Sub is designed for service-to-service communication; use Firebase for client-to-server and Cloud Tasks for async service calls.

### pubsub-three-subscription-types [IN] OBSERVATION
Pub/Sub offers three subscription types: Pull, Push, and Export (BigQuery and Cloud Storage).

### pubsub-typical-latency-100ms [IN] OBSERVATION
Pub/Sub typical latency is approximately 100 milliseconds.

### secretmanager-accessor-only-grants-versions-access [IN] OBSERVATION
The `roles/secretmanager.secretAccessor` role grants only `secretmanager.versions.access` — it cannot list secrets or view metadata.

### secretmanager-avoid-env-vars-and-files [IN] OBSERVATION
Best practice is to avoid passing secrets via environment variables or filesystem and instead use the Secret Manager API directly via client libraries.

### secretmanager-billing-enabled-disabled-not-destroyed [IN] OBSERVATION
Billing applies to Enabled and Disabled secret versions; Destroyed versions are free.

### secretmanager-compute-gke-cloud-platform-scope [IN] OBSERVATION
Workloads on Compute Engine or GKE require the `cloud-platform` OAuth scope to use Secret Manager.

### secretmanager-create-requires-admin-role [IN] OBSERVATION
Creating secrets requires the `roles/secretmanager.admin` (Secret Manager Admin) IAM role.

### secretmanager-creating-secret-no-auto-version [IN] OBSERVATION
Creating a secret via CLI/API does not automatically create a version; the Console creates a first version only if a value is provided during creation.

### secretmanager-default-encryption-aes256-tls [IN] OBSERVATION
Secret Manager encrypts all secrets with AES-256 at rest and TLS in transit by default with no configuration required; CMEK is available for customer-controlled keys.

### secretmanager-destroyed-version-irreversible [IN] OBSERVATION
The Destroyed state for a secret version is irreversible — contents are permanently discarded and the version cannot transition to another state.

### secretmanager-disable-before-destroy [IN] OBSERVATION
Best practice is to disable secret versions before destroying them; disabling is reversible, destroying is not.

### secretmanager-editor-no-secret-access [IN] OBSERVATION
The basic `roles/editor` role does not include `secretmanager.versions.access`; only `roles/owner` among basic roles grants secret access.

### secretmanager-five-predefined-iam-roles [IN] OBSERVATION
Secret Manager has five predefined IAM roles: Admin, Secret Accessor, Secret Version Adder, Secret Version Manager, and Viewer.

### secretmanager-gce-gke-cloud-platform-scope-required [IN] OBSERVATION
Workloads on Compute Engine or GKE require the `cloud-platform` OAuth scope to use Secret Manager.

### secretmanager-iam-conditions-date-and-resource [IN] OBSERVATION
Secret Manager supports IAM Conditions for date/time-based expirable access and resource-attribute filtering (e.g., secret name prefix, specific version).

### secretmanager-iam-granularity-mismatch [IN] OBSERVATION
Secret Manager IAM has a granularity mismatch between role scope and resource structure: roles are granted at the secret level (not per-version), but secrets have three version states (Enabled/Disabled/Destroyed) with distinct access semantics — and the accessor role grants only `versions.access` (no list or metadata), while the viewer role sees metadata but not payloads, forcing dual-role grants for full operational visibility without violating least privilege.

### secretmanager-iam-roles-secret-level-not-version [IN] OBSERVATION
IAM roles cannot be granted on a secret version — only on the secret itself.

### secretmanager-lowest-iam-resource-is-secret [IN] OBSERVATION
The lowest-level resource for granting Secret Manager IAM roles is the individual secret.

### secretmanager-no-expiration-production [IN] OBSERVATION
Expiration on production secrets should be avoided because it causes irreversible deletion; use time-based IAM conditions instead.

### secretmanager-pin-version-not-latest [IN] OBSERVATION
Best practice is to reference secrets by specific version number in production, not the `latest` alias, to enable validation and rollback.

### secretmanager-production-access-pattern [IN] OBSERVATION
Production secret access should use the Secret Manager API directly (not env vars/files), pin to specific version numbers (not latest), and account for the fact that Cloud Run env var secrets resolve only at startup — creating a specific operational model.

### secretmanager-production-integration-requires-application-awareness [IN] OBSERVATION
Secret Manager production integration requires application-level awareness across three dimensions: the access pattern (API-direct with pinned versions, avoiding env var indirection), the rotation model (notification-only, requiring application code to handle credential refresh), and the IAM granularity (per-secret not per-version, meaning version-level access control must be enforced by application logic) — the service stores secrets but delegates lifecycle management to the consuming application.

### secretmanager-regional-not-replicated [IN] OBSERVATION
Regional secrets are not automatically replicated across locations, unlike global secrets.

### secretmanager-regional-requires-regional-service [IN] OBSERVATION
Regional secrets require using the regional service endpoint, not the default global service.

### secretmanager-regional-residency-rest-use-transit [IN] OBSERVATION
Regional secrets ensure data stays within the chosen location at rest, in use, and in transit.

### secretmanager-regional-same-region-access-only [IN] OBSERVATION
Access to regional secrets is limited to applications and services running within the same location.

### secretmanager-remove-rotation-schedule-removes-both [IN] OBSERVATION
The `--remove-rotation-schedule` flag removes both `next_rotation_time` and `rotation_period`, while `--remove-next-rotation-time` removes only the timestamp.

### secretmanager-replication-automatic-or-user-managed [IN] OBSERVATION
Every secret requires a replication policy: `automatic` (Google chooses regions, charged for one location) or `user-managed` (customer selects regions, charged per location).

### secretmanager-rest-api-base64-payload [IN] OBSERVATION
The Secret Manager REST API requires base64-encoded payload data when adding a secret version.

### secretmanager-rotation-next-time-min-5-minutes [IN] OBSERVATION
The `next_rotation_time` for a Secret Manager rotation schedule cannot be less than 5 minutes in the future.

### secretmanager-rotation-notification-only [IN] OBSERVATION
Secret Manager rotation is notification-only: it sends a Pub/Sub message rather than rotating the value, has a 5-minute minimum scheduling window, and removing the schedule clears both period and next-time — actual rotation logic must be implemented externally via subscriber code.

### secretmanager-rotation-period-min-1-hour [IN] OBSERVATION
The `rotation_period` for a Secret Manager rotation schedule cannot be less than 1 hour.

### secretmanager-rotation-retry-7-days [IN] OBSERVATION
Secret Manager retries failed rotation message delivery for up to 7 days, after which the rotation is canceled.

### secretmanager-rotation-sends-pubsub-not-rotates [IN] OBSERVATION
Secret Manager rotation does not rotate the secret value itself — it only sends a `SECRET_ROTATE` notification to configured Pub/Sub topics; the actual rotation logic must be implemented by a subscriber.

### secretmanager-rotation-skips-if-inflight [IN] OBSERVATION
Secret Manager skips scheduled rotations if an in-flight rotation already exists; concurrent rotations are prevented.

### secretmanager-secret-name-max-255-chars [IN] OBSERVATION
Secret names allow uppercase/lowercase letters, numerals, hyphens, and underscores with a maximum length of 255 characters.

### secretmanager-secret-value-max-64kib [IN] OBSERVATION
Secret version values must not exceed 64 KiB in size.

### secretmanager-secrets-global-by-default [IN] OBSERVATION
Secrets are global resources by default; regional secrets exist for data residency compliance.

### secretmanager-stores-values-kms-stores-keys [IN] OBSERVATION
Secret Manager stores actual secret values (viewable with permissions); Cloud KMS stores cryptographic keys (never viewable/extractable).

### secretmanager-version-data-immutable [IN] OBSERVATION
Secret Manager secret data is immutable — modifications require adding a new version rather than changing existing ones.

### secretmanager-version-three-states [IN] OBSERVATION
Secret versions have three states: Enabled (accessible), Disabled (exists but not accessible, re-enableable), and Destroyed (permanently discarded, irreversible).

### secretmanager-viewer-no-payload-access [IN] OBSERVATION
The `roles/secretmanager.viewer` role can read secret and version metadata but cannot access secret payloads.

### secretmanager-vpc-service-controls-network-protection [IN] OBSERVATION
VPC Service Controls can add network-level perimeter protection to Secret Manager API access in addition to IAM.

### serverless-cloudsql-private-access-triple-constrained [IN] OBSERVATION
Accessing Cloud SQL privately from serverless compute (Cloud Run) requires navigating three networking layers: (1) explicit VPC bridging for serverless egress, (2) private services access VPC peering for Cloud SQL, and (3) peering's inherent constraints (non-transitivity, no overlapping subnets, no IAM exchange) — each layer adds configuration surface and distinct failure modes.

### serverless-memorystore-doubly-constrained-private-access [IN] OBSERVATION
Serverless access to Memorystore for Redis is doubly constrained: Memorystore enforces private-IP-only connectivity (no public exposure, 300GB cap, no AOF persistence, basic tier lacks replication) AND serverless workloads require explicit VPC bridging (Direct VPC egress or connector VMs) to reach any VPC-private resource, creating a two-layer networking dependency chain where either layer's failure blocks connectivity entirely.

### serverless-multi-tenant-compounds-bridging-and-connectivity [IN] OBSERVATION
Serverless workloads in multi-tenant GCP environments face compounding network constraints from two independent layers: multi-network connectivity is fundamentally limited regardless of model (Shared VPC requires same-org hierarchy, peering is non-transitive with no IAM exchange), AND serverless resources require explicit VPC bridging just to reach any VPC network — meaning serverless in a shared network must solve both the bridging gap and the connectivity model constraints simultaneously.

### serverless-multi-tenant-worst-case-networking [IN] OBSERVATION
Multi-tenant serverless architectures requiring private data access must configure the full VPC connectivity stack (VPC, NAT, connectors/direct VPC egress, private services access) for each tenant's isolation boundary, multiplying the networking complexity per tenant.

### serverless-private-data-access-five-layer-stack [IN] OBSERVATION
Serverless workloads accessing private data must navigate five dependency layers: (1) VPC bridging for network egress, (2) peering non-transitivity for database reach, (3) private services access for Cloud SQL IP allocation, (4) Secret Manager API integration with fail-fast startup semantics, and (5) rotation notification gaps requiring application-level credential refresh — each layer adds a failure mode invisible from the serverless abstraction.

### serverless-production-networking-contradicts-serverless-promise [IN] OBSERVATION
Production serverless workloads requiring private data access need VPC configuration, NAT gateways, and private connectivity — networking infrastructure that adds significant complexity to otherwise simple serverless deployments.

### serverless-vpc-connectivity-requires-explicit-bridging [IN] OBSERVATION
Serverless resources (Cloud Run, Cloud Run functions, App Engine) cannot natively reach VPC networks — they require explicit VPC bridging via Direct VPC egress or Serverless VPC Access connectors, connectivity is egress-only from serverless to VPC, and services like Memorystore mandate this bridging for access.

### shared-vpc-billing-to-service-project [IN] OBSERVATION
Shared VPC resource costs are billed to the service project, except VPN gateway egress (billed to host project) and VLAN attachment traffic (billed to attachment owner).

### shared-vpc-cannot-be-host-and-service [IN] OBSERVATION
A project cannot be both a Shared VPC host project and a service project simultaneously.

### shared-vpc-existing-resources-not-migrated [IN] OBSERVATION
Existing resources in a newly attached service project do not automatically use the shared network; new resources must be created to use shared subnets.

### shared-vpc-internal-dns-uses-service-project-id [IN] OBSERVATION
Internal DNS names for VMs in Shared VPC use the service project's project ID, not the host project ID.

### shared-vpc-legacy-networks-not-supported [IN] OBSERVATION
Legacy networks are not supported for Shared VPC.

### shared-vpc-network-user-role-grants-subnet-access [IN] OBSERVATION
The compute.networkUser role grants subnet access — at project level (all subnets including future) or at subnet level (specific subnets only).

### shared-vpc-same-organization-required [IN] OBSERVATION
Host and service projects must be in the same Google Cloud organization for Shared VPC.

### shared-vpc-service-project-one-host-only [IN] OBSERVATION
A service project can attach to only one host project; multiple host projects are allowed per organization.

### shared-vpc-strict-organizational-hierarchy [IN] OBSERVATION
Shared VPC enforces a strict organizational hierarchy for multi-tenant networking: host and service projects must share an organization, each service project attaches to exactly one host project, DNS uses service project IDs, and GKE follows the same host-service pattern for cluster networking.

### spanner-deletes-database-cmek-unavailable-30-days [IN] OBSERVATION
Spanner automatically deletes a database if its CMEK key is unavailable for more than 30 consecutive days.

### special-ip-ranges-health-checks [IN] OBSERVATION
Google health check probe IP ranges include 35.191.0.0/16 and 130.211.0.0/22; IAP uses 35.235.240.0/20; Cloud DNS uses 35.199.192.0/19; Serverless VPC Access uses 35.199.224.0/19.

### special-routing-paths-non-removable [IN] OBSERVATION
Special routing paths (health checks, IAP, DNS, etc.) are non-removable and do not appear in the route table.

### subnet-four-reserved-ips-primary-range [IN] OBSERVATION
Each primary IPv4 subnet range has 4 unusable addresses: network (first), default gateway (second), second-to-last (reserved), and broadcast (last). Secondary ranges have no reserved addresses.

### subnet-minimum-size-slash-29 [IN] OBSERVATION
Minimum VPC subnet size is /29 (8 addresses). Recommended maximum is /8.

### subnet-primary-range-expand-not-shrink [IN] OBSERVATION
Primary IPv4 subnet ranges can be expanded but never shrunk after creation.

### subnet-routes-always-win-over-custom [IN] OBSERVATION
Subnet routes always take precedence over static and dynamic routes for overlapping destinations, unless using hybrid subnets.

### subnets-are-regional-vpcs-are-global [IN] OBSERVATION
VPC subnets are regional resources while VPC networks are global resources.

### vpc-firewall-asymmetric-stateful-evaluation [IN] OBSERVATION
VPC firewalls implement an asymmetric, stateful security posture: default rules deny all ingress but allow all egress (asymmetric baseline), connection tracking expires after 10 minutes of idle (stateful with silent timeout), and source port filtering is unsupported (coarse-grained matching) — the net effect is that outbound-initiated connections are permissive by default but their return path depends on connection tracking state that silently expires.

### vpc-firewall-connection-tracking-10min-idle [IN] OBSERVATION
VPC firewall connection tracking expires after 10 minutes of inactivity.

### vpc-firewall-default-priority-1000 [IN] OBSERVATION
The default priority for VPC firewall rules is 1000; priority range is 0–65535 (lower = higher priority).

### vpc-firewall-deny-beats-allow-same-priority [IN] OBSERVATION
At equal priority, deny rules override allow rules in VPC firewall evaluation.

### vpc-firewall-no-source-port-filtering [IN] OBSERVATION
VPC firewall rules support destination port specification only; source port filtering is not supported.

### vpc-firewall-per-network-no-sharing [IN] OBSERVATION
VPC firewall rules are scoped to a single VPC network and cannot be shared across networks, including peered networks.

### vpc-firewall-rules-stateful [IN] OBSERVATION
VPC firewall rules are stateful — return traffic for allowed connections is automatically permitted.

### vpc-flow-logs-asymmetric-firewall-visibility [IN] OBSERVATION
VPC Flow Logs provide asymmetric visibility into firewall-blocked traffic: egress denied packets are captured (sampled before egress firewall evaluation) but ingress denied packets are not captured — creating a systematic blind spot for inbound attack detection that must be supplemented with firewall rule logging or other network security tooling.

### vpc-flow-logs-default-aggregation-5s [IN] OBSERVATION
The default VPC Flow Logs aggregation interval is 5 seconds.

### vpc-flow-logs-egress-denied-are-captured [IN] OBSERVATION
Egress packets blocked by firewall rules are captured by VPC Flow Logs (sampled before egress firewall evaluation).

### vpc-flow-logs-gke-intranode-visibility-required [IN] OBSERVATION
GKE intra-node pod-to-pod traffic requires intranode visibility to be enabled for VPC Flow Logs capture.

### vpc-flow-logs-ingress-denied-not-captured [IN] OBSERVATION
Ingress packets blocked by firewall rules are not captured by VPC Flow Logs.

### vpc-flow-logs-no-performance-impact [IN] OBSERVATION
Enabling VPC Flow Logs introduces no delay or performance impact.

### vpc-flow-logs-secondary-sampling-defaults-differ [IN] OBSERVATION
Default secondary sampling rate for VPC Flow Logs is 50% via Compute Engine API and 100% via Network Management API.

### vpc-flow-logs-shared-vpc-host-project [IN] OBSERVATION
VPC Flow Logs for Shared VPC are written to the host project, not service projects.

### vpc-implied-firewall-rules-deny-ingress-allow-egress [IN] OBSERVATION
Every VPC has two implied firewall rules: deny all ingress and allow all egress.

### vpc-metadata-server-always-accessible [IN] OBSERVATION
The metadata server at 169.254.169.254 is always accessible regardless of firewall rules and cannot be blocked.

### vpc-network-global-subnets-regional [IN] OBSERVATION
VPC networks are global resources; subnets are regional.

### vpc-peering-cloud-router-no-auto-advertise-peered-subnets [IN] OBSERVATION
Cloud Router does not auto-advertise received peering subnet routes; custom advertisement mode with explicit ranges is required.

### vpc-peering-custom-routes-not-exchanged-by-default [IN] OBSERVATION
Static and dynamic routes are not exchanged by default in VPC Peering; must enable --export-custom-routes and --import-custom-routes.

### vpc-peering-dns-does-not-resolve-across-peers [IN] OBSERVATION
Internal DNS names do not resolve across peered VPC networks; Cloud DNS peering zones are required.

### vpc-peering-exporting-network-dynamic-routing-mode-controls [IN] OBSERVATION
The dynamic routing mode of the exporting network determines regional vs global availability of peering dynamic routes; the importing network's mode is irrelevant.

### vpc-peering-firewall-rules-not-exchanged [IN] OBSERVATION
Firewall rules are not exchanged via VPC Peering; each VPC must independently create ingress allow rules.

### vpc-peering-limited-connectivity-model [IN] OBSERVATION
VPC peering provides constrained connectivity: it is non-transitive, never exchanges IAM policies, prohibits overlapping subnets, and does not auto-advertise peered routes via Cloud Router.

### vpc-peering-never-exchanges-iam [IN] OBSERVATION
VPC Network Peering exchanges subnet routes automatically but never exchanges IAM policies.

### vpc-peering-no-overlapping-subnets [IN] OBSERVATION
Subnet IP ranges cannot overlap across peered VPC networks; peering will fail if they do.

### vpc-peering-non-transitive [IN] OBSERVATION
VPC Peering is non-transitive — if A peers with B and B peers with C, A cannot reach C through B.

### vpc-peering-two-auto-mode-cannot-peer [IN] OBSERVATION
Two auto mode VPC networks cannot be peered because both use ranges within 10.128.0.0/9.

### vpc-route-evaluation-order [IN] OBSERVATION
VPC route evaluation order: Special routing paths → Policy-based routes → Subnet routes → Custom routes (static/dynamic) → System-generated default routes.

### vpc-security-dual-asymmetry-enforcement-and-visibility [IN] OBSERVATION
VPC security has dual asymmetry in enforcement and observability that creates a blind spot at the ingress boundary: firewall rules default to deny-all-ingress/allow-all-egress (asymmetric enforcement), while flow logs capture denied-egress but miss denied-ingress (asymmetric visibility) — the traffic most aggressively blocked by default is precisely the traffic invisible to forensic analysis.

### vpc-shared-requires-same-org [IN] OBSERVATION
Shared VPC uses a host project model and requires all projects to be in the same organization.

### vpc-smtp-port25-egress-blocked-by-default [IN] OBSERVATION
Port 25 (SMTP) egress to external IPs is blocked by default by Google Cloud (not via a firewall rule).

### vpc-ula-ipv6-slash-48-permanent [IN] OBSERVATION
A VPC network's /48 ULA IPv6 range (from fd20::/20) is globally unique within Google Cloud and cannot be removed or changed once assigned.

### vpc-vms-multiple-nics-different-networks [IN] OBSERVATION
VMs can have multiple network interfaces attached to different VPC networks.

### wif-direct-access-preferred-over-impersonation [IN] OBSERVATION
Direct resource access (granting IAM roles directly to federated identities) is preferred over service account impersonation; impersonation requires `roles/iam.workloadIdentityUser`.

### wif-eliminates-service-account-keys [IN] OBSERVATION
Workload Identity Federation is the recommended alternative to service account keys for external workloads accessing Google Cloud resources.

### wif-google-subject-required-127-chars [IN] OBSERVATION
The `google.subject` attribute mapping is required for all workload identity pool providers and has a maximum length of 127 characters.

### wif-one-pool-per-environment [IN] OBSERVATION
Best practice is one workload identity pool per non-Google Cloud environment (dev, staging, prod).

### wif-principal-uses-project-number [IN] OBSERVATION
Workload Identity Federation principal identifiers use project number (not project ID) in fully qualified resource names.

### wif-supported-idp-protocols [IN] OBSERVATION
Workload Identity Federation supports identity providers using OIDC, SAML V2.0, X.509 certificates, AWS, Azure, Active Directory, GitHub, and GitLab.

### wif-token-exchange-rfc8693 [IN] OBSERVATION
Workload Identity Federation token exchange follows the OAuth 2.0 token exchange spec (RFC 8693) via the Security Token Service (STS).

### wif-unified-keyless-auth-across-workload-types [IN] OBSERVATION
Workload Identity Federation provides keyless authentication for GKE workloads and external identities, serving as the recommended alternative to service account keys and reducing credential management overhead.

### wif-up-to-50-custom-attributes [IN] OBSERVATION
Workload identity pool providers support up to 50 custom attributes for `principalSet://` bindings.
