Reputation: 81
I have a secret in secrets manager and there are multiple IAM roles in the system. I only want only one role to access the scecret. Unfortunately there are some other IAM roles that have full Secrets Manager privileges. So i want to restrict the access to the secret to all other roles except desired one by me.
roles
The following is working.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "secretsmanager:GetSecretValue",
"Principal": {
"AWS": "arn:aws:iam::IAM_role_1_that_should_not_access_the_secret",
"AWS": "arn:aws:iam::IAM_role_2_that_should_not_access_the_secret"
},
"Resource": "*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::IAM_role_that_need_to_access_the_secret"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
"Condition": {
"ForAnyValue:StringEquals": {
"secretsmanager:VersionStage": "AWSCURRENT"
}
}
}
]
}
But i want to Deny access to all roles without explicitly mentioning each of them in the Deny permission section. Something like below. But it will restrict to all roles including the desired role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "secretsmanager:GetSecretValue",
"Principal": {"AWS": "*"},
"Resource": "*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::IAM_role_that_need_to_access_the_secret"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
"Condition": {
"ForAnyValue:StringEquals": {
"secretsmanager:VersionStage": "AWSCURRENT"
}
}
}
]
}
Upvotes: 2
Views: 4502
Reputation: 1145
I was able to achieve this with using a Condition on the Resource Policy and specifying the ARN of the Role in aws:PrincipalArn (Ref: https://aws.amazon.com/blogs/security/iam-makes-it-easier-to-manage-permissions-for-aws-services-accessing-resources/)
{
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "Get",
"Effect" : "Deny",
"Principal" : "*",
"Action" : "secretsmanager:GetSecretValue",
"Resource" : "<<ARN OF Secret>>",
"Condition" : {
"StringNotLike" : {
"aws:PrincipalArn" : [
"<<ARN of IAM_role_that_need_to_access_the_secret>>" ]
}
}
} ]
}
Upvotes: 4
Reputation: 1
You could create a KMS key then create a policy for the KMS key which grants access only to the roles you need. Something like below:
{
"Version": "2012-10-17",
"Id": "key-default-admin",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<AWS_ACCOUNT_ID>:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow administration of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME>",
"arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME>"
]
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<AWS_ACCOUNT_ID>:role/AdminRole",
"arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME>"
]
},
"Action": [
"kms:DescribeKey",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey",
"kms:GenerateDataKeyWithoutPlaintext"
],
"Resource": "*"
},
{
"Sid": "Deny use of the key",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<AWS_ACCOUNT_ID>:root"
},
"Action": "kms:*",
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME>",
"arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME>"
]
}
}
}
]
}
Upvotes: 0
Reputation: 269370
Update:
I asked AWS Support, and they said:
It is a known issue where
NotPrinicipal
fails the resource policy with an explicit deny.The workaround is to use
"StringNotEquals":"aws:PrincipalArn"
condition key.
Previous answer:
You can use :NotPrincipal
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::IAM_role_that_need_to_access_the_secret"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
...
Upvotes: 0