In early 2025, security researchers uncovered a serious privilege-escalation vulnerability in the Google Cloud Platform (GCP) that they dubbed “ConfusedComposer.” This flaw resided in Cloud Composer, Google’s managed workflow orchestration service powered by Apache Airflow. It would have allowed an attacker with only minimal permissions to seize control of a highly privileged service account. With that foothold, they could have mounted project-wide attacks, accessed sensitive data, and disrupted mission-critical pipelines.
Over the past decade, enterprises have flocked to managed cloud services to streamline operations, automate DevOps, and scale data processing. However, as organizations stitch together dozens of services, each with its service account and permission model, the risk of misconfiguration and unexpected interactions grows. ConfusedComposer is a textbook example: a seemingly innocuous feature (installing a custom Python package) inadvertently granted attackers a path to total compromise. In this post, we’ll trace the root cause of the vulnerability, explore the technical exploitation steps, detail Google’s remediation, and consider broader lessons for cloud security teams.
How Cloud Composer Orchestrates Workflows and Introduces Risk
What Is Cloud Composer?
Cloud Composer is Google’s fully managed implementation of Apache Airflow, a popular open-source platform for authoring, scheduling, and monitoring complex data pipelines. Data engineers define directed acyclic graphs (DAGs) of tasks—extracting data from sources, transforming it, and loading results into data warehouses. Composer manages the underlying Kubernetes cluster, Airflow servers, and integrations with services such as Cloud Storage, BigQuery, and Pub/Sub, freeing teams from operational overhead.
The Custom PyPI-Package Feature
To support specialized data transformations, Composer allows users to specify custom Python packages (hosted on PyPI or private repositories). When you update an environment to include new dependencies, Composer automatically spins up a Cloud Build job behind the scenes. That job packages and installs the requested modules into the environment’s worker images. From a developer’s perspective, it’s a seamless way to extend Airflow with third-party or in-house libraries.
The Root Cause: A Confused Trust Boundary
Service Accounts and Trust
In GCP, every managed service runs under one or more service account identities with associated IAM roles. Cloud Composer uses two key accounts:
- Composer Environment Service Account: owns the Airflow environment and typically holds least-privilege roles scoped to that environment.
- Cloud Build Service Account: a broad-privileged account that Cloud Build uses to read/write artifacts, push container images, and access storage.
The security gap emerged because Composer delegated the custom-package installation step to Cloud Build, crucially doing so under the Cloud Build service account rather than the more restricted environment account. As a result, any code that ran in that build inherited powerful permissions.
“Jenga” Attack Class
Tenable researchers categorize ConfusedComposer as a “Jenga” attack: adversaries exploit the stacking of services and permissions that cloud providers assemble automatically. Last year’s “ConfusedFunction” vulnerability similarly abused interactions between Cloud Functions and Cloud Build. In both cases, attackers topple the misconfigured stack, gaining leverage far beyond their initial privileges.
Step-by-Step: How an Attacker Could Exploit ConfusedComposer
Gaining the Initial Foothold
To exploit ConfusedComposer, an attacker only needs to possess the Composer’s environment and update permission in a target project. That permission is often granted to DevOps or data-engineering roles responsible for updating DAG definitions and dependencies. In many organizations, those roles are widespread, significantly lowering the bar for exploitation.
Injecting a Malicious PyPI Package
The adversary publishes a trojanized Python package, called evil-pkg, to a public (or private) PyPI repository. This package includes a setup.py script that runs arbitrary code during installation (leveraging Python’s “pre-install” and “post-install” hooks). The attacker then issues a standard Composer environment update, adding evil-pkg to the list of custom dependencies.
Code Execution within Cloud Build
When Composer processes the update, it triggers a Cloud Build job in the victim’s project. That build fetches evil-pkg and, in the course of installing it, executes the malicious setup script. Inside the build container, that script runs with the Cloud Build service account’s credentials.
The script contacts the Cloud Build metadata server, retrieves the service account token, and exfiltrates it to an attacker-controlled endpoint. With that token in hand, the attacker can call any GCP API that the Cloud Build account is authorized to use.
Elevating to Project-Wide Control
By default, the Cloud Build service account holds roles such as:
- roles/storage.admin on Cloud Storage buckets
- roles/artifact registry. Writer on Artifact Registry
- roles/container registry.ServiceAgent for pushing images
- And often more, depending on organizational policies
Armed with those roles, the attacker can read or overwrite data in storage buckets, deploy new container images, spin up VMs, or even grant themselves further IAM privileges. What began as a minor environment update morphs into a complete project compromise.
Google’s Fix and Mitigation Guidance
The Patch: Shifting to the Environment Service Account
In April 2025, Google rolled out a patch that changes which identity performs PyPI installations. Rather than invoking Cloud Build under its powerful service account, Composer now configures the build to run as the much more restricted Composer environment service account. That account only has permissions explicitly granted to the user’s environment, effectively removing the attacker’s path to high-impact roles.
Google has already applied this fix to all new Composer environments. Existing environments will receive the update automatically by the end of April 2025. No customer action is required to use the patch, though organizations should verify their environment version to confirm the change has taken effect.
Updated Documentation and Best Practices
Alongside the technical fix, Google revised Composer’s documentation in three key areas:
- Access Control: Clarifying which IAM roles govern environment updates, DAG deployments, and package installations.
- Installing Python Dependencies: Highlighting the trust boundary and advising users to minimize permissions on service accounts.
- Airflow CLI Access: Emphasizing least-privilege configuration when granting users or CI systems rights to run CLI commands.
Cloud security teams should revisit their IAM policies to ensure the update of Composer environments. It is tightly scoped, ideally for a small set of trusted operators. Wherever possible, custom-package installation should be limited or subjected to code-review gates in CI/CD pipelines.
Broader Lessons for Cloud Security
Beware Hidden Service Interactions
Managed cloud services often orchestrate multiple back-end components without overtly exposing them. In this case, Composer’s UI never mentions Cloud Build; users click “Install packages” and expect dependencies to appear. But under the hood, Composer delegates to Cloud Build, and that hidden linkage almost led to a catastrophic privilege jump.
Cloud architects must map not only the services they directly consume but also the ancillary services those platforms invoke on their behalf. Drawing a complete service dependency graph can reveal surprising “trust chains” that warrant tighter controls or monitoring.
Enforce Least Privilege End-to-End
Least privilege is more than assigning narrow IAM roles to human users; it requires ensuring that every automated component, from build services to managed pipelines, carries no more permissions than is strictly necessary. In practice, this means:
- Regularly auditing service-account roles
- Using IAM Conditions to limit where and when accounts can act
- Employing VPC Service Controls or organizational policies to fence sensitive data
For environments running dynamic code, such as custom Python packages, consider introducing an approval workflow or sandbox testing phase before dependencies reach production.
Embrace “Jenga” Style Threat Modeling
The Jenga metaphor aptly captures the risk: every new service or permission is another block in the tower. A tower that looks stable at a glance can wobble if one misplaced block undermines the entire structure. Security teams should simulate scenarios where low-privileged actions trigger high-privileged processes, identifying and shoring up weak points before attackers do.
Conclusion: Strengthening Trust in Managed Services
The ConfusedComposer vulnerability underscores a paradox of managed cloud offerings. They abstract away complexity and reduce operational burden, but that very abstraction can mask dangerous interactions. As cloud adoption accelerates, organizations must pair the convenience of managed services with rigorous service-account hygiene, threat modeling, and documentation review.
Google’s swift patch and documentation updates have closed the immediate gap in Cloud Composer. Yet the broader challenge remains: ensuring that every invisible handoff between services respects the principle of least privilege. By treating managed-service orchestration as part of their attack surface, cloud security teams can build more resilient architectures—ones, where a simple package install no longer, holds the keys to the castle.