Home > Software design >  AWS Lambda Function Permission Denied when trying to access AppSync GraphQL endpoint
AWS Lambda Function Permission Denied when trying to access AppSync GraphQL endpoint

Time:02-06

new to AWS and just not sure how to define the relevant authenitcation to get my lambda function to be able to call my graphQL endpoint for a post req. Assuming I need to put an API key somewhere in this function but just am a bit lost. Any help at all would be great. Have put the function below - created it using the amplify cli and the generategraphqlpermissions flag is set to true if thats any help narrowing it down.

import crypto from '@aws-crypto/sha256-js';
import { defaultProvider } from '@aws-sdk/credential-provider-node';
import { SignatureV4 } from '@aws-sdk/signature-v4';
import { HttpRequest } from '@aws-sdk/protocol-http';
import { default as fetch, Request } from 'node-fetch';

const GRAPHQL_ENDPOINT = <myEndpoint>;
const AWS_REGION = process.env.AWS_REGION || 'us-east-1';
const { Sha256 } = crypto;

const query = /* GraphQL */ `mutation CreateCalendarEvent($input: CreateCalendarEventInput!, $condition: ModelCalendarEventConditionInput) {
  createCalendarEvent(input: $input, condition: $condition) {
    __typename
    id
    start
    end
    title
    actions
    allDay
    resizable
    draggable
    colour
    createdAt
    updatedAt
  }
}`;

/**
 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
 */

 export const handler = async (event) => {
  console.log(`EVENT: ${JSON.stringify(event)}`);
  console.log(GRAPHQL_ENDPOINT);

  const endpoint = new URL(GRAPHQL_ENDPOINT);

  const signer = new SignatureV4({
    credentials: defaultProvider(),
    region: AWS_REGION,
    service: 'appsync',
    sha256: Sha256
  });

  const requestToBeSigned = new HttpRequest({
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      host: endpoint.host
    },
    hostname: endpoint.host,
    body: JSON.stringify({ query }),
    path: endpoint.pathname
  });

  const signed = await signer.sign(requestToBeSigned);
  const request = new Request(endpoint, signed);

  let statusCode = 200;
  let body;
  let response;

  try {
    response = await fetch(request);
    body = await response.json();
    if (body.errors) statusCode = 400;
  } catch (error) {
    statusCode = 500;
    body = {
      errors: [
        {
          message: error.message
        }
      ]
    };
  }

  return {
    statusCode,
    //  Uncomment below to enable CORS requests
    // headers: {
    //   "Access-Control-Allow-Origin": "*",
    //   "Access-Control-Allow-Headers": "*"
    // }, 
    body: JSON.stringify(body)
  };
};

CodePudding user response:

WHen invoking an AWS Service from Lambda, you do not need the keys. Instead, you can give the IAM role that the Lambda function runs under the permissions to invoke that service. In your case, give the role permission to invoke app sync.

More information can be found here:

https://docs.aws.amazon.com/lambda/latest/dg/lambda-permissions.html

  • Related