Typically I combined AppSync with Cognito User Pools for authorization. This works great for API’s where the user is logged in but what if you need a few queries or mutations to work for users who aren’t logged in?

A common example of this is a mutation that allows people to register.

While AppSync doesn’t allow unauthenticated requests you can use API key authorization to get around the need for a user to be logged in.

Start by setting up AppSync with Cognito User Pools as the default authorization mode and API key as an additional authorization provider. This will protect the API using Cognito User Pools authorization but allow us to enable API key authorization for some fields.

Next I need a schema with a mutation.

type Account {
  id: ID!
  email: AWSEmail!
  name: String!
}

input RegisterAccountInput {
  email: AWSEmail!
  name: String!
  password: String!
  ## Other registration fields
}

type Query {
    findAccount(id: ID!): Account
}

type Mutation {
  registerAccount(input: RegisterAccountInput!): Account
}

By default the entire schema can only be accessed if the request uses Cognito User Pools authorization. By adding @aws_api_key @aws_cognito_user_pools to a type/field you can allow both authorization methods. If you only want to allow API key then you can use @aws_api_key.

In the following example I’ve limited access to the registerAccount mutation to only requests using API key authorization and you can only access the id field on the Account that it returns.

type Account {
  id: ID! @aws_api_key @aws_cognito_user_pools
  email: AWSEmail!
  name: String!
}

input RegisterAccountInput {
  email: AWSEmail!
  name: String!
  password: String!
  ## Other registration fields
}

type Query {
    findAccount(id: ID!): Account
}

type Mutation {
  registerAccount(input: RegisterAccountInput!): Account @aws_api_key
}

For the user to access the other Account fields they would need to switch to Cognito User Pools authorization and use findAccount.