I have two AWS accounts: an account that holds my secrets, an account for deployment of my cloudformation stack. I am using cloudformation to deploy my infrastructure as code and have a pretty simple CD pipeline:
EC2 instances created as part of my stack rely on the secrets during start up. I would like to add the secret ARNs to my EC2 userdata script then use the AWS command line to retrieve the secret value when the userdata script is executed.
The IAM service roles used by my EC2 instances are also created as part of my cloudformation script. As such, the IAM role ARNs are not known prior to the launch of the stack. I find myself in a bit of a catch-22: I cannot launch my stack until access is granted to my secrets, but I cannot grant access to my secrets because the Principal in the resource policy does not accept wildcards.
Does anybody know how I might be able to create a secretsmanager resource policy for my secrets which does not require the IAM role ARN to be known beforehand? Or perhaps any other ideas?
What may be a better alternative to specifying the principals in the resource policy is to use Attribute Based Access Control (ABAC, a.k.a tagging). There is a fairly detailed tutorial on setting this up for IAM policies which can be modified for resource policies.
In this approach, you would create your resource policy granting access to the other account, but only for principals with a given tag. Then when you create the roles in the other account you add tags to them for the secrets they need to access. For example, the resource policy below grants GetSecretValue to account 123456789012 only when the tag "access-project" has the same value for both the secret and the accessing role:
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal": {"AWS": "123456789012" },
"Condition": {
"StringEquals": {
"aws:ResourceTag/access-project": "${aws:PrincipalTag/access-project}"
}
},
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "*"
} ]
}
After adding this resource policy to the secret, you would also add the tag "access-project" to both the secret and the user/role. Note that this only grants GetSecretValue. It is probably a bad idea to let the user modify the the secret or the tags on the secret, but if you need to do so you would also include the other conditions from the referenced tutorial. Of course, you could also hard code the tags in the resource policy if you do not want to add tags to the secrets.
In general, this approach is a lot easier to manage since you do not need to keep updating the resource policy every time you add or remove a user/role. You would just add or remove the tags from the users and or secrets.
The alternate way to do this is to just open up the secret to the entire account, and then within that account limit who can access the secret via IAM policies (possibly still using tags as in the tutorial). Cross account access requires both the resource policy granting access and the IAM user/role policy granting access.