How to give permissions to my uploaded aws lambda function? - amazon-web-services

I need to give permission for all logged users on my application.
This is my code:
this.amplifyService.auth().currentUserCredentials().then(credentials => {
const lambda = new Lambda({
credentials: this.amplifyService.auth().essentialCredentials(credentials)
});
lambda.invoke({
FunctionName: 'my-function',
}, res => {
console.log(res);
});
});
And this is the return:
authRole/CognitoIdentityCredentials is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-2:function:my-function
I already try to create a IAM role manually:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-east-2:XXXXXXXXX:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-east-2:XXXXX:log-group:/aws/lambda/my-function:*"
]
},
{
"Effect": "Allow",
"Action": [
"lambda:*"
],
"Resource": [
"arn:aws:lambda:us-east-2:XXXXXXXXX:function:my-function"
]
}
]
}
But doesn't work yet.

Related

How to produce "all principals" to principal - "AWS": "*"

When I write the following code:
const somePolicy: PolicyStatement = new PolicyStatement({
effect: Effect.ALLOW,
resources: ["someData/*"],
actions: ["es:*"],
principals: [
new ArnPrincipal("*")
],
conditions: {
IpAddress: {
SourceIp: ["*"]
}
}
});
I receive following access policy in the Elastic-Domain:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "es:*",
"Resource": "someData/*",
"Condition": {
"IpAddress": {
"SourceIp": "*"
}
}
}
]
}
My goal is to get this principal:
"Principal": {
"AWS": "*"
},
How can I receive this with cdk?
Thanks
"Principal": "*" is same as "Principal": {"AWS": "*"}. So it does not matter how you write it. CDK uses the first option, because there is no reason to make it longer than it needs to be.

How do I correctly call a lambda function in another account from a lambda?

I'm having issues with calling a lambda in account B from a different lambda in account A.
Account A's role arn is arn:aws:iam::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP
Account A's role name is DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP
Account B's role name is Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1
Account B's role arn is arn:aws:lambda:us-east-1:462087996972:function:GetActiveDeviceIdsLambdaChris
For account A my lambda role has the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
"Effect": "Allow"
},
{
"Action": "lambda:InvokeFunction",
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
"Effect": "Allow"
}
]
}
My lambda in account B has the following role as defined using cloudformation:
"CrossAccountExecutionRoleDemo": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": { "Service": ["lambda.amazonaws.com"] },
"Action": ["sts:AssumeRole"]
}
]
}
}
},
"CrossAccountExecutionPolicyDemo": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": { "Fn::GetAtt": ["GetActiveDeviceIdsLambdaDemo", "Arn"] }
}
]
},
"Roles": [
{
"Ref": "CrossAccountExecutionRoleDemo"
}
]
}
}
When I make the following request I get an error
let roleArn = 'arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-CrossAccountExecutionRol-1ANKXFZ6YS23'
sts.assumeRole(
{
RoleArn: roleArn,
RoleSessionName: 'NightlySimService',
}, function(err, res){ ... }
Error:
'
AccessDenied: User: arn:aws:sts::ACCOUNT_A:assumed-role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP/DeviceApiStack-nightlySimServiceLambdaA51B2AFE-JSUFU8F5BZGC is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-CrossAccountExecutionRol-1ANKXFZ6YS23F
'
I can spot two apparent issues in the roles, which could be the cause of your errors.
First. Incorrect principle:
"Principal": {
"AWS": "arn:aws:sts::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP"
},
As you wrote the role arn is arn:aws:iam::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP, which does not match of what you provided in the Principal.
Second. Incorrect resource:
{
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
"Effect": "Allow"
}
The action lambda:InvokeFunction applies to lambda functions, not IAM roles. Thus, the Resource should be ARN of the lambda.
There could be more issues, which are not that obvious at present.

aws:RequestTag on s3 bucket is not working (while assuming a role)

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

S3 Access Denied when specify the principal

Bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456784337:root",
"arn:aws:iam::123456784337:user/lambda-user"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
Initialize
AWS.config.update({
region: 'ap-southeast-1',
accessKey: 'abcxxxx',
secretAccessKey:'abcdxxx'
});
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'ap-southeast-1:12340000-5587-4d40-91fe-9fab5668c708'
});
S3 getObject
function (bucketName, key) {
const params = {
Bucket: bucketName,
Key: key,
};
return s3.getObject(params).promise()
.then((data) => {
console.log('Successfully read from S3!');
return data;
});
};
Congnito userUnauthenticated
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"lambda:InvokeFunction",
"mobileanalytics:PutEvents",
"dynamodb:Scan",
"lambda:InvokeAsync",
"cognito-sync:*"
],
"Resource": "*"
}
]
}
Failed to read to S3. AccessDenied: Access Denied
(node:73168) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AccessDenied: Access Denied
It only works when Principal is wildcard but it is not advisable to have that configuration.
Here is the policy to read files from S3.
{
"Id": "Policy1528709447655",
"Version": "2012-10-17",
"Statement": [{
"Sid": "Stmt1528709412334",
"Action": [
"s3:GetBucketPolicy",
"s3:GetObject",
"s3:GetObjectTagging",
"s3:GetObjectAcl"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket_name",
"arn:aws:s3:::bucket_name/*"
],
"Principal": {
"AWS": [
"arn:aws:iam::123456784337:root",
"arn:aws:iam::487686674337:user/lambda-user"
]
}
}]
}

IAM role inside SAM template

How to create an IAM role inside a SAM template likewise I did in SAM package.
I tried this as following:
"lambdaFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"apigateway.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
},
"ManagedPolicyArns": [
{
"Ref": "lambdaBasePolicy"
}
],
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"iam:ListRoles",
"ses:*",
"events:*"
],
"Resource": "*"
}
]
}
}
]
}
}
It throws me an error : com.amazonaws.serverlessappsrepo.template.InvalidTemplateException: Resource with name [lambdaFunctionRole] is invalid. AWS::Serverless::Role is not a supported Serverless Apps Repository Type.
When publishing to the Serverless app repo, you need to take care to use only the supported resources in you SAM template.
In your case, you can skip creating the lambdaFunctionRole as a standalone resource and just create it inline in your function resource definition.
"lambdaFunction": {
"Type": "AWS::Serverless::Function",
"Policies": [
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"iam:ListRoles",
"ses:*",
"events:*"
],
"Resource": "*"
}
]
}
]
}
Notice that I've only copied the PolicyDocument part of the Policies in the Role. See the Policies section in the SAM spec.