API Gateway Overview
With AWS API Gateway, you can run a fully managed REST API that integrates with AWS Lambda functions to execute business logic. API Gateway provides benefits such as:
- Traffic management
- Authorization & authentication
- Monitoring & logging
- API versioning
Within your system, you are likely to have APIs with different levels of access. The following section lists the different types of APIs.
Public / Unauthenticated APIs
APIs that can be consumed by any user, such as endpoints for returning a landing page which is publicly accessible and does not require users to be authenticated.
Authenticated User APIs
APIs that require users to be authenticated. Such APIs will typically involve updating system state on the user's behalf. For example, An API that is used to submit a vote in an online voting system.
Internal APIs are meant to be used by the system itself and are not intended to be consumed by client applications directly in the micro services architecture. Such APIs are often used to encapsulate and manage a set of shared ressources. For example, shared resource data that many parts of the system would need to access in a micro service architecture.
Internal APIs are often very powerful and can be used to update or even delete system state so they must be well protected.
Using API Gateway
Typically (in a non-serverless application) you would restrict access to internal APIs by using a combination of private VPCs coupled with authorization. However, when you use an API Gateway, you lose the ability of creating network boundaries with private VPCs.
Having said that, API Gateway provides efficient access control mechanisms, which are implemented at the API gateway level. One of the ways to secure APIs with API gateway is to use API keys.
Controlling Access to APIs
There are multiple controls in place which can be used to control access to APIs - the most common ones are:
- Usage plans using API keys granted to users with usage quota limiting
- AWS IAM roles and policies
- Amazon Cognito user pools
- Lambda authorizer functions for controlling access to API methods using token authentication as well as header data, URL paths, query string parameters, stage variables, or context variables request parameters
API keys are string tokens that you provide to client application developers to grant access to your APIs. You can use API keys together with usage plans or Lambda authorizers to control access to your APIs. API Gateway can generate API keys on your behalf, or you can import them from a CSV file.
You can find more information on how to set-up API keys for use with API Gateway in the following link.
A usage plan declares who can access one or more deployed APIs (including stages and methods), and also define the volume/frequency they can access them. The plan uses API keys to identify clients and measures access to the associated API stages for each key.
For example we might allow prospective customers to try our API during a trial period. In that case, we will limit them to a maximum of one request per second, with a request burst of up to five requests per second. At the same time, we will limit such customers to a total of no more than 10 requests per day.
More information on how to set-up usage plans can be found in the following link.
Controlling Access to APIs With AWS IAM
If you need to grant employees access to internal APIs, you would probably do so by using the AWS IAM authentication, rather than by using API keys.
To allow an API caller to invoke an API, you must first create an IAM policy that permit a specified API caller to invoke the API method for which the IAM user authentication is enabled. You can set this by configuring the method's 'authorizationType' property to AWS_IAM, which will require that the caller will submit the IAM user's access keys in order to be authenticated. After setting the configuration to use the AWS IAM authentication, you will need to attach the policy to an IAM user representing the API caller, to an IAM group containing the user, or to an IAM role assumed by the user.
Many developers make the mistake of implementing their own authentication systems. Such systems are a good example of 'heavy lifting' work that is neither core to you business, nor something that's easy to implement correctly. In fact, many data breaches in the past were a direct result of custom built authentication systems which were poorly designed or implemented.
It is highly recommended to always prefer using an authentication service such as Amazon Cognito, Auth0 or similar. Such services remove the burden of implementing robust authentication systems, and allow you to focus your development efforts and energy on your business logic.
Amazon Cognito provides authentication, authorization, and user management for your applications. End users can sign-in with a username and password, or by using a third party web service such as Google, Facebook or Amazon.
Amazon Cognito User Pools
Cognito user pools is a managed identity service that manages everything related to user sign-up and sign-in. It implements all common user management flows out of the box, as well as a host of leading best-practices including multi-factor authentication (MFA) and server side data encryption. The service stores passwords using the Secure Remote Password protocol (SRP) so that passwords never need to travel over the wire and are therefore resistant to several relevant attack vectors.
You can allow users to access your APIs through API Gateway by authenticating them with Amazon Cognito User Pools. In such a configuration, API Gateway will validate the tokens from a successful user pool authentication, and will use them to grant your users access to resources including Lambda functions, or your APIs.
AWS Lambda Custom Authorizers
A Lambda authorizer is a serverless function that you create to authorize access to your APIs. A Lambda authorizer uses bearer token authentication, such as SAML or OAuth. It can also use information described by HTTP headers, URL path, Query string parameters, and so forth.
When an API is called by a client, and API Gateway is configured to use a Lambda authorizer, it will invoke the relevant Lambda function. During the invocation, API Gateway will pass the authorization token that is extracted from a specified request header for the token-based authorizer, or it will pass the incoming request parameters as the input to the authorizer function.
If you found this interesting, check out our deep dive tutorial on how to build an authentication system with CloudFormation custom resources.