Q:

How do I make an AWS AppSync GraphQL API publicly accessible while using Amazon Cognito for authentication?

Currently I am using Amazon Cognito for authentication in an AWS Amplify project, so only signed-in users have access to the api.
But I want to have some api calls publicly accessible.
How do I go about this?

A:

I just solved this exactly same problem. This is what I did:

Update your API by running amplify update auth and select IAM as your users handler (everything else go with default)
Login to your AWS console -> Appsync and modify access to IAM (instead of Cognito Pool)
Go to the IAM console and create IAM policies for both AUTH and UNAUTH users (search them on the list by typing the name of your Appsync app)

Locate the AUTH user and attach the following policy (update it with your info):
AUTH USER
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:GraphQL",
            "Resource": [
                "arn:aws:appsync:<AWS region>:<AWS account ID>:apis/<app sync endpoint ID>/*"
            ]
        }
    ]
}

Locate the unauth user and attach the following Policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:GraphQL",
            "Resource": [
                "arn:aws:appsync:<AWS region>:<AWS account ID>:apis/<app sync endpoint ID>/types/Query/fields/<your Query name>",
        "arn:aws:appsync:<AWS region>:<AWS account ID>:apis/<app sync endpoint ID>/types/Query/fields/<your Query name>",
        "arn:aws:appsync:<AWS region>:<AWS account ID>:apis/<app sync endpoint ID>/types/Query/fields/<your Query name>"

            ]
        }
    ]
}

And now the thing that is not documented (people transitioning from Cognito Pools to IAM ) You need to import {AUTH_TYPE} 

import AWSAppSyncClient, {AUTH_TYPE} from "aws-appsync";
and use it to load the credentials in the AppSync initialization 
const client = new AWSAppSyncClient(
  {
    disableOffline: true,
    url: aws_config.aws_appsync_graphqlEndpoint,
    region: aws_config.aws_cognito_region,
    auth: {
      // IAM
      type: AUTH_TYPE.AWS_IAM,
      credentials: () => Auth.currentCredentials(),
    });

Hope this helps. 

