Back to Checks
gcp

Service account has no administrative privileges

iam_sa_no_administrative_privileges
Service: iamSeverity: high
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:iam.googleapis.com/ServiceAccount

Google Cloud service accounts with high-privilege IAM roles are identified, including roles/owner, roles/editor, or any role containing admin. The evaluation looks for service accounts bound to these roles in IAM policies across the project hierarchy.

Risk

Over-privileged service accounts jeopardize the CIA triad:

  • Confidentiality: data can be read and exfiltrated
  • Integrity: configs, IAM, and code can be altered
  • Availability: resources can be deleted or halted

Compromise via key theft or impersonation enables lateral movement and persistence.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler gcp --checks iam_sa_no_administrative_privileges

Recommendation

Apply least privilege: replace roles/owner, roles/editor, and roles containing admin with narrowly scoped predefined or custom roles. Use separation of duties, temporary elevation, and IAM Conditions to limit scope and time. Prefer impersonation over long-lived keys and monitor SA usage.

Remediation

CLI

gcloud projects remove-iam-policy-binding <PROJECT_ID> --member=serviceAccount:<SERVICE_ACCOUNT_EMAIL> --role=<ROLE>

Other

1In the Google Cloud console, go to IAM & Admin > IAM
2Select the project (or switch to the folder/organization) where the role is granted
3Find the service account by email and click Edit principal
4Remove roles: Owner, Editor, and any role with "Admin" in the name
5Click Save
6Repeat at folder/organization level if the role was inherited

Check Code

from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.services.cloudresourcemanager.cloudresourcemanager_client import (
    cloudresourcemanager_client,
)
from prowler.providers.gcp.services.iam.iam_client import iam_client


class iam_sa_no_administrative_privileges(Check):
    def execute(self) -> Check_Report_GCP:
        findings = []
        for account in iam_client.service_accounts:
            report = Check_Report_GCP(
                metadata=self.metadata(),
                resource=account,
                resource_id=account.email,
                location=iam_client.region,
            )
            report.status = "PASS"
            report.status_extended = (
                f"Account {account.email} has no administrative privileges."
            )
            for binding in cloudresourcemanager_client.bindings:
                if f"serviceAccount:{account.email}" in binding.members and (
                    "admin" in binding.role.lower()
                    or binding.role.lower() in ["roles/editor", "roles/owner"]
                ):
                    report.status = "FAIL"
                    report.status_extended = f"Account {account.email} has administrative privileges with {binding.role}."
            findings.append(report)

        return findings