- Newest
- Most votes
- Most comments
The configuration you describe provides the service role that CloudFormation uses to execute the change set or deploy the stack. You still have to have permissions to pass the role to CloudFormation (iam:PassRole) on a per stack basis and create the stack itself. See here. You can only pass the role from an IAM role in the same account. So, if I'm trying to create a stack and specify a role in a different account, the stack creation will fail because I can't pass that role to CFN. If you look at the instructions here and here, you'll see that the cross account access relies on a role in Account A where the pipeline lives assuming a role in Account B. Then it uses the role in Account B to create the stack and to pass a third role to CFN, also in Account B. This prevents any type of cross account access with the role that trusts the CloudFormation service principal (cloudformation.amazonaws.com).
Hi! Good question. I'm reviewing the 2 answers above, and don't think they solve what you're trying to do.
In this case, you would want to limit access via the role you have in Account B - and to do so, you would have to do so on the IAM Role's trust relationship to scope that down so AWS is not using CloudFormation as a confused deputy.
Check out the IAM Condition Key aws:SourceAccount: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount. I'm not sure if this works with CodePipeline, but that condition would do what you are looking to do: "This key is included in the request context only if accessing a resource triggers an AWS service to call another service on behalf of the resource owner. The calling service must pass the resource account ID of the source to the called service. This account ID includes the source account ID."
aws:PrincipalOrgID would not be applicable to the trust policy you have posted above, since the trusted principal is the AWS Service, cloudformation.amazonaws.com.
Yes, I think aws:SourceAccount is what I'm looking for. Where can I find whether or not CodePipeline and/or CloudFormation include this in the cross-account request?
If you're using AWS Organizations you can use IAM Condition Keys, such as aws:PrincipalOrgID, to help craft a more specific scoped policy on who (or what) can assume a role. In the case of wanting to ensure only principals from within your organization are able to assume a role. You can also build the IAM role/policy with a condition (or specific ARN depending on how prescriptive you want to be) which only allows assuming a role from a single known account or even a single role in a single account.
Relevant content
- asked 2 years ago
- asked 6 years ago
- asked 5 months ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated a year ago
- AWS OFFICIALUpdated 12 days ago
- AWS OFFICIALUpdated 2 years ago
The role I described is deployed in account B. Account A assumes this role during a CodePipeline deployment via a CloudFormation deployment. The pipeline does have the ability to sts:AssumeRole the role in account B. This already works, and is not my question. My question is that the role in Account B does not know anything about account A. How do I tell account B to only allow the role to be assumed by CloudFormation when it's called from a CodePipeine executing in account A?
Per @mike's description, you will have 2 roles in Account B - 1/ cross-account role that CodePipeline will assume 2/ service role that will be passed to CloudFormation and deploy the resources. Cross-account role is the one that has permissions to pass the service role to CloudFormation for Account B. This is also the only role that can trigger the deployment in Account B. In order to prevent from another account to use the cross-account role, you can specify Account A as the only approved principal in role's trust policy.
You said "you can specify Account A as the only approved principal in role's trust policy", which is exactly what I'm trying to do. What's the magic incantation to make that happen?