AWS cognito's documentation suggest all the roles around IAM. How to make meaningful role that my application (resource-server) understands?
I have used AWS Cognito extensively in my applications and I can try helping you here.
Whatever you are saying is possible using Cognito. I believe you are trying to figure one pattern to map your application roles to Cognito/AWS IAM roles.
All Cognito users in the pool can be segregated under different Cognito Groups. documentation is here -> https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-user-groups.html
Each Cognito user group has to be mapped with corresponding IAM Role (permissions you can customize).
Now, these groups need to have one to one mapping with the user role/group in the application.
These groups can be leveraged in 2 different ways. We are considering the design pattern with UI layer (eg:AngularJS) -> AWS APi Gateway -> RestAPI (Lambda/hosted as an application in Beanstalk/container/Ec2/etc.)
The UI controls need to be displayed according to the user group. For example, a super admin will see all the links and menus, full privilege. But for normal end-user, limited links and menus will be visible. In order to achieve this, you can use some of the plugins for AngularJS (may be different in your case) to control the rendering of UI based on group information.
The API layer can be protected by introducing an authorization layer by setting the Authorizer configuration of API Gateway as IAM/Cognito. So before a request hits the API hosted in back-end, API gateway will check whether the requested user group has permission to access the API.
I hope this helps.
Not sure what you mean too much, but roles are for accessing AWS resources. Cognito can be used with an Identity Pool to grant temporary credentials to AWS resources. This means you can put your server/ec2 instance behind an API gateway configured with IAM authentication, and create an authenticated role in your Identity Pool which allows HTTP calls to your API GW.
Related
I am making a web application where a user can get a text (they have to enter) read.
The user doesn't have to identify / login before using the service.
The text is read thank to AWS Polly (with a cognito unauth role called via javascript by the user browser).
I did followed this tutorial:
https://docs.amazonaws.cn/en_us/sdk-for-javascript/v2/developer-guide/getting-started-browser.html
Nonetheless I would like to give a kind of quota to the users.
I am afraid a single user uses the service too many times because I will have to pay for the many AWS Polly requests.
I don't know how to create quotas for each unauth user...
Any idea ?
Shortly, this is impossible.
AWS Cognito controls whether or not a set of credentials is allowed to make a particular API call. The credentials can be time-limited and API calls can be restricted by things like IP address, but it is not possible to limits API calls by quantity. This is true both for authenticated and unauthenticated users.
You can overcome this problem by having users call an API through AWS API Gateway which will trigger your own code on AWS Lambda. The Lambda function then verifies whether to allow the action and then makes the API call on behalf of the client.
Passing through the API Gateway will also allow you to have more control on the user actions (tracking per-user usage, restricting functionalities).
I have a RESTful API being accessed via AWS API Gateway. I want both human users (authenticated via Cognito) AND other (internal) services to be able to call the API. There exists plenty of documentation of how to do either, but not for how to do both.
I have tried using unauthenticated Cognito federated identities to authorize services. I have also used Cognito user pools to authenticate people. However, API Gateway only allows for a single authorizer (in this case, either AWS_IAM or a Cognito authorizer). However, I don't see a way to do both.
I imagine I will need a custom Lambda authorizer, but I'm having a lot of trouble finding accurate information on how to write an authorizer using IAM or Cognito.
Surely we can't be the first people to want to allow both services and humans access to an API. The dearth of documentation on doing so leads me to believe I'm either missing something painfully obvious or that this is a use case that is best avoided (in which case, what IS best practice?).
Is there any way of doing both? Is there a Lambda authorizer example that can point me in the right direction? Is there something built-in that I'm missing?
We have rejected the idea of "pretending" that a Cognito user is a human, when in fact it's actually a service, as it seems to us to be a misuse of Cognito user pools and identity federation. Likewise, the opposite, where a Cognito user is federated to act as an IAM role shared by both users and services, seems like a misuse of user authentication.
Is there a canonical way to do this? If not, is there existing documentation of how to write a custom Lambda authorizer to do both?
The short answer is: you (probably) don't need to use API Gateway for either case.
API Gateway, as the name suggests, is just a gateway. It takes a request (often HTTP) and forwards it to another location (a Lambda function, an EC2 instance, another AWS service, or another HTTP endpoint). This is great if you need users who do not have an associated IAM role to access AWS services.
Users who are authenticated through Cognito have an associated IAM role through the associated Cognito Identity Pool. Just give them access to the AWS services this way, no need to go through API Gateway.
AWS services that need access to other AWS services don't need to go through API Gateway, they need to be given permission through their IAM role.
If for some reason you must use API Gateway for both your users and your services, make two API Gateways that point to the same resources that use different authentication methods.
I'm quite new to AWS and I try to understand some basic concepts. In my Android app, I use:
Cognito User Pool and Identity Pool to allow my users to register and sign in, but also to use the app as guest users
API Gateway and AWS Lambda to create webservices that the app can call
My use case is very simple: I want some of the APIs I created in API Gateway to be available for my authenticated users and my guest users, and the other APIs available for my authenticated users only.
For the APIs available for my authenticated users only, I was thinking putting the users in a group of users (thanks to CognitoIdentityServiceProvider.adminAddUserToGroup()), that can have a common role with an IAM strategy attached to it, to allow them to access those APIs. I think it makes sense since I'll have different types of users, so I'll use a group for each type.
But for the APIs available for my authenticated users and my guest users, I'm note quite sure of what I'm supposed to do. Should the APIs be public, so they can be called by anyone including my guest users, or is it possible to make them only available for my authenticated users and my guest users, but without being public? What are the good practices and how can I achieve them?
Thanks for your help.
You should use "API Gateway Lambda Authorizers" for this. You configure the authorizer per method. So, only the endpoints reserved for authenticated users should have one set.
How do they work?
Every time a request hits an endpoint with an Authorizer configured, API Gateway will trigger it with the request information. The authorizer then checks if the request have the proper credentials. If it does, then an IAM policy is returned. The method execution call (another Lambda function for example) will consume this policy. Otherwise, the authorizer will return an error status code, say a 403 Access Denied.
In your case, since you are using Cognito, you can use a Cognito User Pool Authorizer. You can create it using Cognito's SDK or AWS cli. After you configure it the only thing you have to do is append the id or access token provided by Cognito after a user authenticates. It's usually served inside the Authorization header.
I hope it helps.
Here is how I did, using the console:
In API Gateway, click on the resource, then the method (GET, POST...)
Click on Method Request
For Authorization, choose AWS_IAM
In Cognito, choose Manage Identity Pools
Create (or edit) the identity pool you use with your Cognito User Pool
In the Unauthenticated identities block, check Enable access to unauthenticated identities
On the same page (at least if you edit the identity pool), you should also see the Authenticated role and the Unauthenticated role
Go to IAM, and in Roles, find those two roles
For each role, click on it, and in the Permissions tab, click on the policy attached to that role to view it (with the little arrow on the left)
Click on Edit policy, then the JSON tab, then add the following block (you can find the ARN by going to API Gateway, click on your API, click on your resource, click on your method: you'll find the ARN in the Method request block):
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": "<the_arn_of_your_resource_api>"
}
Click on Review policy, then Save changes
We're building an application using AWS App Sync, we're still in a very early stage.
Our application has a restricted area, through user sign-in, which is being managed via aws cognito users pool. And this is fine.
We're having issues on the public area which doesn't require any authentication.
How can we protect these public endpoints?
We're having some doubts about hard coding the api key (that we know can be rotated), is it a good practice (documentation page says that it isn't ideal for production)?
Is there any way to authorise the origin? (aka, any request coming from www.foobar.baz is ok)
I would suggest using Amazon Cognito Federated Identity to control authenticated and unauthenticated access to the api. In order to do use Amazon Cognito Federated Identity with AWS AppSync, you need to use AWS IAM based authorization.
For the authenticated access you can use Amazon Cognito User Pools and federated to Amazon Cognito Federated Identity and since the federated identity can also allow for unauthenticated users it will allow you to control some api's which can be made public via an IAM policy.
For more information please read the AWS IAM Section of our security guide here
Under your AppSync app's Settings menu, where you set the User Pool Configuration, there is an option to set a default action. You can change this to DENY and all unauthenticated requests will be rejected. The alternative approach is to ALLOW everything, and manually add #aws_auth directives to every query/mutation/subscription field that you care about restricting.
I have set up a cognito user pool and have attached this to an identity pool. I wanted to allow only valid users from my user pool to execute my aws api. I have been reading about authorizing my api but there seems to be a number of ways to do this as follows:
Using an IAM role that I can attached to my authorized identity role
Using a custom authorizer in the aws api gateway
Based on what I want to do above, is there a recommended way to implement the api authorization?
Thanks in advance.
If the API you are calling, uses the user data, I would go with 2. If not, 1 would work as well. However, why do you want to integrate with an identity pool unless supporting federation with Google, Facebook etc.
http://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html