IAM resource based policy implicit allow¶
Resource policy are typically used to allow cross account access for resources where it is supported some of which include:
S3
SQS
SNS
SES
KMS
Step Functions
Event Bridge
Glue
OpenSearch
API Gateway
Cloudwatch Logs
Lex v2
AWS private CA
Secrets Manager
EFS
Backup
ECR
Lambda
The AWS Documentation states when evaluating requests within the same account the rules are evaluated by AWS as follows:
By default, all requests are implicitly denied with the exception of the AWS account root user, which has full access.
An explicit allow in an identity-based or resource-based policy overrides this default.
I want to make my policy as brief as possible, at the same time lock down access within the same account as much as possible. My question is which resource based policy have such an explicit allow?
From my experiments these are services that implicit allow same account access via resource policy.
Implicit allows are based on the absence of an explicit deny statement.
SQS¶
Here I test it for SQS, I created a SQS queue with a custom defined resource-policy:
{
"Version": "2012-10-17",
"Id": "DenyIfSourceAccountAndPrincipalOrgIdMatch",
"Statement": [
{
"Sid": "DenyAccessIfSourceAccountAndPrincipalOrgIdMatch",
"Effect": "Deny",
"Principal": "*",
"Action": "sqs:*",
"Resource": "arn:aws:sqs:us-east-1m:003422198502:test",
"Condition": {
"StringNotEqualsIfExists": {
"aws:PrincipalOrgId": "o-r2rjrevijr",
"aws:SourceAccount": "${aws:AccountId}"
}
}
}
]
}
This SQS resource policy denies access to all principals *
for any SQS actions
sqs:*
on the named queue if the aws:PrincipalOrgId
is not equal to
o-r2rjrevijr
(the current org) and the aws:SourceAccount
is not equal to the
current AWS account ID.
Then I created a IAM users with permission to SQS:SendMessage
Since the resource policy has not explicitly allowed the action for my principal but testing it still works, we can be certain there is an implicit allow for same account access for SQS.
Summary¶
Services that have implicit allow in the resource-based policy:
S3
SQS
This means that the IAM resource policy has no need for same account allow statements.
Services that do not have implicit allow in the resource-based policy that I have tested using a similar method to SQS:
KMS
IAM
A note about KMS¶
No AWS principal, including the account root user or key creator, has no permissions to a KMS key unless they are explicitly allowed, and never denied, in a key policy, IAM policy, or grant.
The or
is important, because if you have modified the key policy to explicitly
turn on IAM policies to allow access to the key then you can allow access to the
KMS key using either Key Policy or IAM Policy or a grant.
This means if you have an S3 bucket that uses KMS CMK to encrypt the bucket, for
same account access IAM roles that want to decrypt objects in the bucket do not
have to have kms:Decrypt
anywhere in their IAM role policy, if the KMS key
policy grants the role kms:Decrypt
.
Explicitly turn on IAM policies to allow access to the key¶
In the following KMS key policy, when the principal in a key policy statement is the account principal, the policy statement doesn’t give any IAM principal permission to use the KMS key. Instead, it allows the account administrators to use IAM policies to delegate access to the key (when it is same account access).
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
Denied with no resource-based policy allows the kms:Decrypt action¶
This error message can be confusing because it implies the user must have access on its own IAM identity policy to do the decrypt, but in the case of KMS, this is not true you can either add decrypt from the Key policy, or directly on the IAM policy of the user (if IAM delegation is configured on the Key policy already).
<Error>
<Code>AccessDenied</Code>
<Message>User: arn:aws:sts::003422198502:assumed-role/s3-read-only-kms-test/brent is not authorized to perform: kms:Decrypt on resource: arn:aws:kms:ap-southeast-1:003422198502:key/d5d50400-1843-48d8-ba9b-d95bcca9825c because no resource-based policy allows the kms:Decrypt action</Message>
<RequestId>D6KHZ1VVT0MHNN47</RequestId>
<HostId>kvckPmdd4o5zp25QALwNCARY4L3w6UL/dIWh9YpR6x7lpHByKOLaCToKvD6VZ2+aUqWw1newmEilt6gsBnDn+g==</HostId>
</Error>
So what will happen is you fix this by adding kms:Decrypt
on the user policy,
but if the Key is not configured to use IAM you will then get this error:
<Error>
<Code>AccessDenied</Code>
<Message>User: arn:aws:sts::003422198502:assumed-role/s3-read-only-kms-test/brent is not authorized to perform: kms:Decrypt on resource: arn:aws:kms:ap-southeast-1:003422198502:key/d5d50400-1843-48d8-ba9b-d95bcca9825c because no resource-based policy allows the kms:Decrypt action</Message>
<RequestId>6SMMXFS0KA9C4ZH1</RequestId>
<HostId>qt1XO1V+pTA239BA+q3juOVwUW2ynsfl8AYOEXCL81/o98UcffdsKZHDFxaUlJH23kV4H2UQkEM6LqDD26LtQqOfkjqtKGV9ZaAHM8Vo1/Q=</HostId>
</Error>
If you get the above then you have forgotten to enable IAM access on the key, adding this policy on the key will make it work:
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
}
In S3 if you mistakenly add bucket policy and lock yourself out of the bucket, you can use the root account to delete the policy and regain access to the bucket. With KMS, there is no concept of deleting the key policy, the policy must have at least one statement so if you configure policy that locks the root out the key will become unmanaged and only AWS support can correct this.
Links¶
KMS¶
Resource policy¶
General¶
Really good summary of IAM policy Forward access session Access undenied Re-Invent slides more details than AWS Doc
Comments
comments powered by Disqus