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

Calling a Lambda Function URL secured through IAM_AUTH always returns HTTP 403 Forbidden #1553

Open
Janosch opened this issue Jul 7, 2024 · 0 comments

Comments

@Janosch
Copy link

Janosch commented Jul 7, 2024

I have an AWS Lambda function which I would like to call via a function URL IAM_AUTH. I am struggling to make the request work with aws4-axios. What does work is:

  • A request to a Lambda function URL with authentication NONE
  • A request to a Lambda function URL with authentication IAM_AUTH, using long-term AWS credentials

However, If I use temporary security credentials with IAM_AUTH, I get HTTP 403 and the message The security token included in the request is invalid.

This is how I create the interceptor:

const configureLambdaCredentials = async () => {
        const {credentials} = await fetchAuthSession()
        if (credentials !== undefined) {
            const interceptor = aws4Interceptor({
                options: {
                    region: 'us-east-1',
                    service: 'lambda'
                },
                credentials: {
                    accessKeyId: credentials.accessKeyId,
                    secretAccessKey: credentials.secretAccessKey,
                    sessionToken: credentials.sessionToken
                }
            })
            axios.interceptors.request.use(interceptor)
        }
    }

And this is how I make the request:

const options = {
      method: 'POST',
      url: `${import.meta.env.VITE_API_URL}/prompt`,
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json;charset=UTF-8'
      },
      data: {
          message: prompt,
      }
  };
  const response = await axios(options);
}

At first I thought I am doing something wrong, maybe some sort of misconfiguration. But when I use aws4fetch instead of aws4-axios, it works. This is the code:

async function prompt(userMessage: string, currentMessages: Message[]): Promise<void> {
        const session = await fetchAuthSession();
        const credentials = session?.credentials;

        if (!credentials) {
            throw new Error("Credentials not available");
        }

        const aws = new AwsClient({
            accessKeyId: credentials.accessKeyId,
            secretAccessKey: credentials.secretAccessKey,
            sessionToken: credentials.sessionToken,
            service: "lambda",
            region: "us-east-1"
        })

        const payload = {message: userMessage}
        const timeStart = performance.now();
        const response = await aws.fetch(`${import.meta.env.VITE_API_URL}/prompt`, {
            headers: {'Content-Type': 'application/json'},
            method: 'POST',
            body: JSON.stringify(payload)
        })
}

Attached are the request using aws4-axios that does not work and the request with aws4fetch that does work.

I noticed that aws4-axios signs the headers accept, content-length and content-type which aws4fetch does not sign. But I have no idea if this is the cause of the error.

request-aws4-axios.txt
request-aws4fetch.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant