aws-sc-update-constraint-attaches-identity

servicecatalog:UpdateConstraint + iam:PassRole(servicecatalog.amazonaws.com) on a LaunchRole constraint: replace the launch role bound to a product with a more privileged role. The next ProvisionProduct executes as the new launch role. can-execute-as execute-as-via-config-identity-swap propagates with CanPassIdentity to derive CanExecuteAs.

derived aws emits CanModifyConfiguration

match

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

{'principal': None} CanPassIdentity {'new_role': None} {'product': None} ExecutesAs {'old_role': None} {'principal': None} HasPermission {'product': None}

where

node_type(?product) == BuildWorker # AWS::ServiceCatalog::CloudFormationProduct ?product has a LaunchRole constraint with RoleArn = ?old_role ?principal has EFFECTIVE servicecatalog:UpdateConstraint on the constraint associated with ?product ?new_role trust policy allows servicecatalog.amazonaws.com as a trusted service iam:PassRole for ?new_role permits iam:PassedToService == servicecatalog.amazonaws.com (or unconditioned)

emit

source typeIdentity
target typeCompute
source?principal
target?product
permissionsservicecatalog:UpdateConstraint iam:PassRole
conditionsrole_compatibility iam_permission
state logicACTIVE when (a) servicecatalog:UpdateConstraint is in EFFECTIVE policy for the constraint, (b) iam:PassRole for ?new_role is granted with iam:PassedToService including servicecatalog.amazonaws.com or unconditioned, AND (c) ?new_role trust policy allows servicecatalog.amazonaws.com. POTENTIAL(role_compatibility) when ?new_role trust policy does not yet include servicecatalog.amazonaws.com — the constraint update will succeed in changing the RoleArn but Service Catalog will fail to assume the role at provision time. BLOCKED when SCP or permission boundary denies servicecatalog:UpdateConstraint or iam:PassRole at the effective scope.

Narrative

{principal.name} can update the Launch Role Constraint on product {product.name} (servicecatalog:UpdateConstraint + iam:PassRole for {new_role.name} to servicecatalog.amazonaws.com), modifying the product's execution binding from {old_role.name} to {new_role.name}. The next ProvisionProduct call executes as {new_role.name}. This CanModifyConfiguration + CanPassIdentity chain derives CanExecuteAs via can-execute-as execute-as-via-config-identity-swap.

Raw rule rules/derived/aws/servicecatalog.yaml

id: aws-sc-update-constraint-attaches-identity
emits: CanModifyConfiguration
description: 'servicecatalog:UpdateConstraint + iam:PassRole(servicecatalog.amazonaws.com) on a LaunchRole
  constraint: replace the launch role bound to a product with a more privileged role. The next ProvisionProduct
  executes as the new launch role. can-execute-as execute-as-via-config-identity-swap propagates with
  CanPassIdentity to derive CanExecuteAs.'
match:
- - principal: null
  - CanPassIdentity
  - new_role: null
- - product: null
  - ExecutesAs
  - old_role: null
- - principal: null
  - HasPermission
  - product: null
where:
- 'node_type(?product) == BuildWorker  # AWS::ServiceCatalog::CloudFormationProduct'
- ?product has a LaunchRole constraint with RoleArn = ?old_role
- ?principal has EFFECTIVE servicecatalog:UpdateConstraint on the constraint associated with ?product
- ?new_role trust policy allows servicecatalog.amazonaws.com as a trusted service
- iam:PassRole for ?new_role permits iam:PassedToService == servicecatalog.amazonaws.com (or unconditioned)
emit:
  source_type: Identity
  target_type: Compute
  source: ?principal
  target: ?product
  permissions:
  - servicecatalog:UpdateConstraint
  - iam:PassRole
  conditions:
  - role_compatibility
  - iam_permission
  state_logic: "ACTIVE when (a) servicecatalog:UpdateConstraint is in EFFECTIVE policy for the constraint,\
    \ (b) iam:PassRole for ?new_role is granted with iam:PassedToService including servicecatalog.amazonaws.com\
    \ or unconditioned, AND (c) ?new_role trust policy allows servicecatalog.amazonaws.com. POTENTIAL(role_compatibility)\
    \ when ?new_role trust policy does not yet include servicecatalog.amazonaws.com \u2014 the constraint\
    \ update will succeed in changing the RoleArn but Service Catalog will fail to assume the role at\
    \ provision time. BLOCKED when SCP or permission boundary denies servicecatalog:UpdateConstraint or\
    \ iam:PassRole at the effective scope."
  confidence: 0.9
  derived_from:
  - ?principal CanPassIdentity ?new_role
  - ?product ExecutesAs ?old_role
  - servicecatalog:UpdateConstraint EFFECTIVE on the constraint
  - can-execute-as.yaml execute-as-via-config-identity-swap (CanModifyConfiguration + CanPassIdentity
    => CanExecuteAs)
  false_positive_note: 'Honor iam:PassedToService: a role passable only to cloudformation.amazonaws.com,
    lambda.amazonaws.com, or ec2.amazonaws.com does NOT satisfy the servicecatalog.amazonaws.com requirement.
    Verify the PassedToService condition is either absent (unconditioned) or explicitly includes servicecatalog.amazonaws.com.
    Downgrade to POTENTIAL(role_compatibility) when the trust policy or PassedToService condition is ambiguous
    or unresolved. can-execute-as execute-as-via-config-identity-swap handles the roll-up with CanPassIdentity;
    do not re-derive CanExecuteAs here.'
  narrative: '{principal.name} can update the Launch Role Constraint on product {product.name} (servicecatalog:UpdateConstraint
    + iam:PassRole for {new_role.name} to servicecatalog.amazonaws.com), modifying the product''s execution
    binding from {old_role.name} to {new_role.name}. The next ProvisionProduct call executes as {new_role.name}.
    This CanModifyConfiguration + CanPassIdentity chain derives CanExecuteAs via can-execute-as execute-as-via-config-identity-swap.'
move · open · esc close