# AppSync integration

Integrate SuperTokens with AppSync through an API Gateway Lambda authorizer.

## Overview

A Lambda authorizer configured as described in the [authorizer guide](/content/docs/integrations/aws-lambda/session-verification#using-lambda-authorizers/index.html) can protect GraphQL HTTP operations sent from API Gateway to AppSync.

## Before you start

Configure SuperTokens in AWS Lambda by following the [AWS Lambda integration guide](/content/docs/integrations/aws-lambda/quickstart-guide/index.html).

## Steps

### 1. Set up AppSync authorization

Use `AWS_IAM` authorization so API Gateway signs requests with its execution role. Grant that role only `appsync:GraphQL` for the root fields this integration needs:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "appsync:GraphQL",
      "Resource": [
        "arn:aws:appsync:<REGION>:<ACCOUNT_ID>:apis/<API_ID>/types/Query/fields/<QUERY_FIELD>",
        "arn:aws:appsync:<REGION>:<ACCOUNT_ID>:apis/<API_ID>/types/Mutation/fields/<MUTATION_FIELD>"
      ]
    }
  ]
}
```

Do not attach `AWSAppSyncInvokeFullAccess`; it includes broad read/list access and wildcard resources. This architecture uses IAM exclusively for the API Gateway-to-AppSync hop and does not inject shared credentials into integration headers.

### 2. Configure API Gateway with the authorizer

Follow the [authorizer guide](/content/docs/integrations/aws-lambda/session-verification#using-lambda-authorizers/index.html) to create `/auth` and `/graphql` resources. Point `/auth` to the Lambda function that handles the auth APIs and require the Lambda authorizer on `POST /graphql`.

Configure `POST /graphql` as an AWS service integration that invokes only the target AppSync GraphQL API with the least-privilege execution role above. Do not infer the current console’s service, subdomain, or path-override values from this page. Capture them in reproducible IaC and prove the generated request reaches the target API before publishing the integration.

### 3. Set up integration headers

- Set the integration request’s `x-user-id` header from `context.authorizer.principalId`. This must overwrite any client-supplied `x-user-id`; never pass the incoming identity header through.
- Set the required `Content-Type` for the GraphQL request and map the request body without changing the GraphQL document or variables. Verify these mappings in the IaC E2E fixture.

### 4. Consume the context in resolvers

In a VTL resolver, read the mapped user ID with:

```
$context.request.headers.get("x-user-id")
```

Treat this value as trusted only after an E2E test proves API Gateway overwrites a spoofed client header after successful authorization. Use it for application-level ownership checks; the execution role limits which root fields API Gateway can invoke, but does not implement per-user authorization inside a resolver. See the [resolver context documentation](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html#access-request-headers).

### 5. Validate the deployed integration

The required IaC fixture must cover valid, missing, expired, and invalid sessions; a spoofed `x-user-id`; IAM denial for fields outside the allowed field list; request and response body mappings; GraphQL errors; and browser CORS behavior. AppSync subscriptions use a separate real-time WebSocket endpoint and are outside this HTTP proxy design.
