Deployer vs runtime service account
Oct 16, 2026 · 2 min read
When you work with service accounts in Google Cloud, one question matters more than it seems: how do you split responsibilities between them?
The easy option is one service account for everything. It deploys your pipeline and runs it in production. But then your CI job has direct access to production data, and your pipeline can change its own infrastructure.
The better option is to split them by stage: a deployer service account and a runtime service account. 2 stages, 2 different needs.
Deploy: deployer-sa
A developer merges code. GitHub Actions logs in as deployer-sa through Workload Identity Federation, builds the image and deploys the pipeline. It changes infrastructure, so it needs roles like:
roles/cloudbuild.builds.editor: build the imageroles/workflows.editor: deploy the workflowroles/cloudscheduler.admin: deploy the scheduler jobroles/iam.serviceAccountUser(onruntime-sa): let the workflow and scheduler job run asruntime-sa
Run: runtime-sa
The pipeline runs in production. Cloud Scheduler triggers the workflow, which runs queries and ML pipelines, all as runtime-sa. It works with data, so it needs roles like:
roles/workflows.invoker: trigger the workflowroles/bigquery.jobUser: run queriesroles/aiplatform.user: run Vertex AI pipelines (now Agent Platform)
Simple rule
- deployer →
.editor/.admin, runs for minutes after a merge - runtime →
.user/.invoker, used on every pipeline run

