gcp-appengine-versions-create

derived gcp emits CanModifyCode

match (effective permission)

{ "action": "appengine.versions.create", "resource_type": "google.appengine.Application" }

emit

source typeIdentity
source<principal>
target<App Engine application>
permissionsappengine.versions.create
conditionsiam_permission
state logicACTIVE if source deploy also has Cloud Build + GCS staging perms OR the deploy is a prebuilt container/image (no build needed); else CONDITIONAL(iam_permission) pending build/storage perms.

Narrative

{principal.name} can deploy a new App Engine version (appengine.versions.create), injecting code that runs as the runtime service account.

Raw rule rules/derived/gcp/appengine.yaml

id: gcp-appengine-versions-create
emits: CanModifyCode
match_effective_permission:
  action: appengine.versions.create
  resource_type: google.appengine.Application
optional_permission:
- cloudbuild.builds.create
- storage.objects.create
modeling_note: 'Node-type convention for App Engine: the deploy target (application/version) is modeled
  as ApplicationPlatform and treated as Compute-like for CanModifyCode purposes; schema/edges.yaml CanModifyCode.target
  does not yet list ApplicationPlatform. ExecutesAs is anchored on the Instance (Compute) node. This is
  the single consistent convention applied across ExecutesAs, CanModifyCode, CanModifyConfiguration, and
  ExposedToInternet in this file (ExposedToInternet uses the PublicEndpoint node, which IS schema-valid).

  '
emit:
  source_type: Identity
  source: <principal>
  target: <App Engine application>
  permissions:
  - appengine.versions.create
  conditions:
  - iam_permission
  state_logic: 'ACTIVE if source deploy also has Cloud Build + GCS staging perms OR the deploy is a prebuilt
    container/image (no build needed); else CONDITIONAL(iam_permission) pending build/storage perms.

    '
  escalation: Deploy a version containing attacker code (reverse shell / token exfil) that runs as the
    runtime SA.
  false_positive_note: 'Full ''gcloud app deploy'' of source needs roles/cloudbuild.builds.editor + roles/storage.objectAdmin
    to build and stage. Without them a source deploy may fail -> emit CONDITIONAL. Container/traffic-split
    paths avoid this.

    '
  narrative: '{principal.name} can deploy a new App Engine version (appengine.versions.create), injecting
    code that runs as the runtime service account.'
move · open · esc close