Get current AWS Cognito identity id from supplied credentials - amazon-web-services

I have an iOS app that is authenticating using Facebook & Cognito. I am able to make calls to a local ReST service with the following AWS credentials from my iOS app extracted from Cognito:
accessToken: {a_token}
secretToken: {a_token}
sessionToken: {a_token}
I want to get the current Cognito identity from the AWS credentials so I can use that as a key in my DynamoDB table and handle authorization (I don't want to use IAM roles for this). I know I can directly invoke DynamoDB from the iOS app but I do not want my app directly calling my data storage (in case I want to change data storage, add caching, etc...). Is it possible to get the current Cognito identity from the current AWS credentials?
I do not want to pass the identity id with the request, as is defeats the purpose of passing the tokens.
I do not want to use AWS API Gateway either.

From your credentialsProvider you can call getIdentityId() and in continueWithBlock' you can accesscredentialsProvider.identityId`

I am sorry but there is no way to get an identity id from AWS credentials.
Is there a reason you do not want to call Amazon DynamoDB from the device directly using credentials vended by Cognito Identity? Using IAM roles you can restrict the usage for an identity to be able to write to only their records and this is the approach we recommend currently.
You can refer to our blog about fine grain access with DynamoDB using Cognito.

Related

A lambda function trigger on deleting a AWS cognito user

I'm very new to AWS cognito. I want to send a mail on deleting a user from AWS cognito user pool. I learnt that there is a list of predefined event trigger sources for various user actions such as sign up, sign in, password change etc., but, there is no such event trigger sources for deleting a user. I found few similar questions posted and saw that using cognito sync trigger was recommended and when I tried to follow that, it asked me to select a cognito identity pool to proceed further but there is no identity pool used in my project.
Kindly let me know how can I trigger a lambda function on deleting a cognito user.
Identity pools are used for giving temporary access to you AWS Resources/Services, you can refer the docs
Amazon Cognito identity pools (federated identities) enable you to create unique identities for your users and federate them with identity providers. With an identity pool, you can obtain temporary, limited-privilege AWS credentials to access other AWS services.
Since your backend is not using any AWS resource, you can use AWS API Gateway for creating an endpoint which can be hit to trigger the lambda function, as Auth provider of the api you can use cognito. Here is the reference

How to avoid hard coding access key and security key values aws

In my js file, I am accessing my AWS sns, but the main issue is that currently, I am hard coding my IAM access and security keys... Is there a way to avoid doing this by using a temporary key or hiding my keys? I have posted a snippet on how I am updating the config below.
var AWS = require('aws-sdk');
AWS.config.update({
region: < 'My Hard coded region' >,
credentials: {
accessKeyId: < 'My Hard coded Access Key' >,
secretAccessKey: <'My Hard Coded Security Key'>
}
});
...
PLEASE HELP.
It's very hard to comment without knowing more about your code.
The react native is a mobile app. You will need a service to authenticate your mobile app users against the service. One such service is amazon Cognito.
Userpool
Amazon Cognito has a concept called user pool. The user pool is where the users are stored.
When you authenticate a user against a user pool, you will get a authorised token in return. Your app can store this token and send it to your backend services. The backend services can validate the token to confirm the identity of the user.
Identity pool
The identity pool is a concept where temporary AWS credentials are issued in exchange for an authorised token. This is the temporary AWS credentials, using which you can call aws services directly from the mobile app.
Hope this helps.
here is an article for you to read - https://pusher.com/tutorials/serverless-react-native-aws-amplify
Yes there are much more secure ways to handle credentials. Hard coding them is the least secure.
While it is possible to do so, we do not recommend hard-coding your AWS credentials in your application. Hard-coding credentials poses a risk of exposing your access key ID and secret access key
See https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html
Also see From Best Practices for Managing AWS Access Keys:
Don't embed access keys directly into code. The AWS SDKs and the AWS Command Line Tools allow you to put access keys in known locations so that you do not have to keep them in code.
See https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html
The most secure method is to load the credentials from AWS Identity and Access Management (IAM) roles for Amazon EC2.
Each SDK has a way to do this. Check your SDK documentation for loading credentials from IAM.
Here is a good overview for credentials best practices, with examples in Java: https://aws.amazon.com/blogs/developer/credentials-best-practices/
I came across this stackoverflow while googling how to solve this problem. Here's the approach I ended up using to solve this problem in case this helps anyone else. It will expand on the identity pool answer provided earlier.
My setup was this:
Static website hosted on s3, so no way to make AJAX calls back to the server itself to bypass hardcoding credentials.
The solution I ended up using was Cognito identity pools as mentioned. The setup involved creating an identity provider in IAM. We were using an company internal OpenID identity provider. Then the next step was to create an identity pool in cognito that pointed to that identity provider. Next was to provision an IAM role for signed in users of that identity pool to give them access to whatever resources you are trying to secure.
On the s3 website, we had already integrated with the internal OpenID identity provider, so it was just a matter of extracting the token and passing it to Cognito.
The program flow is as follows:
User logs in to open ID internal system.
This system returns a token
Code extracts token and then creates a Cognito Identity Credentials
https://docs.aws.amazon.com/cognito/latest/developerguide/getting-credentials.html
The below is a code snippet copy pasted from the docs linked above. Note that the Logins object is where we will pass the token. The key will be the "provider" field value configured in IAM.
AWS.config.region = 'us-east-1';
// Configure the credentials provider to use your identity pool
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'IDENTITY_POOL_ID',
Logins: { // optional tokens, used for authenticated login
'graph.facebook.com': 'FBTOKEN',
'www.amazon.com': 'AMAZONTOKEN',
'accounts.google.com': 'GOOGLETOKEN',
'appleid.apple.com': 'APPLETOKEN'
}
});
// Make the call to obtain credentials
AWS.config.credentials.get(function(){
// Credentials will be available when this function is called.
var accessKeyId = AWS.config.credentials.accessKeyId;
var secretAccessKey = AWS.config.credentials.secretAccessKey;
var sessionToken = AWS.config.credentials.sessionToken;
});
The call to cognito will return temporary credentials including a session token, which you can now pass to your other aws clients.

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.

Forward claims from external provider to Cognito Identity

I have an app and openid identity server. My app retrieves tokens from the Identity server.
I have also configured the identity server as an external provider for an AWS Cognito Identity Pool.
I can successfully retrieve AWS credentials for the User logged into my app.
However, I find the AWS credentials limited as the token does not contain any of the claims from the original login token. Is there any way to get them in there?
One the claims I use is clientID and I was hoping to be able to use that in a an IAM Policy to restrict S3 access by client.
I haven't found direct solution for that, and it seems like missing feature.
The workaround I did was:
Mapping id_token/access_token/refresh_token to custom cognito attributes. As all mapped attributes are later available in your frontend, you need to restrict read permissions for sensitive attributes.
Use TokenGeneration_HostedAuth lambda trigger to work on this data.

To call AWS SDK APIs using secret key credentials versus using cognito credentials

In the AWS Xamarin SDK docs, the Amazon Cognito Identity API documentation for GetOpenIdTokenForDeveloperIdentity() says in its second paragraph that "You must use AWS Developer credentials to call this API."
Now, the general idea is to try to never expose API secrets & keys in the source code especially if there are other mechanisms available. AWS provides the IAM mechanism so that we can assume a role and then we can define which privileges can be assumed by that role.
But this text mentioned in bold above, does it mean i cannot use IAM roles and/or policies to call those APIs? Does it mean i HAVE TO include my accessKey and secretKey in my application source code?
Edit:
AWS provides the Cognito mechanism through which we can requested temporary credentials via
`credentials = new CognitoAWSCredentials ("IDENTITY_POOL_ID", "REGION_NAME");`
without directly using Developer credentials like the accesskey and secretkey etc.
But this text mentioned in bold above, does it mean i cannot use the credentials obtained via cognito because these credentials were not produced with Developer credentials?
Trying to figure out this new cognito thing.
You can use IAM roles to call this API, same way you would call any other AWS sigv4 API. Purpose of the text is to emphasize that unlike other Cognito unauth APIs (getId, getOpenIdToken, getCredetialsForIdentity) you will need to call GetOpenIdTokenForDeveloperIdentity from your server and with AWS credentials. These credentials can be obtained with IAM user or IAM roles.
Edit:
Cognito is meant for vending credentials on the client side applications, for eg: Mobile apps. Typically credentials are vended after federating with social identity providers, eg: Facebook, google, Amazon etc.
The API 'GetOpenIdTokenForDeveloperIdentity' was introduced to allow you to federate with Cognito with your own authentication system. If you don't have your own authentication system, you should not be using this API. This API is meant to be called from your server side application. Of course you can use Cognito to get the credentials on server side and call GetOpenIdTokenForDeveloperIdentity, but that's not what Cognito is meant for. Simpler will be to just use credentials with help of IAM on server side.