App Sync - Protecting Api for non authenticated users - amazon-web-services

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.

Related

AWS cognito authorization

I have an application (node.js) that need an Authentication and authorization.
My app need access to postgres database and also need a Inheritances (roles etc.)
One option to implement that is using the cognito service of aws (the app will host on aws properly - not sure about that)
so the questions is
Is cognito service support the authorization for node.js with database that is not services on aws? (I read that "identity pool" is for aws services like mariaDB)
If my app will be on heroku (not on aws), I will also be able to use with cognito services (for authorization)?
Is cognito support roles/users inheritances ?
Tnx
Cognito identity pool is used for granting access to aws services. User pool is used to exchange user credentials for tokens which can contain additional information about the user once decoded. So yes, you can use user pool just for authentication. Your user attributes can contain information related to the services this user needs to access.
However, if you plan on storing database credentials, I suggest you use AWS secrets manager to store your DB credentials and grant the cognito user access to this secret. You'll need to use both user pool and identity pool in this case.
Not directly, but you can use it to access secrets manager where you db credentials are stored.
Yes you can use cognito anywhere. It will be connecting to AWS to grant you tokens however. And these tokens are only recognized on AWS. Which is why you need to use them to access other secrets that can be used to access whatever other services you want.
Cognito supports groups. I'm not sure if that's what you mean by inheritences. You can have token based roles with groups.

AWS cognito custom user roles for authorization

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.

Is AWS Federated Identities necessary if the only AWS resource a user interacts with is API Gateway?

I am currently investigating the use of Federated Identities and from the many examples I have read, it seems to be a way to grant users temporary credentials to various AWS services. For my case, the API Gateway is all that the user will interact with, since the API server is the one making calls to other services like S3 and DynamoDB. I like how permissions are controlled using IAM, but I'm failing to see any other appeals of Federated Identities. User Pools itself already supports password/fb/google/etc sign in, the only downside I see with user pools is that I'll need to do the authorization manually in the API layer. Is there something else I am missing with Federated Identities? Is it worth it given my use of only API Gateways (externally).
It all depends on the way that you will secure your API Gateway endpoint.
If you secure your API using AWS IAM, you'll need a way to convert your authentication tokens in AWS IAM Roles. For that scenario you can use AWS Cognito Idp (not the User Pool) or AWS Federated Identities. The difference is: using AWS IAM Federated Identities you will need to call AWS STS AssumeRoleWithWebIdentity in your frontend code. If you use AWS Cognito Idp this is done for you. . (AWS strongly suggest that you use the Cognito Idp in that scenario)
If you secure your API using AWS Cognito User Pools you don't need to use AWS Federated Identities. You can connect API Gateway directly to AWS Cognito and the service will enforce the controls for you. In that case you'll need to have a Cognito User Pool.
You also have a choice to use Custom Authorizers. In that scenario you will implement a lambda function that will evaluate your request and decide if it is authorized or not. In the same way, you won't need federated identities.
And finally you have the API Key authorization, that you already mentioned that is not applicable to your use case.

With AWS Amplify Auth and GraphQL API, how would you have some public, and some private query/mutation calls?

Setup:
AWS Amplify API w/ GraphQL
AWS Amplify Auth w/ Cognito User Pools
Say the majority of the platform should be accessible by a logged out user. E.g. they should be able to read forum Topics, but if they want to post, they need to sign in.
I see an #auth resolver that I can use, but whenever I try to make a graphQL call to my.url.amazonawscom/graphql to fetch Topics, it says "errorType": "UnauthorizedException". I'm having trouble figuring out how a logged out user can have authorization to publicly accessible data.
AWS AppSync recently launched support for multiple authorization types on the same AppSync API. So you could for example enable cognito user pools as the authorization type on your API and add API_KEY as an additional authorization provider.
After this, you would be able to use the #aws_api_key directive to make selected fields from your schema such as for example getForumTopics be api key authenticated. API Keys are in general considered to give public access.
Also Cognito User Pools and Cognito Federated Identities are separate products. Cognito Federated Identities does indeed have an unauthenticated identity role that you can use to secure top level fields in your schema but it looks like the auth type on your API is set to Cognito User Pools.
In Cognito identity pool you need to set the policy for unauthorized users. Go to Edit Identity Pool and you can see an option where role can be set for unauthorized

How a mobile app should authenticate to AWS

I'm developing a mobile app that must access some AWS resources, so it needs authentication to AWS endpoint. The app doesn't manage users (sign-in, sign-out, register and so on).
My first solution was to create a IAM user dedicated to the mobile app and embed its credentials in the mobile app code. The app authenticate itself to AWS using the embedded credentials. It works, however AWS suggests to avoid embedding credentials directly in the app.
I think a better solution is Cognito. Because I don't need users management, I should use unauthenticated (guest) identity to request temporary AWS credentials.
However I don't understand why a guest Cognito identity is more secure than an embedded credentials. The mobile app receive a temporary AWS credentials by sending a Cognito Identity Pool ID, that is a long-term "number" embedded in the mobile app. If someone is able to find this Identity Pool ID, she can receive AWS credentials and access AWS resources as my official mobile app. It seems there's no difference between embedded AWS long-term credentials and huest Cognito access.
Why Cognito solution is better than embedded AWS credentials?
If you are creating unauthenticated access using identity pool, you are allowing public to access your AWS resources. Make sure you write your policy carefully and it won't matter if you use a single IAM user or cognito unauthenticated access as far as security is concerned.
Using federated identity will provide you benefits like getting statistics on usage and adding triggers to events. Also keep in mind that creating a single IAM user and then allowing multiple people to use these credentials is a "hack" way of doing what cognito federated unauthenticated idenity was designed to do. You might run into unexpected complications later if AWS decides to throttle this behavior of IAM.