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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
CanPassIdentity {'new_role': None}
{'principal': None} HasPermission {'portfolio': None}
{'product': None} MemberOf {'portfolio': None}
where
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. |
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.'