15.1 Creating Service Accounts & Assigning Least-Privilege Permissions
Key Takeaways
- Service account IDs are locked at creation: 6-30 characters, lowercase alphanumeric and dashes, never renamable.
- Default service accounts auto-receive the Editor role -- disable that grant and build dedicated, narrowly-scoped accounts instead.
- Creation requires roles/iam.serviceAccountCreator; granting project roles on top requires roles/resourcemanager.projectIamAdmin.
- One service account per workload keeps Cloud Audit Logs attributable to a single application.
- Disable before deleting -- a same-named replacement account gets a brand-new identity with none of the old bindings.
Why This Matters on the ACE Exam
Domain 5, "Configuring access and security," is worth 17.5% of the exam, and roughly half of that domain is about service accounts -- non-human identities that Google Cloud services and applications use to call APIs. The official exam guide lists "Creating service accounts" and "Using service accounts in IAM policies with minimum permissions" as explicit bullets, and in practice this is one of the highest-yield topics on the test: expect scenario questions that ask you to pick the least-privileged way for a VM, Cloud Function, or CI/CD pipeline to reach another Google Cloud resource.
What Is a Service Account?
A service account is a special kind of account meant for a workload (a VM, a container, a pipeline, an API caller) rather than a person. Every service account has two identities at once:
- As a principal -- it can be granted IAM roles to access other resources, exactly like a human user.
- As a resource -- other principals (users or other service accounts) can be granted IAM roles on the service account itself, controlling who may use or manage it.
This dual nature is the single most-tested conceptual point in this section, and the next section (15.2) builds directly on it.
Each service account gets a permanent, unique numeric ID and an email-style identifier in the format:
SA_NAME@PROJECT_ID.iam.gserviceaccount.com
For example, billing-exporter@acme-prod.iam.gserviceaccount.com.
Naming Rules (Frequently Tested)
- The account ID (
SA_NAME) must be 6 to 30 characters, lowercase alphanumeric characters and dashes only. - The ID cannot be changed after creation -- only the display name and description are editable later.
- Allow up to 60 seconds after creation before the account is fully visible everywhere (IAM policy bindings, consoles, APIs).
Three Kinds of Service Accounts
| Type | Created By | Example |
|---|---|---|
| User-managed | You, for your own workloads | deploy-bot@my-project.iam.gserviceaccount.com |
| Default | Google, automatically when you enable a service | Compute Engine default SA, App Engine default SA |
| Service agents | Google, for its own internal service-to-service calls | service-PROJECT_NUMBER@gcp-sa-*.iam.gserviceaccount.com |
Default service accounts are a classic exam trap. The Compute Engine and App Engine default service accounts are automatically granted the broad Editor role (roles/editor) on the project the first time the relevant API is enabled. Editor lets the account read and modify almost every resource type in the project -- nowhere close to least privilege. Google explicitly recommends disabling this automatic grant (using the organization policy constraint that disables automatic IAM grants for default service accounts) and instead creating a purpose-built service account with only the roles a given workload actually needs.
Who Can Create a Service Account?
Creating a new service account requires the Service Account Creator role (roles/iam.serviceAccountCreator), which contains the iam.serviceAccounts.create permission. If you also need to grant that new account roles on the project, you additionally need Project IAM Admin (roles/resourcemanager.projectIamAdmin) or an equivalent broader role such as Owner.
# Create the service account
gcloud iam service-accounts create billing-exporter \
--display-name="Billing Export Job" \
--description="Writes daily billing exports to BigQuery"
# Grant it a project-level role (least privilege, not Editor)
gcloud projects add-iam-policy-binding acme-prod \
--member="serviceAccount:billing-exporter@acme-prod.iam.gserviceaccount.com" \
--role="roles/bigquery.dataEditor"
Least-Privilege Design in Practice
The exam consistently rewards the narrowest workable answer. Apply these rules when a scenario asks "what should this service account be granted?":
- One service account per application/workload, not one shared account across many apps. Sharing collapses your audit trail -- you can no longer tell which application performed a given action in Cloud Audit Logs.
- Prefer predefined roles scoped to a single service (for example,
roles/bigquery.dataEditor,roles/pubsub.publisher) over broad roles like Editor or Owner. - Use a custom role only when no predefined role is narrow enough -- custom roles let you hand-pick individual permissions.
- Use Policy Analyzer / IAM Recommender (the Policy Intelligence tools) to detect and remove permissions a service account has never actually used.
- Disable, then delete. Never delete a still-in-use service account outright. If you delete an account and later create a new one with the same name, it receives a different, new identity, and none of the old IAM bindings apply to it.
Exam Scenario
A team deploys a new Compute Engine VM that only needs to read objects from one Cloud Storage bucket. The VM is launched using the Compute Engine default service account, which still carries the Editor role. What is the least-privilege fix?
The correct move is not to add more roles to the default account -- it is to create a new, dedicated service account with only roles/storage.objectViewer on that one bucket, attach it to the VM, and disable the Editor grant on the default account (or stop using the default account altogether).
Key IAM Roles for Managing Service Accounts (Preview of 15.2)
| Role | Lets You... |
|---|---|
roles/iam.serviceAccountCreator | Create new service accounts |
roles/iam.serviceAccountAdmin | View, edit, disable, delete service accounts |
roles/iam.serviceAccountUser | Attach a service account to a resource / impersonate it |
roles/iam.serviceAccountKeyAdmin | Create and delete service account keys |
Takeaways
- Service account IDs are locked at creation: 6-30 characters, lowercase alphanumeric and dashes, never renamable.
- Default service accounts auto-receive Editor -- disable that grant and build dedicated, narrowly-scoped accounts instead.
- Creation requires
roles/iam.serviceAccountCreator; granting project roles on top requiresroles/resourcemanager.projectIamAdmin. - One service account per workload keeps Cloud Audit Logs attributable to a single application.
- Disable before deleting -- a same-named replacement account gets a brand-new identity with none of the old bindings.
A Compute Engine instance is running on the project's default service account, which still carries the auto-granted Editor role. The workload only needs to read objects from one Cloud Storage bucket. What is the least-privilege fix?
Which IAM role must a user hold to create a brand-new service account in a Google Cloud project?