AWS Secrets Manager Resource Policy to Deny all roles Except one Role - amazon-web-services

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
IAM_role_that_need_to_access_the_secret.
IAM_role_1_that_should_not_access_the_secret.
IAM_role_2_that_should_not_access_the_secret.
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"
}
}
}
]
}

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": "*",
...

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>"
]
}
}
}
]
}

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>>" ]
}
}
} ]
}

Related

AWS permission boundary won't apply to the secound user

I tried to implement the AWS Permission Boundary to user1 who has full permission on IAM actions. Then user1 created a another user (user2). The user2 is apple to do any actions without any restriction. As I understood, the user2 should not have more permission than user1. Anyone had same issue? anyone got any sample Permission Boundary policy?
Had a kind of same issue with AWS Permission Boundary and issue was with the the policy didn't deny some permission. Eg: DeleteUserPermissionsBoundary, DeleteRolePermissionsBoundary
You can find the full video explanation here: https://youtu.be/ExjW3HCFG1U?t=3402
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IAMAccess",
"Effect": "Allow",
"Action": "iam:*",
"Resource": "*"
},
{
"Sid": "DenyCreatingUserWithoutPermisionBoundary",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:CreateRole"
],
"Resource": [
"arn:aws:iam::YOUR_ACCOUNT_ID:user/*",
"arn:aws:iam::YOUR_ACCOUNT_ID:role/*"
],
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::YOUR_ACCOUNT_ID:policy/permission-boundary"
}
}
},
{
"Sid": "DenyDeletingPolicy",
"Effect": "Deny",
"Action": [
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:CreatePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
"Resource": [
"arn:aws:iam::YOUR_ACCOUNT_ID:policy/permission-boundary"
]
},
{
"Sid": "DenyDeletingPermBoundaryFromAnyUserOrRole",
"Effect": "Deny",
"Action": [
"iam:DeleteUserPermissionsBoundary",
"iam:DeleteRolePermissionsBoundary"
],
"Resource": [
"arn:aws:iam::YOUR_ACCOUNT_ID:user/*",
"arn:aws:iam::YOUR_ACCOUNT_ID:role/*"
],
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::YOUR_ACCOUNT_ID:policy/permission-boundary"
}
}
},
{
"Sid": "DenyUpdatingPermissionBoundary",
"Effect": "Deny",
"Action": [
"iam:PutUserPermissionsBoundary",
"iam:PutRolePermissionsBoundary"
],
"Resource": [
"arn:aws:iam::YOUR_ACCOUNT_ID:user/*",
"arn:aws:iam::YOUR_ACCOUNT_ID:role/*"
],
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::YOUR_ACCOUNT_ID:policy/permission-boundary"
}
}
}
]
}

AWS Policy that allows only one SSO user to access a resource

We are in a process to move all of our IAM users to aws SSO
we used to have this IAM policy for sagemaker :
"
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sagemaker:ListTags",
"sagemaker:DeleteNotebookInstance",
"sagemaker:StopNotebookInstance",
"sagemaker:CreatePresignedNotebookInstanceUrl",
"sagemaker:DescribeNotebookInstance",
"sagemaker:StartNotebookInstance",
"sagemaker:UpdateNotebookInstance"
],
"Resource": "arn:aws:sagemaker:::notebook-instance/${aws:username}*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"sagemaker:ListNotebookInstanceLifecycleConfigs",
"sagemaker:ListNotebookInstances",
"sagemaker:ListCodeRepositories"
],
"Resource": "*"
}
]
}
"
this would give access to each user to use his\hers own notebook in sagemaker
now on the new SSO permission set i gave this:
"
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"glue:CreateScript",
"secretsmanager:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sagemaker:ListTags",
"sagemaker:DeleteNotebookInstance",
"sagemaker:StopNotebookInstance",
"sagemaker:CreatePresignedNotebookInstanceUrl",
"sagemaker:Describe*",
"sagemaker:StartNotebookInstance",
"sagemaker:UpdateNotebookInstance",
"sagemaker:CreatePresignedDomainUrl",
"sagemaker:*"
],
"Resource": "arn:aws:sagemaker:::notebook-instance/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Owner": "${identitystore:UserId}"
}
}
},
{
"Effect": "Allow",
"Action": [
"sagemaker:ListTags",
"sagemaker:Describe*",
"sagemaker:StartNotebookInstance"
],
"Resource": "*"
}
]
}
"
this is what i tried but i cant make it work please assist?
i also treid using the attributes and many other things
but i just cant make it work
please if you have any suggestions
apprently on the SSO permission set we must write the region and account number of the resource
so the fix was just adding that to the resource part like this
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"glue:CreateScript",
"secretsmanager:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sagemaker:ListTags",
"sagemaker:DeleteNotebookInstance",
"sagemaker:StopNotebookInstance",
"sagemaker:CreatePresignedNotebookInstanceUrl",
"sagemaker:Describe*",
"sagemaker:StartNotebookInstance",
"sagemaker:UpdateNotebookInstance",
"sagemaker:CreatePresignedDomainUrl"
],
"Resource": "arn:aws:sagemaker:us-east-1:7XXXXXXXXX:notebook-instance/*",
"Condition": {
"StringEquals": {
"sagemaker:ResourceTag/Owner": "${identitystore:UserId}"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"sagemaker:ListNotebookInstanceLifecycleConfigs",
"sagemaker:ListNotebookInstances",
"sagemaker:ListCodeRepositories"
],
"Resource": "*"
}
]
}
thanks to Yash_c from repost.aws

Create S3 bucket policy for ssm resource data sync that allows new accounts added access without manually adding a statement

I am attempting to deploy a SSM Inventory Collection and a Resource Data Sync via Cloudformation in 15 accounts. I am able to manually add each account by adding a statement in the central s3 bucket for proper access. I was wondering is there a way to create a policy that allows newly created AWS accounts in the future to have proper access without adding a statement to the s3 bucket policy. Below is the documentation I have followed. I was using this method to add each account below
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*/accountid=123456789012/*",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*/accountid=444455556666/*",
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*/accountid=777788889999/*"
],
https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-inventory-datasync.html
Further in the documentation, I see you can create a resource data sync for accounts defined in AWS Organizations. But this still doesnt accomplish granting any new accounts where template gets deployed, access will be granted.
Creating an inventory resource data sync for accounts defined in AWS Organizations
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::S3_bucket_name"
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/bucket-prefix/*/accountid=*/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control",
"s3:RequestObjectTag/OrgId": "organization-id",
"aws:SourceAccount": "123456789012"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:ssm:*:123456789012:resource-data-sync/*"
}
}
},
{
"Sid": " SSMBucketDeliveryTagging",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObjectTagging",
"Resource": [
"arn:aws:s3:::DOC-EXAMPLE-BUCKET/bucket-prefix/*/accountid=*/*"
]
}
]
}
I have played around with a few policies but doesn't seem to work
{
"Version": "2012-10-17",
"Statement": [
{
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::inventorycollectionsync/*"
],
"Effect": "Allow",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-mb7bem0c79"
}
}
}
]
}
Try this:
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::bucketname"
},
{
"Sid": " SSMBucketOrgDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucketname/*/accountid=*/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucketname/*/accountid=*/*",
"Condition": {
"StringEquals": {
"s3:RequestObjectTag/OrgId": "org-id",
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid": " SSMBucketDeliveryTagging",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObjectTagging",
"Resource": "arn:aws:s3:::bucketname/*/accountid=*/*"
}
]
}

Deny Amazon S3 buckets and objects from being public

I am trying to write bucket policies to deny public access to buckets and objects using the AWS's defense-in-depth methodology as per How to Use Bucket Policies and Apply Defense-in-Depth to Help Secure Your Amazon S3 Data | AWS Security Blog.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnSecureCommunications",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::ironman111",
"arn:aws:s3:::ironman111/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
},
{
"Sid": "DenyPublicReadACL",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::ironman111/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": [
"public-read",
"public-read-write",
"authenticated-read"
]
}
}
},
{
"Sid": "DenyPublicReadGrant",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::ironman111/*",
"Condition": {
"StringLike": {
"s3:x-amz-grant-read": [
"*http://acs.amazonaws.com/groups/global/AllUsers*",
"*http://acs.amazonaws.com/groups/global/AuthenticatedUsers*"
]
}
}
},,
{
"Sid": "DenyPublicListACL",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutBucketAcl",
"Resource": "arn:aws:s3:::ironman111",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": [
"public-read",
"public-read-write",
"authenticated-read"
]
}
}
},
{
"Sid": "DenyPublicListGrant",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutBucketAcl",
"Resource": "arn:aws:s3:::ironman111",
"Condition": {
"StringLike": {
"s3:x-amz-grant-read": [
"*http://acs.amazonaws.com/groups/global/AllUsers*",
"*http://acs.amazonaws.com/groups/global/AuthenticatedUsers*"
]
}
}
}
]
}
However I don't see this above policy restricting me from making the bucket or object public or its ACLs public read/write.
I have later added the following to the policy. In this case, the resources are private but now I am restricted from sharing S3 buckets between accounts.
{
"Sid": "DenyAuthenticatedUsersAccess",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::ironman111/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-acl": "private"
}
}
},
{
"Sid": "DenyAuthenticatedUsersAccess",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutBucketAcl",
"Resource": "arn:aws:s3:::ironman111",
"Condition": {
"StringNotEquals": {
"s3:x-amz-acl": "private"
}
}
},
Please suggest what is wrong in the first policy.
I am unable to use IAM policy validator as it is a bucket policy. Also, I am unable to test cross-account as I do not have another canonical id.
Why does order matter in the resources array?
Updated:
I have added the following policy to the IAM user and it is still allowing the creation of a bucket with public access.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"s3:CreateBucket",
"s3:PutBucketAcl"
],
"Resource": "*",
"Condition": {
"StringLike": {
"s3:x-amz-acl": [
"public-read",
"public-read-write"
]
}
}
}
]
}
I need the policies to stop buckets from being public.
The first policy is Denying the ability to upload objects with an Access Control List that will make the objects public.
You are correct that the policy will not stop you "from making the bucket or object public or its ACLs public read/write". Rather, it is preventing files being stored as public objects in the first place.
You, as an administrator, could certainly add a Bucket Policy that then makes the whole bucket public. But that is not what the policy is trying to prevent.

Amazon S3 Policy for only PUT,Read and List

I'm trying to create a policy for only read/put/list my bucket and a dir into it.
I've write this policy:
{
"Version": "2014-05-19",
"Statement": [
{
"Effect": "Allow",
"Action": [ "s3:Put*", "s3:Get*" ],
"Resource": "arn:aws:s3:::<mybucket>/<mydirectoryinbucket>/*"
}
]
}
{
"Version": "2014-05-19",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Condition": { "StringLike": { "s3:prefix": "<mydirectoryinbucket>/*"} },
"Resource": "arn:aws:s3:::<mybucket>"
}
]
}
But I get error on the last line of the first policy...the error is only syntax error, and no additional informations.
Where I did wrong ?
You're at the very least missing the principal, which defines the entity that is allowed or denied access to a resource.
I took your policy, added the wildcard * to denote 'any' principal, and regenerated it with the IAM Policy Generator. Try this:
{
"Id": "Policy1432045314996",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicGetAndPutPolicy",
"Action": [
"s3:Get*",
"s3:Put*"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::<mybucket>/<mydirectoryinbucket>/*",
"Principal": "*"
},
{
"Sid": "PublicListPolicy",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::<mybucket>",
"Condition": {
"StringLike": {
"s3:prefix": "<mydirectoryinbucket>/*"
}
},
"Principal": "*"
}
]
}
Documentation:
Specifying a Principal in a Policy