Josh Matthews
Josh Matthews

Reputation: 23

Securing access to AWS Lambda through API Gateway

I am creating simple REST API using AWS Lambda and API Gateway. This API will be used by external services (scripts), but I want to secure access to the API so it won't be accessible publicly. Also I want to restrict some services from accessing parts of the API and be able to revoke their permissions at any time.

API example:

External scripts:

I think I need to create some kind of users for my scripts and use them for accessing API. I was thinking of using Cognito but I am no longer sure if this kind of setup is possible.

Do you have any ideas? Do I have to create my own authorizer on API Gateway?

Upvotes: 1

Views: 388

Answers (1)

For this you can use either Custom Authorizer or AWS Cognito user pools.

If you are going ahead with custom authorizer, you can create a lambda function to do the authorization part. A sample code from AWS documentation is like follows

console.log('Loading function');

exports.handler =  (event, context, callback) => {
    var token = event.authorizationToken;
    // Call oauth provider, crack jwt token, etc.
    // In this example, the token is treated as the status for simplicity.

    switch (token.toLowerCase()) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); 
    }
};

var generatePolicy = function(principalId, effect, resource) {
    var authResponse = {};

    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }

    // Can optionally return a context object of your choosing.
    authResponse.context = {};
    authResponse.context.stringKey = "stringval";
    authResponse.context.numberKey = 123;
    authResponse.context.booleanKey = true;
    return authResponse;
}

You can read more and how to implement custom authorizers using this link.

If you are using User pools, you can integrate API with user pool. You can follow the steps defined in this documentation to do the integration. Quoting from the site,

To create a user pool authorizer using the API Gateway console

  • Create a new API or select an existing API in API Gateway.
  • From the main navigation pane, choose Authorizers under the specified API.
  • Under Authorizers, choose Create and then choose Cognito User Pool Authorizer.

To configure this authorizer:

  • Choose a region for Cognito region.
  • For Cognito User Pool, choose an available user pool.
  • The Authorizer name field will be automatically populated with the chosen user pool name. However, you can customize it if you want to.
  • The Identity token source field will be set to method.request.header.Authorization by default. However, you can customize it if you want to. Using the default, Authorization will be the name of the incoming request header to contain an API caller's identity token.
  • Optionally, type a regular expression in the App client ID regex field to validate client IDs associated with the user pool.
  • Choose Create to finish integrating the user pool with the API.
  • Having created the authorizer, you can, optionally, test it by supplying an identity token provisioned from the user pool.

To enable a user pool authorizer on methods

  • Choose (or create) a method of your API.
  • Choose Method Request.
  • Under Authorization Settings, choose the edit icon by the Authorization field.
  • Choose one of the available Amazon Cognito User Pool authorizers from the drop-down list.
  • Choose the check-mark icon to save the settings.

Repeat these steps for other methods of your choosing.

[Update] Updating the answer with Ashan's suggested methodology.

Another option is to use Cognito user groups with IAM authorization at API gateway. Access permission can be given through policies which are assigned to roles linked with groups.

Upvotes: 1

Related Questions