gcp-composer-exposes-env-sa-cred

All Composer DAG task executions can mint OAuth tokens for the environment SA from the GKE metadata server; code execution in any DAG task yields the environment SA's credentials.

derived gcp emits ExposesCredential

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

?env ExecutesAs ?sa

where

node_class(?env) in [AnalyticsService] # Composer Environment

emit

source typeAnalyticsService
target typeIdentity
source<Composer Environment node>
target<environment service account>
state logicACTIVE: structural fact — the GKE metadata server is always reachable from Airflow worker pods. This edge only becomes an attack step when combined with a CanModifyCode, CanTrigger, or CanExecuteAs edge on the environment. Cite credential-chains.yaml for the ExposesCredential → CredentialsFor → CanImpersonate collapse when relevant.

Narrative

Code running in {env.name}'s DAG tasks can retrieve OAuth 2.0 access tokens for environment service account {sa.name} from the GKE metadata server (http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token), granting all of {sa.name}'s IAM roles to any code in the environment.

Raw rule rules/derived/gcp/composer.yaml

id: gcp-composer-exposes-env-sa-cred
emits: ExposesCredential
description: All Composer DAG task executions can mint OAuth tokens for the environment SA from the GKE
  metadata server; code execution in any DAG task yields the environment SA's credentials.
match:
- - ?env
  - ExecutesAs
  - ?sa
where:
- 'node_class(?env) in [AnalyticsService]  # Composer Environment'
emit:
  source_type: AnalyticsService
  target_type: Identity
  source: <Composer Environment node>
  target: <environment service account>
  permissions: []
  conditions: []
  state_logic: "ACTIVE: structural fact \u2014 the GKE metadata server is always reachable from Airflow\
    \ worker pods. This edge only becomes an attack step when combined with a CanModifyCode, CanTrigger,\
    \ or CanExecuteAs edge on the environment. Cite credential-chains.yaml for the ExposesCredential \u2192\
    \ CredentialsFor \u2192 CanImpersonate collapse when relevant."
  confidence: 1.0
  derived_from:
  - <ExecutesAs edge_id for ?env -> ?sa>
  false_positive_note: "Not an escalation by itself \u2014 expresses the fact that code execution in any\
    \ DAG task equals credential access for the environment SA. Attack value is gated by an upstream code-injection\
    \ capability (CanModifyCode via dags/ write, or a CanTrigger over an already-attacker-influenced DAG).\
    \ Do not treat as a standalone high-value finding."
  narrative: Code running in {env.name}'s DAG tasks can retrieve OAuth 2.0 access tokens for environment
    service account {sa.name} from the GKE metadata server (http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token),
    granting all of {sa.name}'s IAM roles to any code in the environment.
move · open · esc close