This is a series of articles about setting up a complex Serverless backend infrastructure with AWS SAM and CloudFormation.
Here is the index of all the articles in case you want to jump to any of them:
1. Setup of AppSync and API Gateway with Multiple AWS Cognito User Pools
2. Configuring S3 Buckets with Permissions and Access Roles in AWS Cognito AuthRole
3. Intro to DynamoDB Resolvers for AppSync Implementation
4. Intro to Lambda Resolvers for AppSync Implementation
5. Configuring an AWS VPC to Include Lambda Resolvers with a Fixed IP
6. Intro to Pipeline Resolvers for AppSync Implementation
7. Handling Lambda Resolver Timeouts with SNS Messages
Introduction
AWS S3 is a versatile storage solution. When combined with AWS Cognito's AuthRole, it offers granular access control, ensuring users can only access relevant data. In this guide, we'll explore how to grant users read access to an entire S3 bucket but restrict write access to folders matching their user IDs.
The Code
Setting Up the S3 Bucket
- Create an S3 Bucket.
- Organize Data: Structure your data such that each user's data resides in a folder named after their user ID.
Resources:
MyS3Bucket:
Type: "AWS::S3::Bucket"
Configuring Cognito AuthRole and UnAuthRole for S3 Access
- Define the UnAuthRole
- Create a New Identity Pool: This associates the Cognito User Pool with the identity pool. This allows for federated identities and the distinction between authenticated and unauthenticated roles.
- Attach both Roles: identity pool using the IdentityPoolRoleAttachment resource.
Resources:
# Unauthenticated Role with write access to the user folder
CognitoAuthRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: "Allow"
Principal:
Service: "cognito-identity.amazonaws.com"
Action: "sts:AssumeRoleWithWebIdentity"
Policies:
- PolicyName: "S3AccessPolicy"
PolicyDocument:
Statement:
- Effect: "Allow"
Action: "s3:GetObject"
Resource: !Sub "arn:aws:s3:::${MyS3Bucket}/*"
- Effect: "Allow"
Action: "s3:PutObject"
Resource: !Sub "arn:aws:s3:::${MyS3Bucket}/${cognito-identity.amazonaws.com:sub}/*"
# Unauthenticated Role with read access to the S3 bucket
CognitoUnAuthRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud": !Ref CognitoIdentityPool
Policies:
- PolicyName: "S3ReadAccessPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "s3:GetObject"
Resource: !Sub "arn:aws:s3:::${MyS3Bucket}/*"
# Cognito Identity Pool
CognitoIdentityPool:
Type: "AWS::Cognito::IdentityPool"
Properties:
IdentityPoolName: "MyIdentityPool"
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId: !Ref UserPoolGeneralClient
ProviderName: !GetAtt [UserPoolGeneral, ProviderName]
# Attach roles to the Cognito Identity Pool
SetIdentityPoolRoles:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
Properties:
IdentityPoolId: !Ref CognitoIdentityPool
Roles:
authenticated: !GetAtt [CognitoAuthRole, Arn]
unauthenticated: !GetAtt [CognitoUnAuthRole, Arn]
# Assuming you have a user pool client for the general user pool
UserPoolGeneralClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: "GeneralUserClient"
UserPoolId: !Ref UserPoolGeneral
GenerateSecret: false
Conclusion
By leveraging AWS Cognito and S3's powerful access control mechanisms, businesses can ensure that users have the right data access level. This setup not only enhances security but also provides a personalized user experience.
Please note that the code examples have been simplified to help understand the approach and the resources. Some adjustments might be needed.
---------
Next UP: Part 3. Intro to DynamoDB Resolvers for AppSync Implementation