Introduction

Welcome back to GCP Security and Networking Fundamentals! In this lesson, we move beyond user and group management to explore a core GCP security concept: service accounts and IAM roles. While users and groups are great for managing human access, service accounts are designed for applications and services running on Google Cloud. They provide a secure, manageable way for your workloads — such as virtual machines and serverless functions — to access other GCP resources. By the end of this lesson, you'll know how to create service accounts, grant them the right permissions, assign them to resources, and review their access, all using Python and GCP APIs.

Understanding the Power of Service Accounts

Before we dive into implementation, let's clarify what service accounts are and why they're essential in GCP. Unlike user accounts, which represent people, a service account is a special identity intended for applications, virtual machines, or other compute workloads. Service accounts allow these workloads to authenticate to GCP APIs and access resources securely, without embedding user credentials or managing passwords.

Think of a service account as a digital identity badge for your application. When you assign a service account to a VM or a Cloud Function, that workload can act as the service account and use its permissions to interact with other GCP services. This approach keeps your environment secure and makes it easy to follow best practices like least privilege.

Controlling Access to Service Accounts

In GCP, access control is managed through IAM policies. You can grant permissions to service accounts, users, or groups by assigning them IAM roles on specific resources. Additionally, you can control which identities are allowed to "impersonate" or "act as" a service account by granting the roles/iam.serviceAccountUser role. This ensures that only trusted users or services can use a service account's identity to access resources.

Permissions in GCP are always explicit: you must grant a service account the necessary roles to access resources, and you must grant users or other service accounts the ability to use or manage a service account. This separation of duties helps maintain a strong security posture.

Authentication Note: mock environment vs. production credentials

Throughout this course, Unit 2 uses the same mock GCP environment as the other units. That means all discovery clients should be built with:

  • os.environ.get("GCP_DISCOVERY_URL")
  • credentials=None
  • static_discovery=False

Why is credentials=None acceptable here? Because requests are sent to a local practice service rather than real Google Cloud APIs, so real authentication is not required.

Why do we also set static_discovery=False? Some versions of google-api-python-client can otherwise fall back to built-in discovery metadata and send requests to real Google API endpoints. In this course, we want to force the client to use the mock discovery URL so all practice code stays inside the local training environment.

In production, things work differently:

  • your Python client must authenticate to Google Cloud
  • the recommended approach is usually Application Default Credentials (ADC)
  • when a workload runs on GCP with an attached service account, the workload can often obtain credentials automatically from the metadata service
  • when running locally, ADC is commonly set up with gcloud auth application-default login or by using a configured service account in a secure way

So, in this lesson, remember the distinction:

  • mock environment: credentials=None and static_discovery=False
Creating Your First Service Account

Let's create a service account that will allow a Compute Engine VM to read objects from Cloud Storage. We'll use the Google API discovery client to automate this process in the course mock environment.

Zone note: what is us-central1-a?

In GCP, a region is a geographic area such as us-central1, and a zone is a specific deployment location inside that region, such as us-central1-a or us-central1-b.

When creating zonal resources like Compute Engine VMs, you must choose a zone. In this lesson, we use the ZONE environment variable and default it to us-central1-a simply to keep examples concrete and easy to run.

How do you choose a zone in practice?

  • pick a zone in the region where you want your workload to run
  • keep related resources close together when latency matters
  • consider availability and redundancy if you plan to spread workloads across zones

For this course, using a configurable ZONE variable is enough. In production, you may choose zones based on architecture, quotas, service availability, and resilience requirements.

Granting Permissions Through IAM Roles

A service account without permissions can't access any resources. In GCP, you grant permissions by assigning IAM roles to the service account. GCP provides many predefined roles for common use cases, such as roles/storage.objectViewer for read-only access to Cloud Storage or roles/datastore.user for Datastore access.

You can grant roles at different levels: project, folder, or resource. For most workloads, granting a role at the project level is sufficient, but you can scope it down to a specific bucket or database for tighter security.

Predefined roles are maintained by Google and cover most common scenarios. For more granular control, you can create custom roles with exactly the permissions your workload needs.

Assigning Service Accounts to Compute Engine VMs

When you create a Compute Engine VM, you can specify which service account it should use. The VM will automatically receive credentials for that service account, allowing applications running on the VM to access GCP resources according to the service account's permissions.

If you need to change the service account for an existing VM, you can do so using the Compute Engine API or the Google Cloud Console. The VM will then use the new service account's permissions for all future API calls.

Note: In real GCP environments, applications on the VM should usually rely on Application Default Credentials (ADC) rather than embedding keys in code. When a service account is attached to the VM, the workload can typically obtain credentials automatically.

Production Note: Custom Roles and Least Privilege
  • In these examples, we use predefined roles for simplicity.
  • In production, follow the principle of least privilege: grant only the permissions your workload needs, and nothing more.
  • You can create custom roles in GCP to specify exactly which permissions are allowed.

Example: Custom role for read-only access to a specific Cloud Storage bucket

Best practices:

  • Grant roles at the lowest possible resource level (e.g., a single bucket, not the whole project).
  • Regularly review service account permissions and remove unnecessary access.
Building Specialized Service Accounts for Cloud Functions

Different GCP services require different service accounts and permissions. Let's create a service account for a Cloud Function that needs to write to Firestore.

This creates a service account, grants it Firestore access, and deploys a Cloud Function using that service account.

Analyzing Service Account Permissions and Auditing Access

After creating service accounts and assigning roles, it's important to review their permissions and audit access. You can use the IAM API to list the roles granted to a service account.

For auditing, GCP provides Cloud Audit Logs, which record all access to resources, including which service account was used. You can review these logs in the Cloud Console or export them for analysis.

Orchestrating Complete Service Account Workflows

Let's put it all together: create service accounts, grant roles, assign them to resources, and inspect their permissions.

Conclusion and Next Steps

In this lesson, you've learned how GCP uses service accounts and IAM roles to manage secure, fine-grained access for applications and services. You now know how to create service accounts, grant them predefined or custom roles, assign them to resources like VMs and Cloud Functions, and review their permissions. In this course's mock environment, we build discovery clients with os.environ.get("GCP_DISCOVERY_URL"), credentials=None, and static_discovery=False so the client stays inside the mock environment. In real GCP environments, use Application Default Credentials (ADC) or another supported authentication flow. Remember to always follow the principle of least privilege: grant only the permissions needed, and regularly review access. In production, use custom roles and resource-level scoping to keep your cloud environment secure and manageable.

In the next lesson, we'll explore more advanced IAM features and best practices for securing your GCP workloads.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal