math
math

Reputation: 2022

Service to service workflow with AWS cognito and AWS Lambda

I'm rather new to AWS Cognito and AWS Lambda. So far I've played around with Serverless and deployed my REST API via AWS Lambda. However, I would like to make my API available for several external parties. As this is service to service, there is no end user directly calling my API. I make the API available for other businesses which use it in their applications. All functionalities exposed via the API are rather simple, meaning they are not invoking any other AWS services like a Dynamo DB etc.

I have several questions, some are rather high-level others are quite specific to the setup of AWS Cognito. I decided to put all in one post as it makes it much more self-contained and easier understandable.

1. Question, Cognito vs API key: What is the advantage of using AWS Cognito vs AWS Lambda in combination with restricting the access via an API key and IP-Whitelisting? Is one much more secure than other?

Let's assume I want to use AWS Cognito. As this is a service to service case, I've read that the standard is to use token endpoints where the grant_type is client_credential. I've found the following on medium. The first few steps consist of

  1. Create a user pool in AWS Cognito.
  2. Create an App client
  3. Add Resource Servers
  4. Enable the client credentials checkbox for Allower OAuth flows

2. Question, App client: Within the added App client I find the corresponding App client id and App client secret. If I expose my API to several different parties, do I need to add for each party another App client? Otherwise they use all the same credentials. Is this the right way to do it?

3. Question, Resource Server: Here I'm completely stuck. What exactly is the meaning for this? At then end, all I want is that my clients can do a post request against my API and access is granted through Cognito. Some clarification what this is for and how this applies in my case would be appreciated. More than happy to share more insights if needed.

The next part is to configure Cognito Authorizer for the API Gateway. This should be fine.

4. Question, client workflow Regarding my clients workflow. Am I correct that this consist of the following steps:

  1. First, I provide to the client his client_id and client_secret.

then the client implements on his side the following workflow:

  1. Whenever he wants to use my API exposed via API Gateway, he first uses his provided client_id and client_secret to retrieve his bearer token.
  2. He uses this bearer token to make a request to API Gateway with the bearer token in the Authorization header.
  3. If access granted, the client retrieves the output of my API.

Is this correct or am I missing anything?

Upvotes: 3

Views: 935

Answers (1)

Yahya Hussein
Yahya Hussein

Reputation: 9121

1-Question, Cognito vs API key

Well as you can see here.

Amazon Cognito user pools let you create customizable authentication and authorization solutions for your REST APIs.

Usage plans let you provide API keys to your customers — and then track and limit usage of your API stages and methods for each API key

So the purpose is different, the API Key is used basically to count a customer usage while AWS Cognito is there to authenticate/authorize calls to your API.

Let us say, you have a requirement that a trail user can't call your API more than 100 times.

Then using AWS Cognito, you will allow a user to sign up, also you will provide the same user with an API Key, you will identify the source of the calls using Cognito and with each call API Gateway will decrease the limit assigned to user's API Key by 1.

And you will have the following cases:

  1. When token (obtained through login using username and password), and API Key are valid, then the call will be successful.
  2. When token is wrong/missing, your caller will get 401 status code.
  3. When API Key is wrong/missing, your caller will get 403 status code.
  4. When API Key is correct but limit is exceeded, your caller will get 429 status code.

2. Question, App client:

Well, client id and client secrets are meant to identify a trusted client (app) rather than a user and each app should have its own client id, so if the caller is an application not a user so yes, create a client id for each separate app. Please be aware that client secrets must be kept confidential so if the caller app can't achieve that, such as single-page Javascript apps or native apps, then the secret shouldn't be issued.

3. Question, Resource Server:

It is your API server.

Check this page.

The resource server is the OAuth 2.0 term for your API server. The resource server handles authenticated requests after the application has obtained an access token.

Large scale deployments may have more than one resource server. Google’s services, for example, have dozens of resource servers, such as the Google Cloud platform, Google Maps, Google Drive, Youtube, Google+, and many others. Each of these resource servers are distinctly separate, but they all share the same authorization server.

4. Question, client workflow

Check Client credentials grant in here

The steps for the process are as follows:

An app makes a POST request to https://AUTH_DOMAIN/oauth2/token, and specifies the following parameters:
    grant_type – Set to “client_credentials” for this grant type.
    client_id – The ID for the desired user pool app client.
    scope – A space-separated list of scopes to request for the generated access token.

In order to indicate that the app is authorized to make the request, the Authorization header for this request is set as “Basic

BASE64(CLIENT_ID:CLIENT_SECRET)“, where BASE64(CLIENT_ID:CLIENT_SECRET) is the base64 representation of the app client ID and app client secret, concatenated with a colon. The Amazon Cognito authorization server returns a JSON object with the following keys: access_token – A valid user pool access token. expires_in – The length of time (in seconds) that the provided access token is valid for. token_type – Set to ” Bearer“.

Note that, for this grant type, an ID token and a refresh token aren’t returned.
The app uses the access token to make requests to an associated resource server.
The resource server validates the received token and, if everything checks out, executes the request from the app.

Upvotes: 2

Related Questions