Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does allowUnauthenticatedIdentities allow anonymous users to obtain a JWT? #13150

Closed
ChapterSevenSeeds opened this issue Aug 24, 2023 · 7 comments
Labels
pending-triage Issue is pending triage question General question

Comments

@ChapterSevenSeeds
Copy link

Amplify CLI Version

12.2.3

Question

I recently enabled public read access to an S3 bucket in my Amplify project. While I was doing this in the CLI, Amplify told me that I will have to enable the allowUnauthenticatedIdentities option for my user pool. This term has since been a bit of a buzzword for me, and I just want some assurance that anonymous users aren't magically granted the same level of access as authenticated users.

So, with allowUnauthenticatedIdentities enabled for S3 public read access, can anonymous users do anything else? Are they able to get a JWT and make GraphQL queries to AppSync? Are they able to make requests to an API Gateway that has a Cognito authorizer? From all the reading I have done, it seems like the answer is no, but I am not sure enough of it to feel completely safe.

@ChapterSevenSeeds ChapterSevenSeeds added pending-triage Issue is pending triage question General question labels Aug 24, 2023
@josefaidt
Copy link
Contributor

Hey @ChapterSevenSeeds 👋 thanks for raising this! This is a great question! The allowUnauthenticatedIdentities option will allow guest access via the "Unauth" role that is created with your project on amplify init, and will make requests to AWS services by signing the request with credentials obtained from assuming that role.

with allowUnauthenticatedIdentities enabled for S3 public read access, can anonymous users do anything else?

No, they will be able to read/get files from the bucket, but not write or delete.

Are they able to get a JWT and make GraphQL queries to AppSync?

No, unless the public IAM auth rule is specified.

..., iam is specified as the provider which allows you to use an "Unauthenticated Role" from the Cognito identity pool for public access instead of an API Key. When you run amplify add auth, the Amplify CLI generates scoped down IAM policies for the "Unauthenticated role" in Cognito identity pool automatically.

An example of this auth rule is:

@auth(rules: [{ allow: public, provider: iam }])

Are they able to make requests to an API Gateway that has a Cognito authorizer?

No, this will require a valid Cognito User Pools user, where the unauth role is attached to the Cognito Identity Pool and IAM authorization is (by default) applied when using amplify add|update api

@josefaidt josefaidt added the pending-response Issue is pending response from the issue author label Aug 24, 2023
@ChapterSevenSeeds
Copy link
Author

Thanks @josefaidt, I appreciate the reassurance.

So, I think you calmed all my fears. My last concern still lives with my REST API. When I added this API using the Amplify CLI, I selected No for the Restrict API Access option. However, I added an override to the API in which I add my Cognito user pool as a security definition and require it on most of my routes. The majority of the code doing this is outlined below.

resources.restApi.addPropertyOverride("Body.securityDefinitions", {
        Cognito: {
            type: "apiKey",
            name: "Authorization",
            in: "header",
            "x-amazon-apigateway-authtype": "cognito_user_pools",
            "x-amazon-apigateway-authorizer": {
                type: "cognito_user_pools",
                providerARNs: [
                    {
                        "Fn::Join": [
                            "",
                            [
                                "arn:aws:cognito-idp:",
                                {
                                    Ref: "AWS::Region",
                                },
                                ":",
                                {
                                    Ref: "AWS::AccountId",
                                },
                                ":userpool/",
                                {
                                    Ref: "AuthCognitoUserPoolId",
                                },
                            ],
                        ],
                    },
                ],
            },
        },
    });

I then have the following for each route:

resources.restApi.addPropertyOverride(
            `Body.paths.${path}.x-amazon-apigateway-any-method.parameters`,
            [
                ...resources.restApi.body.paths[path]["x-amazon-apigateway-any-method"]
                    .parameters,
                {
                    name: "Authorization",
                    in: "header",
                    required: false,
                    type: "string",
                },
            ]
        );
        resources.restApi.addPropertyOverride(
            `Body.paths.${path}.x-amazon-apigateway-any-method.security`,
            [
                {
                    Cognito: [],
                },
            ]
        );

Then, when I make requests to my API, I have to manually insert the JWT, as follows.

const data: Price[] = await API.post("myapi", "/my-route", {
            headers: {
                Authorization: `Bearer ${(await Auth.currentSession())
                    .getIdToken()
                    .getJwtToken()}`
            }
        });

This seems to work quite well. So, with the setup outlined above, an anonymous user will never be able to make requests to the restricted routes in my API, right? If the answer is still a yes, then I think I can put this issue to bed.

Thanks!

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label Aug 24, 2023
@josefaidt
Copy link
Contributor

Hey @ChapterSevenSeeds that is correct, and to demonstrate if I were to run amplify add api to create a route /public that allows "authenticated and guest access" you will see an update to the unauth role as shown in the screenshot below

✔ Restrict API access? (Y/n) · yes
✔ Who should have access? · Authenticated and Guest users
✔ What permissions do you want to grant to Authenticated users? · read
✔ What permissions do you want to grant to Guest users? · read
image

To verify this you can call API.post without passing additional headers, which will in turn make a signed request to your endpoint, and it should fail with a 401 status code

@josefaidt josefaidt added the pending-response Issue is pending response from the issue author label Aug 24, 2023
@ChapterSevenSeeds
Copy link
Author

@josefaidt That's perfect, thanks again.

Regarding my override that adds a Cognito authorizer to my API, do you know of any way to do the same thing without an override? Essentially, if I want to restrict API access to authenticated Cognito users only, how can I do this without an override? I'm fine leaving the override as is, I just figured it wouldn't hurt to see if there is a better way.

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label Aug 24, 2023
@josefaidt
Copy link
Contributor

Hey @ChapterSevenSeeds yes, but I'd say it depends whether you're looking to capture the caller's identity in your API routes. By default when restricting access to API routes it will set up IAM authorization to be used with your auth and unauth roles, and also supports Cognito User Pool per-Group access. This will remove the need for the override, but you will lose access to the caller's identity in the Lambda resolvers.

@josefaidt josefaidt added the pending-response Issue is pending response from the issue author label Aug 24, 2023
@ChapterSevenSeeds
Copy link
Author

@josefaidt That makes sense. I appreciate all your wisdom!

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label Aug 24, 2023
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pending-triage Issue is pending triage question General question
Projects
None yet
Development

No branches or pull requests

2 participants