gcp-cloudsql-explicit-read-replica-cross-project
A Cloud SQL read replica created in a different project enables cross-project access: principals in the replica's project can query the replica and read source database data.
match (record)
{
"api": "sqladmin.instances.get",
"field": "replicaConfiguration",
"resource_type": "google.sql.Instance"
}
where
instance.kind == REPLICA_INSTANCE
instance.replicaConfiguration.masterInstanceName is in a different project
emit
| source type | Project |
|---|---|
| target type | Project |
| source | <source instance's project> |
| target | <replica instance's project> |
| permissions | cloudsql.instances.create (with replicaConfiguration) cloudsql.instances.connect on replica |
| conditions | iam_permission service_state |
| state logic | ACTIVE when a read replica is confirmed in a different project, both instances are RUNNABLE, and the replication is active; CONDITIONAL(service_state) when instance states cannot be confirmed or replication is suspended. |
Narrative
Cloud SQL read replica {replica.name} is located in project {replica_project.name} and replicates data from source instance {source_instance.name} in project {source_project.name}. Principals in the replica's project can query the replica and read source database data without source-project IAM bindings covering that access.
Raw rule rules/explicit/gcp-cloudsql.yaml
id: gcp-cloudsql-explicit-read-replica-cross-project
emits: CrossProjectTrust
description: 'A Cloud SQL read replica created in a different project enables cross-project access: principals
in the replica''s project can query the replica and read source database data.'
applies_to:
- gcp
match_record:
api: sqladmin.instances.get
resource_type: google.sql.Instance
field: replicaConfiguration
where:
- instance.kind == REPLICA_INSTANCE
- instance.replicaConfiguration.masterInstanceName is in a different project
emit:
source_type: Project
target_type: Project
source: <source instance's project>
target: <replica instance's project>
permissions:
- cloudsql.instances.create (with replicaConfiguration)
- cloudsql.instances.connect on replica
conditions:
- iam_permission
- service_state
state_logic: ACTIVE when a read replica is confirmed in a different project, both instances are RUNNABLE,
and the replication is active; CONDITIONAL(service_state) when instance states cannot be confirmed
or replication is suspended.
false_positive_note: 'A read replica in a different project is a valid Cloud SQL replication path (documented
in cloudsql.md Sections 10 & 15). The replica replicates data from the source instance to the replica''s
project. Principals in the replica''s project can query the replica via standard Cloud SQL access
controls (cloudsql.instances.connect, cloudsql.instances.login if IAM auth enabled). This creates
a cross-project read access path: a principal controlling the replica''s project (or holding cloudsql.instanceUser
on the replica) can read all source data replicated there, OUTSIDE the source project''s IAM policies.
Model as CrossProjectTrust(source_project -> replica_project). The replica''s replication service
account must hold cross-project permissions to read from the source instance; this is typically granted
by the source project admin.'
narrative: Cloud SQL read replica {replica.name} is located in project {replica_project.name} and replicates
data from source instance {source_instance.name} in project {source_project.name}. Principals in the
replica's project can query the replica and read source database data without source-project IAM bindings
covering that access.
api_source: sqladmin.instances.get (replicaConfiguration and masterInstanceName)
evidence_field: instance.kind == REPLICA_INSTANCE + replicaConfiguration cross-project masterInstanceName
derived_from:
- google.sql.Instance.kind == REPLICA_INSTANCE
- google.sql.Instance.replicaConfiguration.masterInstanceName in different project