Skip to main content

Service Account & IAM

EZ-CDC uses two service accounts in your GCP project, both created by a one-time setup script (not by Terraform):

ComponentPurposeCreated By
Deployer Service AccountIdentity the EZ-CDC control-plane uses to provision infrastructureYou (one-time setup script)
Worker Service AccountIdentity attached to worker GCE instances at runtimeYou (one-time setup script)
Workload Identity FederationLets the AWS-based control-plane impersonate the deployer SAYou (one-time setup script)

Splitting deployer and worker keeps the permission model easy to reason about: the deployer only exists for orchestration, and the worker only exists for runtime on the instances.

Deployer Service Account​

The deployer SA is used by the EZ-CDC control-plane (through Workload Identity Federation) to create and update worker infrastructure, and to run read-only preflight checks before Terraform starts. It is not the identity that runs on the worker VMs after deployment.

Project-level roles granted to the deployer SA:

RolePurpose
roles/compute.instanceAdmin.v1Create and update VM-related resources
roles/compute.networkAdminWork with network resources for the deployment
roles/compute.securityAdminManage firewall rules and related network security

Service-account-level bindings (scoped to the deployment's two SAs, not the whole project):

BindingOnPurpose
roles/iam.workloadIdentityUserdeployer SALet the WIF principal impersonate the deployer
roles/iam.serviceAccountTokenCreatordeployer SAMint short-lived tokens via WIF
roles/iam.serviceAccountUserworker SAAttach the worker SA to VMs during deployment
roles/iam.serviceAccountAdminworker SACreate/delete the worker SA during cleanup
roles/iam.serviceAccountAdmindeployer SADelete the deployer SA during cleanup

Worker Service Account​

The worker SA is attached to worker GCE instances. Its account ID is derived from your deployment ID to ensure uniqueness:

ez-cdc-wk-{deployment-hash}@YOUR_PROJECT.iam.gserviceaccount.com

It is intentionally minimal. The worker SA does not get project-level logging.logWriter / monitoring.metricWriter roles: telemetry is shipped by the worker-agent to Victoria Metrics and logs by Fluent Bit to Victoria Logs, not through Cloud Logging / Cloud Monitoring.

GCS Access​

Workers download binaries from the EZ-CDC releases bucket at bootstrap. The instance template runs with the read-only storage scope (https://www.googleapis.com/auth/devstorage.read_only) for this — no broad cloud-platform scope.

Workload Identity Federation​

EZ-CDC's control-plane runs in AWS and needs to deploy Terraform in your GCP project. This is done through Workload Identity Federation (WIF), which allows the AWS-based control-plane to authenticate to GCP without exported service account keys.

How It Works​

EZ-CDC Control Plane (AWS)
│
├── AWS IAM Role → STS Token
│
└── GCP Workload Identity Federation
│
├── Validates AWS STS token
├── Maps to the deployer Service Account
└── Issues short-lived GCP credentials

Security Benefits​

  • No exported keys: No long-lived service account JSON keys
  • Short-lived tokens: GCP credentials are temporary and auto-rotate
  • AWS identity verified: GCP validates the AWS caller identity
  • Auditable: All access logged in Cloud Audit Logs

What EZ-CDC Can Do​

✅ Allowed:

  • Create and manage worker infrastructure (deployer SA)
  • Read cloud metadata for preflight validation (deployer SA, read-only)
  • Download binaries from ez-cdc-releases-gcp (worker SA)
  • Attach the worker SA to instances during deployment

❌ Not Allowed:

  • Access your databases
  • Access your Cloud Storage buckets
  • Create or modify unrelated IAM principals
  • Access other GCP services

The control-plane never connects directly to your databases; worker instances inside your project handle all customer-side connectivity.

Verification​

Check Service Accounts​

gcloud iam service-accounts list \
--project=YOUR_PROJECT_ID \
--filter="email:ez-cdc-*"

Check IAM Bindings​

gcloud projects get-iam-policy YOUR_PROJECT_ID \
--flatten="bindings[].members" \
--filter="bindings.members:ez-cdc-*" \
--format="table(bindings.role, bindings.members)"

Audit Access​

Monitor Service Account usage in Cloud Audit Logs:

resource.type="service_account"
protoPayload.authenticationInfo.principalEmail="ez-cdc-*@YOUR_PROJECT.iam.gserviceaccount.com"

Next Steps​