AWS IAM: wildcards in conditions for aws:principalArn - amazon-web-services

I want to make my IAM policy conditional, to allow it to work with an EC2 instance that has definite assumed role. The following syntax works great if I know the id of that instance, sasying it's i-1111111111111111:
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal" : {
"AWS": "arn:aws:sts::111122223333:assumed-role/MyRole/i-1111111111111111"
},
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "*"
} ]
}
However I want to allow this access for any future EC2 instance with the same role. As wildcards do not work in Principal field, I try to specify a wildcarded condition:
"Principal" : "*",
"Condition": {
"StringLike": {
"aws:PrincipalArn": "arn:aws:sts::111122223333:assumed-role/MyRole/*"
}
},
but this does not grant access.
What the correct syntax should be for wildcarded principal?

Related

Restricting access to an AWS resource using a specific pattern of AWS roles

I want all roles of my AWS account having a specific pattern to be able to access a Secrets Manager secret. I know I can use Condition block and wildcard matching for that.
However, the Principal field is required in a resource policy.
Will the following policy restrict access to just the roles matching the pattern?
{
"Statement": [
{
"Action": [
"secretsmanager:UpdateSecret",
"secretsmanager:GetSecretValue"
],
"Condition": {
"StringLike": {
"aws:PrincipalArn": "arn:aws:iam::12345678910:role/my_role_*"
}
},
"Principal": { "AWS": "arn:aws:iam::12345678910:root" },
"Effect": "Allow",
"Resource": "arn:aws:secretsmanager:us-east-1:12345678910:secret:some-secret-1234",
"Sid": "rp1"
}
],
"Version": "2012-10-17"
}
Use the wildcard "All Principal": {"AWS": "*"}. The combination of a same-account Account Principal + wildcard condition works in role *trust* policies1 but apparently not in *resource* policies2.
The IAM docs say:
You can specify the role principal as the principal in a resource-based policy or create a broad-permission policy [with a wildcard Principal] that uses the aws:PrincipalArn condition key.
Because the condition contains the account number, the All Principal is no more permissive than the Account Principal would be. Also, because the policy is always tied to a specific secret resource, the wildcard "*" Resoure is no more permissive than the secret name. Finally, while an ArnLike condition is not always equivalent to StringLike, it is identical in this case.
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal" : { "AWS" : "*" },
"Action" : [ "secretsmanager:DescribeSecret", "secretsmanager:GetSecretValue" ],
"Resource" : "arn:aws:secretsmanager:us-east-1:12345678910:secret:some-secret-1234",
"Condition" : {
"ArnLike" : {
"aws:PrincipalArn" : "arn:aws:iam::12345678910:role/my_role_*"
}
}
} ]
}
See the wildcard permissions section of the AWS blog post How to use trust policies with IAM roles for a trust policy example.
Error using a Lambda role + secrets manager resource policy with a same-account Account Principal: ...no identity-based policy allows the secretsmanager:GetSecretValue action.

Cannot detach AWS-managed service control policy - access denied

I have the following statement in my IAM policy:
{
"Sid" : "AllowDetachingAWSManagedPolicies",
"Effect" : "Allow",
"Action" : [
"organizations:DetachPolicy"
],
"Resource" : "*",
"Condition" : {
"StringEquals" : {
"organizations:PolicyType" : "SERVICE_CONTROL_POLICY"
}
}
}
However, when I try to detach the FullAWSAccess policy from an AWS Organizations account, I get AccessDenied, as if my IAM policy wasn't sufficient. I have made sure that there is another SCP in addition to FullAWSAccess, so the issue is not that there would remain no SCPs attached to the account.
What is going wrong?
Strangely enough, the AWS-managed FullAWSAccess policy does not count as a SERVICE_CONTROL_POLICY even though it is listed as such on the AWS Organizations Policies page.
When I removed the condition, I no longer got AccessDenied errors:
{
"Sid" : "AllowDetachingAWSManagedPolicies",
"Effect" : "Allow",
"Action" : [
"organizations:DetachPolicy"
],
"Resource" : "*"
}
Another thing I tried to do was to specify a resource that matched FullAWSAccess:
"Resource": "arn:aws:organizations::aws:policy/service_control_policy/p-*"
But that similarly resulted in an AccessDenied error. So I left it as:
"Resource": "*"

Sharing AWS Secrets Manager with another account is not working

I need to share an AWS Secrets Manager secret with multiple accounts.
For this public post, I've scrubbed the account numbers and replaced them with dummy values.
For this example, the account holding the secret is 987654 and it needs to be accessed by account 123456
The account that will "read" the secret (123456) should be able to read from "ANY ROLE" within the account.
Note: I tried using a wildcard in the principal (ex: "arn:aws:iam::123456:role/*") but I got a malformed policy error. So I'm using conditionals.
The secret is using a KMS key with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::987654:role/Admin1",
"arn:aws:iam::987654:role/Terraform"
]
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:CallerAccount": [
"987654",
"123456"
]
}
}
}
]
}
The secret policy:
{
"Version" : "2012-10-17",
"Statement" : [ {
"Sid" : "",
"Effect" : "Allow",
"Principal" : {
"AWS" : "*"
},
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "*",
"Condition" : {
"StringEquals" : {
"aws:SourceAccount" : [ "987654", "123456" ]
}
}
} ]
}
When reading the key from account 987654 it works fine. When I try to read the secret from role in account 123456 I get AccessDeniedException:
An error occurred (AccessDeniedException) when calling the GetSecretValue operation: User: arn:aws:sts::123456:assumed-role/Admin/sessionfoo is not authorized to perform: secretsmanager:GetSecretValue on resource: arn:aws:secretsmanager:us-east-1:987654:secret:test because no resource-based policy allows the secretsmanager:GetSecretValue action
I am testing with:
aws secretsmanager get-secret-value --secret-id 'arn:aws:secretsmanager:us-east-1:987654:secret:test'
What's wrong with my policies? Thanks!

aws secrets manger and multiple accounts

I have a secret in one account that I want to share in another account. In the other account we have a lambda function that will need this secret. I followed this and it works great.
AWS share secrets between accounts
Now we want to see if instead of granting access to every user that invokes this lambda is there a way to grant access to a group or a role in the other account access to the secret. I tried using the role that invokes the function but I got denied in the response for the lambda. Then next I tried a group in the other account but it wouldn't let me save it. I just kept telling the principal was not correct. Thanks.
So here is what I used for policies.
Policy on the Customer Managed Key
{
"Sid": "Permissions for external users",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::external-acct:role/Cross-Account-KMS-Role"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "secretsmanager.us-east-1.amazonaws.com"
},
"StringLike": {
"kms:EncryptionContext:SecretARN": "arn:aws:secretsmanager:us-east-1:central-acct:secret:my-secret"
}
}
}
Now on the secret itself we set this policy up.
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal" : {
"AWS" : "arn:aws:iam::external-acct:role/Cross-Account-KMS-Role"
},
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "*",
"Condition" : {
"ForAnyValue:StringEquals" : {
"secretsmanager:VersionStage" : "AWSCURRENT"
}
}}
Then on the external account we created this policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:us-east-1:central-acct:secret:my-secret"
},
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:us-east-1:central-acct:key/customer-key-1"
}
]
}
then we atached the policy to the Role above. Now when i did this for my own account instead of the role I can use aws cli and pull the secret. Now of course i wasn't using the role but my account.
Ok, So I figured it out. It seems that the resource policy on the CMK was wrong. I had used one like this
arn:aws:kms:us-east-1:my_acct:key/my_policy
When I needed one like this.
arn:aws:kms:us-east-1:my_acct:key/my_policy_id

How to allow image tagging with least privileges

I am using this IAM policy to allow a user to tag images with the least privileges possible.
However, it does not seem to be enough
{
"Version" : "2012-10-17",
"Statement" : [{
"Effect" : "Allow",
"Action" : [
"ec2:CreateTags",
"ec2:DescribeTags",
"tag:getResources"
"tag:getTagKeys",
"tag:getTagValues",
"tag:addResourceTags"
],
"Resource" : "arn:aws:ec2:::image/*"
}]
}
Also, is there a way to run AWS CLI so that it is more verbose at to the specific IAM permissions that it needs to use?
There is a syntax error after getResources. The following works perfectly for me:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DescribeTags"
],
"Resource": "*"
}
]
}
The resource has to be " * " since CreateTags and DeleteTags actions do not support resource-level permissions. Policies granting access must specify " * " in the resource element.