gcp-dataproc-cluster-update-attach-identity
clusters.update + actAs on the new SA attaches (swaps) the cluster's runtime SA - all future jobs run as the new SA.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanModifyConfiguration {'cluster': None}
{'principal': None} CanPassIdentity {'newsa': None}
where
node_type(?cluster) ==
AnalyticsService # Dataproc Cluster
node_type(?newsa) == ServiceAccount
emit
| source type | Identity |
|---|---|
| target type | AnalyticsService |
| source | ?principal |
| target | ?cluster |
| permissions | dataproc.clusters.update iam.serviceAccounts.actAs |
| conditions | iam_permission role_compatibility |
| state logic | ACTIVE when both CanModifyConfiguration and CanPassIdentity on ?newsa are confirmed. POTENTIAL(iam_permission) if actAs on the new SA is unconfirmed. BLOCKED if IAM deny prevents clusters.update or actAs. The swap takes effect on the running cluster; new jobs submitted after the swap run as ?newsa. |
Narrative
{principal.name} can swap {cluster.name}'s service account to {newsa.name} (dataproc.clusters.update + iam.serviceAccounts.actAs); all future jobs on the cluster execute as {newsa.name}.
Raw rule rules/derived/gcp/dataproc.yaml
id: gcp-dataproc-cluster-update-attach-identity
emits: CanAttachIdentity
description: "clusters.update + actAs on the new SA attaches (swaps) the cluster's runtime SA \u2014 all\
\ future jobs run as the new SA."
match:
- - principal: null
- CanModifyConfiguration
- cluster: null
- - principal: null
- CanPassIdentity
- newsa: null
where:
- 'node_type(?cluster) == AnalyticsService # Dataproc Cluster'
- node_type(?newsa) == ServiceAccount
emit:
source_type: Identity
target_type: AnalyticsService
source: ?principal
target: ?cluster
permissions:
- dataproc.clusters.update
- iam.serviceAccounts.actAs
conditions:
- iam_permission
- role_compatibility
state_logic: ACTIVE when both CanModifyConfiguration and CanPassIdentity on ?newsa are confirmed. POTENTIAL(iam_permission)
if actAs on the new SA is unconfirmed. BLOCKED if IAM deny prevents clusters.update or actAs. The
swap takes effect on the running cluster; new jobs submitted after the swap run as ?newsa.
derived_from:
- ?principal CanModifyConfiguration ?cluster
- ?principal CanPassIdentity ?newsa
false_positive_note: "The cluster SA swap applies to FUTURE jobs, not currently running ones. On a STOPPED\
\ cluster, the swap still applies to jobs submitted after the cluster restarts. CITE can-execute-as\
\ execute-as-via-config-identity-swap for the CanExecuteAs derivation \u2014 this rule only emits\
\ the fact; the linchpin collapses it."
narrative: '{principal.name} can swap {cluster.name}''s service account to {newsa.name} (dataproc.clusters.update
+ iam.serviceAccounts.actAs); all future jobs on the cluster execute as {newsa.name}.'