aws-sc-create-constraint-attaches-identity

servicecatalog:CreateConstraint + iam:PassRole(servicecatalog.amazonaws.com): add a LaunchRole constraint to a product in a portfolio, binding a chosen privileged role. All subsequent ProvisionProduct calls then execute as that 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} {'principal': None} HasPermission {'portfolio': None} {'product': None} MemberOf {'portfolio': None}

where

node_type(?portfolio) == GenericManagement # AWS::ServiceCatalog::Portfolio node_type(?product) == BuildWorker # AWS::ServiceCatalog::CloudFormationProduct ?principal has EFFECTIVE servicecatalog:CreateConstraint on ?portfolio (scoped to portfolio ARN) ?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:CreateConstraint iam:PassRole
conditionsrole_compatibility iam_permission
state logicACTIVE when (a) servicecatalog:CreateConstraint is in EFFECTIVE policy for ?portfolio and its products, (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 is ambiguous. BLOCKED when SCP or permission boundary denies servicecatalog:CreateConstraint or iam:PassRole at the effective scope.

Narrative

{principal.name} can create a Launch Role Constraint (servicecatalog:CreateConstraint + iam:PassRole for {new_role.name} to servicecatalog.amazonaws.com) on product {product.name} in portfolio {portfolio.name}, modifying the product's execution binding to {new_role.name}. All subsequent ProvisionProduct calls for {product.name} then execute 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-create-constraint-attaches-identity
emits: CanModifyConfiguration
description: 'servicecatalog:CreateConstraint + iam:PassRole(servicecatalog.amazonaws.com): add a LaunchRole
  constraint to a product in a portfolio, binding a chosen privileged role. All subsequent ProvisionProduct
  calls then execute as that launch role. can-execute-as execute-as-via-config-identity-swap propagates
  with CanPassIdentity to derive CanExecuteAs.'
match:
- - principal: null
  - CanPassIdentity
  - new_role: null
- - principal: null
  - HasPermission
  - portfolio: null
- - product: null
  - MemberOf
  - portfolio: null
where:
- 'node_type(?portfolio) == GenericManagement  # AWS::ServiceCatalog::Portfolio'
- 'node_type(?product) == BuildWorker  # AWS::ServiceCatalog::CloudFormationProduct'
- ?principal has EFFECTIVE servicecatalog:CreateConstraint on ?portfolio (scoped to portfolio ARN)
- ?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:CreateConstraint
  - iam:PassRole
  conditions:
  - role_compatibility
  - iam_permission
  state_logic: ACTIVE when (a) servicecatalog:CreateConstraint is in EFFECTIVE policy for ?portfolio and
    its products, (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 is ambiguous. BLOCKED when SCP or permission boundary denies servicecatalog:CreateConstraint
    or iam:PassRole at the effective scope.
  confidence: 0.88
  derived_from:
  - ?principal CanPassIdentity ?new_role
  - servicecatalog:CreateConstraint EFFECTIVE on ?portfolio
  - can-execute-as.yaml execute-as-via-config-identity-swap (CanModifyConfiguration + CanPassIdentity
    => CanExecuteAs)
  false_positive_note: "Honor iam:PassedToService: same discipline as aws-sc-update-constraint-attaches-identity\
    \ above. Only emit when the product is (or can be placed) in a portfolio the attacker can create constraints\
    \ on. A product with an EXISTING LaunchRole constraint may reject a second constraint of the same\
    \ type (a portfolio can hold one launch constraint per product \u2014 adding a second may require\
    \ removing the first, which needs servicecatalog:DeleteConstraint). When a prior constraint exists,\
    \ prefer aws-sc-update-constraint-attaches-identity. can-execute-as handles the roll-up to CanExecuteAs\
    \ via execute-as-via-config-identity-swap; do not re-derive here."
  narrative: '{principal.name} can create a Launch Role Constraint (servicecatalog:CreateConstraint +
    iam:PassRole for {new_role.name} to servicecatalog.amazonaws.com) on product {product.name} in portfolio
    {portfolio.name}, modifying the product''s execution binding to {new_role.name}. All subsequent ProvisionProduct
    calls for {product.name} then execute as {new_role.name}. This CanModifyConfiguration + CanPassIdentity
    chain derives CanExecuteAs via can-execute-as execute-as-via-config-identity-swap.'
move · open · esc close