Making API Calls From Lambdas

FusionAuth Reactor logo

This feature is only available in an Essentials or Enterprise plan. Please visit our pricing page to learn more.

Overview

Lambda HTTP Connect allows you to make HTTP requests from within a lambda. Any lambda can make a request to any network accessible URL.

This features allows you to access data from external systems to configure token claims or to add data to a user profile. It also allows you to push profile or other data from FusionAuth to an external system as needed.

Here’s a video showing more details about Lambda HTTP Connect:

Example Lambda

Here is a FusionAuth lambda that adds additional claims to a JWT based on an HTTP request:

A lambda which adds claims based on an external API.

function populate(jwt, user, registration) {
  var response = fetch("https://api.example.com/api/status?" + user.id, {
    method: "GET",
    headers: {
      "Content-Type": "application/json"
    }
  });

  if (response.status === 200) {
    // assuming successful response looks like:
    // {"status":"statusValue"}
    var jsonResponse = JSON.parse(response.body);
    jwt.status = jsonResponse.status;
  } else {
    jwt.status = "basic";
  }
}

You can also call FusionAuth APIs with a valid API key:

A lambda which adds claims based on a FusionAuth API.

function populate(jwt, user, registration) {
  var response = fetch("http://localhost:9012/api/group", {
    method: "GET",
    headers: {
      "Authorization": "bf69486b-4733-4470-a592-f1bfce7af580"
    }
  });

  if (response.status === 200) {
    // a successful response as defined in the Groups API
    var jsonResponse = JSON.parse(response.body);
    jwt.groups = jsonResponse.groups;
  } else {
    jwt.groups = [];
  }
}

Use port 9012, or the configured value for fusionauth-app.http-local.port, whenever making a FusionAuth API call in a lambda. Doing so minimizes network traffic contention and improves performance.

Headers

You can provide request header values in a number of different ways:

An anonymous object

headers: {
  "Content-Type": "application/json"
}

A hash or map

headers: new Headers({
   "Content-Type": "application/json"
})

An array

headers: new Headers([
    ["Content-Type", "application/json"]
])

Response

A response object will be returned. It will have the following fields:

headersObject

The headers returned by the response. The keys of this object are the header names. All header keys are lower cased.

statusInteger

The HTTP status code.

bodyString

The body of the response.

Securing API Keys In Lambdas

Being able to make API requests against FusionAuth can be useful, but requires an API key to be stored in the Lambda code.

To secure that API key, you should:

  • scope your API keys as narrowly as possible (both in terms of tenants and permissions)
  • create a unique API key for each lambda to make revocation easy
  • limit who has access to view lambda code to limit who can see API keys
  • rotate API keys regularly

There’s an open GitHub issue which discusses product improvements to API key handling.

Lambda HTTP Connect Limitations

When using Lambda HTTP Connect to make HTTP requests, do not call a FusionAuth API which invokes the calling lambda, because it will fail. For example, in a JWT Populate lambda, do not invoke the Login API.

Requests from a lambda require the lambda to use the GraalJS engine.

HTTP requests will time out after two seconds.

The fetch method in a lambda does not implement the entire fetch API as implemented in a browser. The first argument to fetch must always be a string URL. Only the following options are supported:

  • method, which defaults to GET
  • headers, which defaults to null
  • body, which must be a string