AWS Cognito vs IAM role in Android APP for security aspects - android

An app of mine in the android playstore (let's say >1.000.000 installs) collect some anonymous statistics. I want to store and work with these statistics on an amazon EMR cluster.
Currently I use AWS Cognito for creating Unauthorized access for Uploading the data to S3/Firehose. For saving money I thought of changing this procedure to use a hardcoded IAM user, which only able to upload the data to FH/S3. I don't need the identification of each user.
What disadvantages should I expect in terms of security?

Cognito federated identities is 100% free. Switching to an IAM user won't save you money.
Per the pricing page: "Using the Federated Identities feature for authenticating users and generating unique identifiers is always free with Amazon Cognito."

I think if they somehow get access to your sourcecode they can upload data to s3/firehose . Actually I am in the same kind of dilema only I dont have an app on appstore yet but since the IAM i am using only has read access to a AWS service I dont really see issue with it. because If I am correct AWs does charge for every token refresh after 50.000 MAU if you use Cognito

Related

Kotlin and AWS Lambda: How to implement secure authentication like OAUTH2

This is a question of architecture. What I tried yet: Research, research, research.
I want to deploy various microservices with AWS Lambda. These should be accessible for authenticated users via Web and Android App.
Question 1: How to securely store AWS Gateway API keys (secrets) in an Android Kotlin / Webview app? Is Android Keystore the right (secure) answer?
Question 2: What's the best, secure way to make user login happen? Should the login be located at Lambda or inside the app? Again, how to securely store login data on Android? Could a cookie-based Web-Authentication be the answer (aka "Keep me logged in")?
The goal / my issue is that I want the Android App user to enter his / her login data only once in the App and never be asked again for login at my Lambda Microservices. I'm aware that API Credentials and Login are two different problems here.
Example projects maybe?
This is not for critical data like banking, but still I want to follow best practices as much as I can in terms of sec.
I am not sure whether you have researched on Amazon Cognito or not but it can be used to provide authentication for both user interfaces and for APIs. It can easily be integrated with Lambda/API gateway.
As an alternative to using IAM roles and policies or Lambda
authorizers (formerly known as custom authorizers), you can use an
Amazon Cognito user pool to control who can access your API in Amazon
API Gateway.
Further reading :
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
If it helps I have some cloud demo sample UIs that connect to lambdas and use Cognito. You can run them starting here: https://authguidance.com/home/code-samples-quickstart/
The blog has some write ups on how it all fits together - see the index page for further details - there is a post on UI token storage for example.
Long lasting sessions can be managed via refresh tokens - but your apps should still deal with token and session expiry - and scenarios such as logging on as a different user for testing.

How to grant access to android app users for AWS S3 Objects?

I have a bucket in Amazon S3 and I have Lambda functions that generates JSON files for this bucket. I am using the S3 files in my mobile app. Until recently, I gave public access to these S3 files for simplicity. But now I want these S3 objects to be accessible with a simple authentication. I’ve examined all AWS tutorials but couldn’t find an easy way to implement this. I don’t want to use Cognito service since my app doesn’t need authentication and since my S3 files are not user-related, they are used for app. I want these S3 objects to be accessible by http request to a url which includes simple key like this:
https://s3.eu-central-1.amazonaws.com/<bucket name>/<object name>?<key>
where key can be a combination of region, aws access key, secret access key or other values of the user that i define (I am using Retrofit to fetch json data from S3 bucket) I’ve looked at the presigned url option but an example for android-sdk doesn’t exists there, and most of the methods that can be used for this purpose are deprecated. Isn’t there an easy way for this? Or should I host my json files in other service/place?
If you say no to Cognito then you are just complicating things for yourself. This is exactly the case where you want to use Cognito. The fact that you don't require your users to authenticate and that the S3 content is not user specific doesn't mean that Cognito is not suitable in this scenario.
All you have to do is to create Cognito identity pool and choose to support unauthenticated entities. Create an IAM policy that allows reading from that specific S3 bucket and let unauthenticated users to assume that IAM role by attaching it to those unauthenticated entities.
Authentication then happens automatically during the initialization of SDK in your application. That is all that you need to do to allow access to that S3 bucket only from your application.
And you get access metrics even for unauthenticated users as a bonus. And if you later decide that you want your application to support authentication as well, then you don't need to change almost anything in your setup.

Authenticate with web server before uploading/downloading file to AWS S3

I want to create an android application and use AWS s3 as a storage service to allow the user to upload and download files. I have studied something about S3 REST service, which can help me achieve the same, after configuration of IAM Role for Bucket etc.
Now thing is, I want only the registered users of my application/ with access control configured at my web server(username/password) should be allowed to upload/download the file and not anyone with only app access should be allowed.
Look the link below as well, to have some idea about AWS S3 upload file using REST
http://www.tothenew.com/blog/file-upload-on-amazon-s3-server-via-rest-api-call/
Putting simply, in addition to that described in the link above, I just need the answer to the following questions:
1) How to allow only registered users?
2) Is it good practice to hard code AWS S3 secretKey etc in the production application.
3) Does hardcoding these values in my app could lead to a scenario where even an unregistered user of my application could be able to upload/download the file to aws s3?
All suggestions are welcome, if-if they solve part of the puzzle, as I am completely unaware of the solution
It would be very helpful...,
Thanks in advance,
For sure it is not best practice to hard code secret keys inside your codes..
Now if you want to separate the authorized and the unauthorized users one AW services that does this job and more is AWS Cognito . You can find a lot in the aws documentation https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-console.html
A few things for Cognito :
You have Amazon Cognito User Pools tha provides :
Sign-up and sign-in services.
A built-in, customizable web UI to sign in users.
Social sign-in with Facebook, Google, and Login with Amazon, as well as sign-in with SAML identity providers from your user
pool.
User directory management and user profiles.
Security features such as multi-factor authentication (MFA), checks for compromised credentials, account takeover
protection, and phone and email verification.
You have Amazon Cognito Identity Pools (Federated Identities) that provides :
Users in an Amazon Cognito user pool
Users who authenticate with external identity providers such as
Facebook, Google, or a SAML-based identity provider
Users authenticated via your own existing authentication process
This how it works in my application
Ask user register/login using aws cognito
deploy an api via api gateway that acts as proxy for S3 services
For the api , apply AWS cognito as Authorizer in api gateway
This however has a limitation on size of object
The option I have tried is use signed urls, and this is spit out by back end application upon registered users access requests.
My implementation includes below
1. Client requests signed urls using an api with a lambda implementation
2. Lambda generates signed urls and passes on the response.
3. while creating signed urls, key/id are used from a parameter store (see EC2 parameter store) secured against role and with a KEY.
I think from your use case , EC2 parameter store (instead of database) should be sufficient to securely keep secretes.

Typical app user authentication using AWS

My main question is what is the typical way mobile apps authenticate users? I know that AmazonCognito is used to sync userdata once you receive a token, but that token is simply a set of access rules, right? Which has nothing to do with a particular user (just the fact that they are an authenticated user in general).
But before even that, there needs to be a way to authenticate a username/pass that the user signed up for so that you can retrieve the token. In almost all of the documentation, they use Facebook/Google/etc as examples of third party providers, and there IS an example of setting up your own 3rd party provider, but this all requires your own backend to service that. C
onsidering that there may be many users trying to user the app and authenticate, does it not seem like a bad idea to set up a backend somewhere else? And is there a way to integrate this part into AWS as well so that there is no custom backend work? How is this typically done?
Site node: I'm using Android SDK at the moment.
Thanks :)
AWS Cognito has two different purposes. One is to synchronize data as you described in your question.
The other one is to help to manage user identities and create the glue between external Identity Providers (your own, Facebook, Google or Amazon) and AWS.
Here is the workflow at high level. Details are available at http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html
Using AWS Console, create a Cognito Identity Pool
Associate two IAM Policies to your Cognito Identity Pool. One for the unauthenticated users and one for authenticated users. Best practices is to grant least privileges to both category of users. The AWS Console will help you to go through these steps and will propose reasonable default values.
In your code, initialize your CognitoCredentialsProvider object as this
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
myActivity.getContext(), // get the context for the current activity
"AWS_ACCOUNT_ID",
"COGNITO_IDENTITY_POOL",
"arn:aws:iam::AWS_ACCOUNT_ID:role/UNAUTHENTICATED_ROLE",
"arn:aws:iam::AWS_ACCOUNT_ID:role/AUTHENTICATED_ROLE",
Regions.US_EAST_1
);
In your code, proceed as usual to authenticate your users (using your own provider or Facebook, Google or Amazon)
When you will receive the token issued by the Identity Provider, associate it to Cognito. The Cognito SDK will transparently trade this token for a temporary AWS Access Key, Secret Key that service clients can use.
Give the credentials provider to your service client object, such as
AmazonDynamoDB client = new AmazonDynamoDBClient(credentialsProvider);
This approach allows you to avoid to deploy your own backend as broker to AWS services. Most service calls can be made directly from the mobile app, allowing a good level of scalability at a low cost.
Backend of your own is only required to offload some computing task of your mobile devices or if you want to implement your own Identity provider and make it interact with Cognito (see detailed workflow at http://mobile.awsblog.com/post/Tx2FL1QAPDE0UAH/Understanding-Amazon-Cognito-Authentication-Part-2-Developer-Authenticated-Ident)

Is amazon simpleDB suitable service for checking an android app's trial status?

I have an android application and it has a trial version. I want to store users' imei numbers and installation dates on serverside and than check everytime when user uses this app to know if trial version is expired. Since i am not experienced on server side programming i was hoping this kind of cloud service would solve my problem. Before i jump into it i would like to be sure if simpleDB is suitable service for me and if not could you suggest another solution ?
The primary issue is securely storing the access credentials. To access the SimpleDB service without an intermediate server, you'll need to store the access credentials in your Android app. These are accessible with very little skill (text editor?) and could potentially allow unauthorised access to you Amazon Web Services account.
For a while there have been some options for creating extra credentials with varying access levels (eg. read-only) but I've yet to explore this myself.
UPDATE
Amazon have updated their Android libraries with improved credential management. This answer for anonymous, read-only access describes in more detail how to use AWS Identity & Access Management.

Categories

Resources