Serverless whitelist different IPs to different functions - amazon-web-services

I'm using serverless to manage my Lambda functions.
If I have to white-list all of the functions in given Serverless deployment I could use something like this.
provider:
name: aws
...
resourcePolicy:
- Effect: Deny
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
Condition:
NotIpAddress:
aws:SourceIp:
- '141.206.243.10/32' # Teradata IP
- '142.0.162.0/32' # Eloqua IPs
- Effect: Allow
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
In my scenario, I have two APIs, for example
GetEmployees
PutEmployees
I want to restrict GetEmployees to be available from a certain IP range 1.2.3.x/24 and PutEmployees to be available from another IP range 4.5.6.x/24.
How can I accommodate this serverless.yml?

Resource Policies are attached to API Gateways not individual paths, so you can only have one Resource Policy document per API Gateway.
But as the rules in a policy are an array of rules, you can have individual rules for different stages, paths and methods in the following format:
execute-api:/{stage}/{path}/{method}
So what you need in your Resource Policy, is to be a bit more specific.
The below example would apply the different IP restrictions to specific resources in your API for any stage and any method.
provider:
name: aws
...
resourcePolicy:
- Effect: Allow
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
- Effect: Deny
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/GetEmployees/*
Condition:
NotIpAddress:
aws:SourceIp:
- '1.2.3.x/24'
- Effect: Deny
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/PutEmployees/*
Condition:
NotIpAddress:
aws:SourceIp:
- '4.5.6.x/24'

Related

How to add AWS managed policy through CloudFormation

I want to add AWS managed policy (AmazonSSMFullAccess) to a role using CloudFormation.
I tried to use AWS::IAM::ManagedPolicy but it creates a Customer Managed policy and I don't want that. I want it to be AWS managed.
Do you have any idea how can I do that?
I am trying to add AWS managed AmazonSSMFullAccess and here is the code I am using in mu CF template:
AmazonSSMFullAccess:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'cloudwatch:PutMetricData'
- 'ds:CreateComputer'
- 'ds:DescribeDirectories'
- 'ec2:DescribeInstanceStatus'
- 'logs:*'
- 'ssm:*'
- 'ec2messages:*'
Resource: '*'
- Effect: Allow
Action: 'iam:CreateServiceLinkedRole'
Resource: >-
arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*
Condition:
StringLike:
'iam:AWSServiceName': ssm.amazonaws.com
- Effect: Allow
Action:
- 'iam:DeleteServiceLinkedRole'
- 'iam:GetServiceLinkedRoleDeletionStatus'
Resource: >-
arn:aws:iam::*:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM*
- Effect: Allow
Action:
- 'ssmmessages:CreateControlChannel'
- 'ssmmessages:CreateDataChannel'
- 'ssmmessages:OpenControlChannel'
- 'ssmmessages:OpenDataChannel'
Resource: '*'
You can't create AWS managed policies, because only AWS can do it. You, as an AWS customer can only create customer managed policies.

CloudFormation refusing to create AWS::KMS::Key with least privilege

Endeavouring to apply the principle of least privilege to a CMK I'm creating, the goal is to create a CloudFormation template that can be used via StackSets to the entire organisation. As a result, I want a key that can be used (kms:Encrypt, kms:Decrypt etc.) for general encryption tasks in the account, but that cannot be modified by principals in the account (specifically kms:PutKeyPolicy but not only).
I have a working policy lifted from a hand crafted key. The CloudFormation template works fine, the StackSet initiates the resource creation.
But only when I don't restrict the account principal with any conditions, which removes the least privilege principle. The CreateKey and PutKeyPolicy API calls both have an option BypassPolicyLockoutSafetyCheck for those of us idiotic enough to think they know better! Except CloudFormation doesn't expose that for AWS::KMS::Key :(
So unless I basically leave the key policy wide open, I get the following error in the Stack:
Resource handler returned message: "The new key policy will not allow you to update the key policy in the future. (Service: Kms, Status Code: 400, Request ID: xxxx, Extended Request ID: null)" (RequestToken: xxxx, HandlerErrorCode: InvalidRequest)
I've tried a variety of options for the principal, with the Condition removed (as below) the key is created, with it in no joy.
- Sid: AllowUpdatesByCloudFormation
Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
Action:
- kms:Describe*
- kms:List*
- kms:PutKeyPolicy
- kms:CreateAlias
- kms:UpdateAlias
- kms:UpdateKeyDescription
- kms:EnableKey
- kms:DisableKey
- kms:EnableKeyRotation
- kms:DisableKeyRotation
- kms:GetKey*
- kms:DeleteAlias
- kms:TagResource
- kms:UntagResource
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
Resource: '*'
# Condition:
# StringEquals:
# "aws:PrincipalAccount": !Sub ${AWS::AccountId}
# "kms:ViaService": !Sub "cloudformation.${AWS::Region}.amazonaws.com"
I've tried with different principal settings, including AWS: "*" and a few different Service options, and different settings on the Condition. I've tried with and without the region in the service name. I must be missing something, but I've lost a few hours scratching my head over this one.
Web searches, AWS forum searches have turned up nothing, so I'm hoping the good bhurgers of StackOverflow can guide me - and future me's searching for the same help :)
It doesn't seem possible to link to the table section on the AWS KMS API page for the condition keys on CreateKey or PutKeyPolicy but I don't think I've missed a trick with those?
Thanks in advance - Robert.
Try giving the root user all kms permissions - (kms:*)
The principle of least privilege still applies when giving root all access.
That will enable IAM User permissions.
Add additional policies to each role or user or user group.
Add a policy for key administration.
Add a policy for usage.
That is where you can fine tune your access.
Try working with this key policy and tweak it.
This is a key I use for RDS encryption in a cfn stack.
(Yes! I know that policies should be applied to user groups, not users directly for best practices... but this is inside a sandbox environment I have access to from 'aCloud guru')
KeyPolicy:
Id: key-consolepolicy-3
Version: "2012-10-17"
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
Action: kms:*
Resource: '*'
- Sid: Allow access for Key Administrators
Effect: Allow
Principal:
AWS:
- !Sub "arn:aws:iam::${AWS::AccountId}:role/admin"
- !Sub "arn:aws:iam::${AWS::AccountId}:user/cloud_user"
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:TagResource
- kms:UntagResource
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
Resource: '*'
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS"
Action:
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
- kms:DescribeKey
Resource: '*'
- Sid: Allow attachment of persistent resources
Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS"
Action:
- kms:CreateGrant
- kms:ListGrants
- kms:RevokeGrant
Resource: '*'
Condition:
Bool:
kms:GrantIsForAWSResource: "true"

What is the valid syntax for a KMS Key Policy to avoid MalformedPolicyDocument errors?

I am trying to create an AWS KMS Key Policy and have been plagued trying to get Cloudformation to accept the key policy. Everything I have been able to find and read says this policy should be valid and the syntax is correct as it runs, but returns MalformedPolicyDocumentExceptionnull (Service: AWSKMS; Status Code: 400;
Has anyone else run into this, if so, any thoughts or suggestions on how I can resolve the errors? I've been stuck and banging my head on this one and can't see what I'm missing and my google-fu is failing me.
Code Snippet:
SnowflakeProdKMS:
Type: AWS::KMS::Key
Properties:
Description: KMS key used by Snowflake to encrypt/decrypt data stored in s3
Enabled: True
EnableKeyRotation: False
KeyPolicy:
Version: 2012-10-17
Id: key-default-1
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
Action:
- kms:*
Resource: '*'
- Sid: Enable AWSAdminRole to have full permissions to KMS key
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:/role/AWSAdminRole
Action: kms:*
Resource: '*'
- Sid: Allow use of the key by other roles
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:role/AWSAdminRole
# - !Sub arn:aws:iam::${AWS::AccountId}:role/SnowflakeAccessRole
Action:
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt
- kms:GenerateDataKey
- kms:DescribeKey
Resource: '*'
- Sid: Allow attachment of persistent resources
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:role/AWSAdminRole
# - !Sub arn:aws:iam::${AWS::AccountId}:role/SnowflakeAccessRole
- !Sub arn:aws:iam::${AWS::AccountId}:root
Action:
- kms:CreateGrant
- kms:ListGrants
- kms:RevokeGrant
Resource: '*'
Condition:
Bool:
- kms:GrantIsForAWSResource: 'true'
After much trial and error and reaching out to other partners I found the solution for the above issue.
The Condition on snippet above was incorrect and should have been formatted as follows:
Condition:
Bool:
"kms:GrantIsForAWSResource": true
Once changed to this the policy went in without issue.

Lambda Function Serverless permission

I've been developing an aws lambda function with python and serverless. It reads files from a s3 bucket and stores data from it in another bucket as a csv. The code works perfectly with invoke local but after deploying I get:
An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
This is the function:
s3_client.put_object(Body=data, Bucket=bucket_name, Key=key_name)
and part of the serverless yml
iamRoleStatements:
- Effect: Allow
Action:
- KMS:Decrypt
Resource: '*'
- Effect: Allow
Action:
- 's3:*'
Resource:
- 'arn:aws:s3:::output_bucket'
- 'arn:aws:s3:::output_bucket/*'
- Effect: Allow
Action:
- 's3:ListBucket'
Resource:
- 'arn:aws:s3:::input_bucket'
- 'arn:aws:s3:::input_bucket/*'
- Effect: Allow
Action:
- 's3:GetObject'
Resource:
- 'arn:aws:s3:::input_bucket'
- 'arn:aws:s3:::input_bucket/*'
Is there any other configuration I need? Am I missing something obvious?
For me the indent looks wrong. Please make sure to use it right.
iamRoleStatements:
- Effect: Allow
Action:
- 'kms:Decrypt'
Resource: '*'
- Effect: Allow
Action:
- 's3:*'
Resource:
- 'arn:aws:s3:::output_bucket'
- 'arn:aws:s3:::output_bucket/*'
- Effect: Allow
Action:
- 's3:ListBucket'
- 's3:GetObject'
Resource:
- 'arn:aws:s3:::input_bucket'
- 'arn:aws:s3:::input_bucket/*'
FYI: I merged s3:ListBucket and s3:GetObject into one statement.

AWS docker container is not inheriting the host instance role

I am trying to access S3 bucket from a Camel Router running in docker container deployed in ECS.
Host EC2 instance has IAM policies which provide access to S3 bucket and I have verified this by running a standalone router directly in EC2. But when I tried the program inside a container it is throwing an exception stating that "Access Denied" to S3 bucket.
After this, I tried providing a Task IAM Role by adding TaskRoleArn in my Cloudformation but that didn't help, still the same exception.
Not sure if I am missing anything here, any suggestions?
[Edit, adding the IAM policy here]
This is my IAM policy for host, similar one I created for Task Role as well with the trust relationship to ‘ecs-tasks.amazonaws.com’
This is my IAM policy for host, similar one I created for Task Role as well with the trust relationship to ‘ecs-tasks.amazonaws.com’
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
- ecs.amazonaws.com
Action:
- sts:AssumeRole
Path: /Developer/
Policies:
- PolicyName: ecs-service
PolicyDocument:
Statement:
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:CreateLogGroup
- logs:DescribeLogGroups
- logs:DescribeLogStreams
- logs:PutLogEvents
- logs:GetLogEvents
- logs:FilterLogEvents
Resource: '*'
- PolicyName: ep-bucket-policy
PolicyDocument:
Statement:
- Sid: bucket1
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectAcl
- s3:AbortMultipartUpload
- s3:GetObjectTagging
- s3:DeleteObject
- s3:ListMultipartUploadParts
Resource: *
- Sid: bucket2
Effect: Allow
Action: s3:ListObjects
Resource: "*"
- PolicyName: ep-ecr-policy
PolicyDocument:
Statement:
- Sid: ecr1
Effect: Allow
Action:
- ecr:BatchCheckLayerAvailability
- ecr:GetDownloadUrlForLayer
- ecr:GetRepositoryPolicy
- ecr:DescribeRepositories
- ecr:ListImages
- ecr:BatchGetImage
Resource:
- !Sub 'arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/*’
- Sid: ecr2
Effect: Allow
Action:
- ecr:GetAuthorizationToken
Resource: '*'
- PolicyName: ep-ecs-policy
PolicyDocument:
Statement:
- Sid: ecs1
Effect: Allow
Action:
- ecs:SubmitTaskStateChange
- ecs:RegisterContainerInstance
- ecs:SubmitContainerStateChange
- ecs:DeregisterContainerInstance
Resource: !Sub 'arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/Custom-*’
- Sid: ecs2
Effect: Allow
Action:
- ecs:Poll
- ecs:DiscoverPollEndpoint
- ecs:StartTelemetrySession
- ecs:CreateCluster
Resource: "*"