I created a secret in AWS Secrets Manager. I want one IAM user and a federated user to be able to list, describe and retrieve the secret. I defined the following policy:
{
"Version" : "2012-10-17",
"Statement" : [ {
"Effect" : "Allow",
"Principal" : {
"AWS" : [
"arn:aws:iam::123456789:user/IAMUser1",
"arn:aws:iam::123456789:role/UAT-Developer/dev_user1#mycompany.com"
]
},
"Action" : [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds", "secretsmanager:ListSecrets" ],
"Resource" : "*"
} ]
}
but it is throwing This resource policy contains an unsupported principal.
I also tried the below syntax for Principal but did not work.
"Principal" : {
"AWS" : "arn:aws:iam::123456789:user/IAMUser1",
"AWS" : "arn:aws:iam::123456789:role/UAT-Developer/dev_user1#mycompany.com"
}
Please help me get this correct.
I got it. We have to put assumed-role instead of just role.
arn:aws:iam::123456789:assumed-role/UAT-Developer/dev_user1#mycompany.com
Related
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.
I am creating a lambda function that will send emails (nothing new). I am having issues with the policy that I am creating. TFSec busted me with a the Resource meta-attribute and indicated that "*" isn't allowed. So all I am trying to do is limit my policy to my lambda function. I figured I could dynamically create the ARN as i have done in the past. Well, the only way I found that it works is leveraging the "condition" meta-attribute BUT..., when I used the condition, I get this error:
│ Error: error creating Lambda Function (1):
InvalidParameterValueException: The provided execution role does not
have permissions to call CreateNetworkInterface on EC2
│ { │ RespMetadata: { │ StatusCode: 400, │ RequestID:
"3b8fc1dd-21d8-xxxx-xxx-xxxxxxx" │ }, │ Message_: "The provided
execution role does not have permissions to call
CreateNetworkInterface on EC2", │ Type: "User" │ }
Whats killing me is that the permission is set in my policy, see below:
resource "aws_iam_role_policy" "lambda_sendmail_policy" {
name = "lambda-sendmail"
role = aws_iam_role.lambda_sendmail_role.id
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Sid" : "Stmt163546987325",
"Effect" : "Allow",
"Action" : [
"ec2:DescribeInstances",
"ec2:CreateNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
"autoscaling:CompleteLifecycleAction"
],
"Resource" : "*",
"Condition" : {
"StringEquals" : {
"lambda:FunctionArn" : "arn:aws:lambda:us-east-1:${local.accountid}:function:${var.appenv}-${var.lambda_appname}"
}
}
},
{
"Effect" : "Allow",
"Action" : [
"logs:PutLogEvents",
"logs:CreateLogStream"
],
"Resource" : [
"arn:aws:logs:us-east-1:${local.accountid}:log-group:/aws/lambda/*"
]
},
{
"Effect" : "Allow",
"Action" : [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"Resource" : "*"
}
]
})
}
Clearly the permission is there but I am passing the Lambda ARN incorrectly need some help here.
If I remove the condition it works but TFSEC catches me telling me that I need to specify the resource.
I am not sure if Lambda is supported by the condition attribute but any help here woudl be great.
You can't put this condition for the ec2 actions mentioned:
"Condition" : {
"StringEquals" : {
"lambda:FunctionArn" : "arn:aws:lambda:us-east-1:${local.accountid}:function:${var.appenv}-${var.lambda_appname}"
}
}
The condition to use for most of those ec2:* actions is...
"Condition": {
"ArnLikeIfExists": {
"ec2:Vpc": "your_vpc_arn"
}
}
This block limits the permission to the vpc shared by the function and fails to true for certain lambda actions like creation/update where the api calls don't include the vpc arn. This is about as tight as you can get this policy.
I'd move autoscaling to it's own block also, because you can definitely tighten that up.
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?
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": "*"
I've two AWS Cloudformation stacks, one for IAM roles and the second to create an AWS service and import the respective roles into it using Cloudformation.
When 10+ services are deployed the following error appears randomly on 1 or 2 of the services -
AWS::ECS::Service service Unable to assume role and validate the
listeners configured on your load balancer. Please verify that the ECS
service role being passed has the proper permissions.
If all the services are torn down and the services redployed to the ECS cluster, the error appears but for different services.
The AWS fix for this can be seen here
If the 1 or 2 broken services are torn down and redeployed the services deploy without issue. So the problem appears to only occur when many services are deployed at the same time - this indicates it may be an IAM propagation timing issue within Cloudformation.
I've tried adding depends on in the service definition -
"service" : {
"Type" : "AWS::ECS::Service",
"DependsOn" : [
"taskdefinition",
"ECSServiceRole"
],
"Properties" : {
"Cluster" : { "Ref": "ECSCluster"},
"Role" : {"Ref" : "ECSServiceRole"},
etc...
}
}
But this doesn't work.
As you can note, I've also removed the IAM import value for the ECSServiceRole and replaced it with an inline resource policy seen here -
"ECSServiceRole" : {
"Type" : "AWS::IAM::Role",
"Properties" : {
"AssumeRolePolicyDocument" : {
"Statement" : [
{
"Sid": "",
"Effect" : "Allow",
"Principal" : {
"Service" : [
"ecs.amazonaws.com"
]
},
"Action" : [
"sts:AssumeRole"
]
}
]
},
"Path" : "/",
"Policies" : [
{
"PolicyName" : "ecs-service",
"PolicyDocument" : {
"Statement" : [
{
"Effect" : "Allow",
"Action" : [
"ec2:Describe*",
"ec2:AuthorizeSecurityGroupIngress",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:Describe*",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:RegisterTargets",
"sns:*"
],
"Resource" : "*"
}
]
}
}
]
}
}
But again - the inline policy doesn't fix the issue either.
Any ideas or pointers would be much appreciated!
In reply to answer 1.
Thank you - I wasn't aware of this improvment.
Is this the correct way to associate the service linked role for ECS?
"ECSServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": [
"ecs.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "CreateServiceLinkedRoleForECS",
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:PutRolePolicy",
"iam:UpdateRoleDescription",
"iam:DeleteServiceLinkedRole",
"iam:GetServiceLinkedRoleDeletionStatus"
],
"Resource": "arn:aws:iam::*:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS*",
"Condition": {
"StringLike": {
"iam:AWSServiceName": "ecs.amazonaws.com"
}
}
}
]
}
}
]
}
}
Final Answer
After months of intermittent on-going issues with AWS regarding this matter AWS came back to say they were throttling us in the background, on the ELB. This is why the random and varied issues were appearing when deploying 3+ docker services via Cloudformation at the same time. The solution was nothing to do with IAM permissions, rather it was to increase the rate limit on the ELB via the "AWS Service Team".
So the fix was to continue using the two stack approach in Cloudformation, one with the IAM roles, which in turn were imported into the service layer stack. The fix was to add a depends on in the service definition for all of the other stack resources in the service layer script. By doing this it allows sufficient time for the IAM roles to be imported and executed by the service, thus this was a Cloudformation resource creation timing issue.
"service" : {
"Type" : "AWS::ECS::Service",
"DependsOn" : [
"TaskDefinition",
"EcsElasticLoadBalancer",
"DnsRecord"
],
"Properties" : {
etc...
}
}
UPDATE:
As of July 19th 2018, it is now possible to create a IAM Service-Linked Roles using CloudFormation https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-servicelinkedrole.html.
EcsServiceLinkedRole:
Type: "AWS::IAM::ServiceLinkedRole"
Properties:
AWSServiceName: "ecs.amazonaws.com"
Description: "Role to enable Amazon ECS to manage your cluster."
OLD ANSWER:
Creating your own ECSServiceRole is no longer required. By not specifying a role for your service, AWS will default on using the ECS Service-Linked role. If your AWS account is recent enough, or you have already created a cluster via the console you don't have to do anything for this to work. If not, run the following command to create the role: aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com.