Currently spinning wheels while using terraform with the aws provider. The policy below seems valid, but it keeps being rejected. I can't figure out why this is invalid Json for policy:
resource "aws_iam_policy" "aws_dms_secret_sql_server_policy" {
name = "${var.application}-${replace(var.service, "-", "")}-${replace(data.aws_region.current.name, "-", "")}-${terraform.workspace}-dms_secret_sql_server_policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "${module.rds_staging.secrets_manager_secret_arn}"
},
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "${module.rds_staging.secrets_manager_kms_key_arn}"
}
]
}
EOF
tags = local.common_tags
}
Here is the terraform error:
Error: "policy" contains an invalid JSON policy
with aws_iam_policy.aws_dms_secret_sql_server_policy,
on dms-bronze-iam.tf line 88, in resource "aws_iam_policy" "aws_dms_secret_sql_server_policy":
88: policy = <<EOF
89: {
90: "Version": "2012-10-17",
91: "Statement": [
92: {
93: "Effect": "Allow",
94: "Action": "secretsmanager:GetSecretValue",
95: "Resource": "${module.rds_staging.secrets_manager_secret_arn}"
96: },
97: {
98: "Effect": "Allow",
99: "Action": [
100: "kms:Decrypt",
101: "kms:DescribeKey"
102: ],
103: "Resource": "${module.rds_staging.secrets_manager_kms_key_arn}"
104: }
105: ]
106: }
107: EOF
Your JSON must be invalid when evaluated. The terraform documentation states:
Don't use "heredoc" strings to generate JSON or YAML. Instead, use the jsonencode function or the yamlencode function so that Terraform can be responsible for guaranteeing valid JSON or YAML syntax.
so, using the jsonencode function:
jsonencode({
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "${module.rds_staging.secrets_manager_secret_arn}"
},
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "${module.rds_staging.secrets_manager_kms_key_arn}"
}
]
})
Related
I am facing the issue "This policy contains the following error: JSON strings must not have leading spaces"
Here is my code, could anyone help please
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"iam:CreateServiceSpecificCredential",
"iam:DeleteAccessKey",
"iam:GetServiceLastAccessedDetailsWithEntities",
"iam:GenerateServiceLastAccessedDetails",
"iam:PutRolePermissionsBoundary",
"iam:ListPoliciesGrantingServiceAccess",
"iam:UpdateOpenIDConnectProviderThumbprint",
"iam:ResetServiceSpecificCredential",
"iam:DeleteSSHPublicKey",
"iam:ListServiceSpecificCredentials",
"iam:CreateSAMLProvider",
"iam:TagSAMLProvider",
"iam:DeleteRolePermissionsBoundary",
"iam:GetServiceLastAccessedDetails",
"iam:GetOrganizationsAccessReport",
"iam:CreateAccessKey",
"iam:ListSSHPublicKeys",
"iam:GenerateOrganizationsAccessReport",
"iam:ListOpenIDConnectProviderTags",
"iam:CreateAccountAlias",
"iam:ListSAMLProviderTags",
"iam:UploadSSHPublicKey",
"iam:DeleteAccountAlias",
"iam:DeleteOpenIDConnectProvider",
"iam:UpdateSAMLProvider",
"iam:GetSAMLProvider",
"iam:ListAccessKeys",
"iam:UpdateServiceSpecificCredential",
"iam:UntagSAMLProvider",
"iam:ListSAMLProviders",
"iam:RemoveClientIDFromOpenIDConnectProvider",
"iam:PutUserPermissionsBoundary",
"iam:GetAccessKeyLastUsed",
"iam:GetSSHPublicKey",
"iam:UpdateAccessKey",
"iam:DeleteUserPermissionsBoundary",
"iam:UpdateSSHPublicKey",
"iam:CreateOpenIDConnectProvider",
"iam:ListOpenIDConnectProviders",
"iam:ListAccountAliases",
"iam:UntagOpenIDConnectProvider",
"iam:GetOpenIDConnectProvider",
"iam:AddClientIDToOpenIDConnectProvider",
"iam:DeleteServiceSpecificCredential",
"iam:TagOpenIDConnectProvider",
"iam:DeleteSAMLProvider"
],
"Resource": ""
},
{
"Sid": "VisualEditor1",
"Effect": "Deny",
"Action": [
"iam:UpdateAssumeRolePolicy",
"iam:PutUserPermissionsBoundary",
"iam:PutUserPolicy",
"iam:CreatePolicyVersion"
],
"Resource": ""
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": ["iam:CreateUser"],
"Resource": "*"
},
{
"Sid": "VisualEditor3",
"Effect": "Deny",
"Action": ["iam:AttachGroupPolicy", "iam:AttachUserPolicy", "iam:AttachRolePolicy"],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"iam:PolicyARN": "arn:aws:iam::758773684219:policy/KodeKloudIAMPolicy"
},
"StringNotEqualsIgnoreCase": {
"iam:PolicyARN": "arn:aws:iam::758773684219:policy/KodeKloudEC2Policy"
}
}
}
]
}
I got no errors while creating the policy but it wont let me create the policy as this message pops up "This policy contains the following error: JSON strings must not have leading spaces For more information about the IAM policy grammar, see AWS IAM Policies"
Below are my configurations and I'm still getting Access Denied excpetion while trying to do PutBucketReplication from a lambda.
Replication role policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:GetReplicationConfiguration",
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging",
"s3:GetObjectRetention",
"s3:GetObjectLegalHold"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<source bucket>",
"arn:aws:s3:::<source bucket>/*",
"arn:aws:s3:::<destination bucket>",
"arn:aws:s3:::<destination bucket>/*"
]
},
{
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:ObjectOwnerOverrideToBucketOwner"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<source bucket>/*",
"arn:aws:s3:::<destination bucket>/*"
]
}
]
}
Lambda Role policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-west-2:<source account>:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-west-2:<source account>:log-group:/aws/lambda/PutReplicationFunction:*"
]
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::*"
}
]
}
Source bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<source account>:role/service-role/PutReplicationFunction-role-pugxea1r"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::<source bucket>",
"arn:aws:s3:::<source bucket>/*"
]
}
]
}
IAM pass role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole"
],
"Resource": "*"
}
]
}
Input request:
client.put_bucket_replication(
Bucket='<source bucket>',
ReplicationConfiguration={
'Role': '<iam role used for replication>',
'Rules': [
{
"Priority": 0,
"DeleteMarkerReplication": {"Status": "Disabled"},
"Filter": {"Prefix": ""},
'Status': 'Enabled',
'Destination': {
'Bucket': 'arn:aws:s3:::<destination bucket>'
}
}
]
}
)
Response:
{
"errorMessage": "An error occurred (AccessDenied) when calling the PutBucketReplication operation: Access Denied",
"errorType": "ClientError",
"requestId": "10515e45-992c-46bf-a20d-cce84c47dbb7",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 7, in lambda_handler\n response = client.put_bucket_replication(\n",
" File \"/var/runtime/botocore/client.py\", line 391, in _api_call\n return self._make_api_call(operation_name, kwargs)\n",
" File \"/var/runtime/botocore/client.py\", line 719, in _make_api_call\n raise error_class(parsed_response, operation_name)\n"
]
}
I also tried adding the bucket policy on destination account, but it is still not working
Destination bucket policy:
{
"Version": "2012-10-17",
"Id": "",
"Statement": [
{
"Sid": "Set permissions for objects",
"Effect": "Allow",
"Principal": {
"AWS": "<iam role used for replication>"
},
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete"
],
"Resource": "arn:aws:s3:::<destination bucket>/*"
},
{
"Sid": "Set permissions on bucket",
"Effect": "Allow",
"Principal": {
"AWS": "<iam role used for replication>"
},
"Action": [
"s3:List*",
"s3:GetBucketVersioning",
"s3:PutBucketVersioning"
],
"Resource": "arn:aws:s3:::<destination bucket>"
}
]
}
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>>" ]
}
}
} ]
}
i have the following policy on an IAM role which i'm assuming into:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/${aws:RequestTag/personalid}/*"
}
]
}
When performing assume role, i'm passing the tag:
response = sts_client.assume_role(
RoleArn=arn,
RoleSessionName=role_session_name,
Tags=[
{
'Key': 'personalid',
'Value':'a'
},
])
but i get access denied when trying to read an object under folder 'a':
s3 = boto3.resource(
's3',
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token=response['Credentials']['SessionToken'],
region_name=client_main_region
)
obj = s3.Object('mybucket', f'a/file.txt')
print(obj.get()['Body'].read().decode('utf-8'))
I've replaced the policy with "principalTag", while adding a tag to the role, and it works - what am i doing wrong?
=====
Another thing i tried, is to tag the s3 object with that ID, and with the following policy:
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Condition": {
"StringEqualsIfExists": {
"aws:RequestTag/personalid": "${s3:ExistingObjectTag/personalid}"
}
},
"Resource": "arn:aws:s3:::mybucket/*"
}
Not working
If anyone ever looks for this - apparently the trust relationship should declare those tags - so they will be available:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123:role/lambda_role"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123:role/lambda_role"
},
"Action": "sts:TagSession",
"Condition": {
"StringLike": {
"aws:RequestTag/personalid": "*"
}
}
}
]
}
Then, i could use this tag as principal tag in the assumed role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/${aws:PrincipalTag/personalid}/*"
}
]
}
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