Restricting access to s3 folder by congito sub
See original GitHub issue** Which Category is your question related to? ** Auth / Storage
** What AWS Services are you utilizing? ** S3 / Cognito
** Provide additional details e.g. code snippets ** I am trying to have users of my app upload images to a folder in an s3 bucket which then triggers a lambda function that adds the image as the profile picture in my dynamodb.
I am having an issue when restricting the access so that users can only mutate their own images.
I used the policy described here https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_cognito-bucket.html
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::<BUCKET-NAME>"],
"Condition": {
"StringLike": {
"s3:prefix": ["app/"]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<BUCKET-NAME>/app/${cognito-identity.amazonaws.com:sub}",
"arn:aws:s3:::<BUCKET-NAME>/app/${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
in my amplify config I changed the default customPrefixes to reflect the folder.
customPrefix: {
private: ‘app/’,
protected: ‘app/’,
public: ‘app/’,
},
But if I try to upload
Amplify.Storage.put(`${congito.sub}/test.txt`', 'Hello')
.then (result => console.log(result))
.catch(err => console.log(err));
I am getting an unauthorized error.
However, if I am adjusting the policy by removing ${cognito-identity.amazonaws.com:sub} to:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::<BUCKET-NAME>"],
"Condition": {
"StringLike": {
"s3:prefix": ["app/"]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<BUCKET-NAME>/app",
"arn:aws:s3:::<BUCKET-NAME>/app/*"
]
}
]
}
it works fine. In my lambda trigger I see then that the userIdentity does not contain a cognito sub though, only a principalId.
{
"Records": [
{
"eventVersion": "2.1",
"eventSource": "aws:s3",
"awsRegion": "eu-west-1",
"eventTime": "2018-12-11T15:10:56.056Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AWS:AROAXXXXXXXXXSJ7LGAIC:CognitoIdentityCredentials"
},
"requestParameters": {
"sourceIPAddress": XXXXXX
},
"responseElements": {
"x-amz-request-id": XXXX,
"x-amz-id-2": XXXX,
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "01b36196-568a-4ce7-97ab-a428e8c581eb",
"bucket": {
"name": "dh--sfa-api--image--images",
"ownerIdentity": {
"principalId": XXXXX
},
"arn": "arn:aws:s3:::dh--sfa-api--image--images"
},
"object": {
"key": "app/07e32422-5a14-4c9b-a286-dc440a72687f/test.txt",
"size": 5,
"eTag": "8b1a9953c4611296a827abf8c47804d7",
"sequencer": "005C0FD38006BD30DC"
}
}
}
]
}
What could I be doing wrong here ?
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (7 by maintainers)
For anyone wondering how to get the
${cognito-identity.amazonaws.com:sub}
I found the issue in the end. Apparently it seems to be a common misconception that the ${cognito-identity.amazonaws.com:sub} is the ${congito.sub} while they are actually different.
When using the
level: protected
it automactically adds the ${cognito-identity.amazonaws.com:sub} which looks like eu-west-1:8f8ac3c6-65bd-4844-a4b6-5446c651684b where the uuid is not the ${congito.sub}.So querying https://XXXXXX.s3.eu-west-1.amazonaws.com/app/${cognito:sub}/example1.png returns a 404, correct would have been https://XXXXXX.s3.eu-west-1.amazonaws.com/app/${cognito-identity.amazonaws.com:sub}/example1.png