gcp-appengine-execute-as-actas

Deploy a version with a custom, more-privileged runtime SA via actAs.

derived gcp emits CanExecuteAs

match

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

{'principal': None} CanPassIdentity {'sa': None} {'principal': None} CanModifyCode {'app': None}

where

?sa is role-compatible as an App Engine runtime SA (same project) ?sa.privilege_level >= ?principal.privilege_level the ?sa bound by CanPassIdentity is the SAME ?sa attached to the deployed version; the deploy path can set version.serviceAccount = ?sa ?principal's iam.serviceAccounts.actAs grant is scoped to THIS ?sa (per-SA actAs), not merely to the appspot SA

emit

source typeIdentity
target typeIdentity
source<principal>
target<chosen service account>
permissionsiam.serviceAccounts.actAs appengine.versions.create
conditionsrole_compatibility iam_permission
state logicCONDITIONAL(iam_permission) until per-SA actAs on ?sa is confirmed AND the deploy path can set version.serviceAccount=?sa; ACTIVE only once both hold.

Narrative

{principal.name} can deploy an App Engine version bound to {sa.name} (per-SA actAs + appengine.versions.create) and execute code as that SA, provided actAs is scoped to {sa.name}.

Raw rule rules/derived/gcp/appengine.yaml

id: gcp-appengine-execute-as-actas
emits: CanExecuteAs
description: Deploy a version with a custom, more-privileged runtime SA via actAs.
match:
- - principal: null
  - CanPassIdentity
  - sa: null
- - principal: null
  - CanModifyCode
  - app: null
where:
- ?sa is role-compatible as an App Engine runtime SA (same project)
- ?sa.privilege_level >= ?principal.privilege_level
- the ?sa bound by CanPassIdentity is the SAME ?sa attached to the deployed version; the deploy path can
  set version.serviceAccount = ?sa
- ?principal's iam.serviceAccounts.actAs grant is scoped to THIS ?sa (per-SA actAs), not merely to the
  appspot SA
emit:
  source_type: Identity
  target_type: Identity
  source: <principal>
  target: <chosen service account>
  permissions:
  - iam.serviceAccounts.actAs
  - appengine.versions.create
  conditions:
  - role_compatibility
  - iam_permission
  state_logic: 'CONDITIONAL(iam_permission) until per-SA actAs on ?sa is confirmed AND the deploy path
    can set version.serviceAccount=?sa; ACTIVE only once both hold.

    '
  derived_from:
  - <CanPassIdentity edge_id>
  - <CanModifyCode edge_id>
  false_positive_note: 'iam.serviceAccounts.actAs is per-SA. A principal able to actAs only the appspot
    SA cannot attach an arbitrary stronger ?sa to a version. Confirm the actAs grant covers exactly the
    ?sa bound by CanPassIdentity and that the deploy actually sets version.serviceAccount=?sa before asserting
    CanExecuteAs.

    '
  narrative: '{principal.name} can deploy an App Engine version bound to {sa.name} (per-SA actAs + appengine.versions.create)
    and execute code as that SA, provided actAs is scoped to {sa.name}.'
move · open · esc close