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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_class(?env) in [
AnalyticsService] # Composer Environment
emit
| source type | AnalyticsService |
|---|---|
| target type | Identity |
| source | <Composer Environment node> |
| target | <environment service account> |
| state logic | ACTIVE: 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.