Open baharev opened 6 years ago
@lestephane Thanks for the detailed explanation. Your use case is different from mine. In your case, you can get away with logged in / not logged in decisions and API keys.
In my case it is not possible; the users must have their own private data. Implementing this without IAM roles would mean re-implementing something that IAM gives me for free (if the user can assume IAM roles).
Thanks for the explanation, now I see that your use case is different from mine.
This has become the most commented open issue, and the second most commented issue of all times. I rest my case.
@baharev Thanks for confirming that i don't need identity pools, making this issue irrelevant for me. Of course, I can't speak for anyone else following this issue. I was merely trying to find a way out of the dichotomy.
@lestephane There are valid use cases where you do not need IAM roles, and apparently your use case is such a use case. That's 100% OK. However, the situation may quickly change in the future if your requirements change, and then this issue will become relevant for you as well.
Indeed @baharev I will continue following this issue
This scenario renders AWS Amplify pretty useless if you want to sign users in using Cognito user pools and then have them interact with a Lex bot. The SDK just passes their identity/IAM token, and without any way to map a user pool id with an identity id, you can't personalise any chat bot response for an authenticated user. Seems particularly short sighted.
The way I've worked round it is to hack the interactions function to pass the pool user id via chat session data, but this is technically insecure since the authenticated user could specify any user id and have the chat content personalised for their id.
Here's a lambda function that resolves a userpool user or federated identity to an email address.
The function is using the serverless typescript template.
For the userPool, I do a listUsers request as per suggestion here.
For federation, I validate the token to ensure it's not been tampered with (not sure if CognitoIdentity
validates it internally), then call CognitoIdentity.getId
as per the suggestion above by @behrooziAWS.
Then, I compare the resolved identity to the request identity to ensure it's not a hijack attempt, if ok, I'll save the details into a DynamoDb table.
export const postAccountCurrentProfile: Handler = async (event: APIGatewayEvent, context: Context, cb: Callback) => {
const body = JSON.parse(event.body);
const provider = body.provider;
const requestIdentityId = getCognitoId(event); //retrieve the id from the event
var foundIdentityId: string;
var foundEmail: string;
if (provider === 'UserPool') {
const sub = event.requestContext.identity.cognitoAuthenticationProvider.split(':CognitoSignIn:')[1];
const request = {
AttributesToGet: [], // NOTE: I'm using email as my username so don't have to get any attributes
UserPoolId: process.env.user_pool_id,
Filter: `sub = "${sub}"`,
Limit: 1
};
const cognitoClient = new CognitoIdentityServiceProvider({ region: process.env.region });
const users = await cognitoClient.listUsers(request).promise();
foundEmail = users.Users[0].Username;
foundIdentityId = requestIdentityId;
} else if (provider === 'Google') {
const gClient = new gApi.OAuth2Client(process.env.google_client_id);
try {
await gClient.verifyIdToken({ idToken: body.token, audience: process.env.google_client_id });
} catch (x) {
console.error(x);
emptyResult(500, cb);
return;
}
const identity = new CognitoIdentity();
const params = {
IdentityPoolId: process.env.identity_pool_id,
Logins: {
'accounts.google.com': body.token
}
};
const response = await identity.getId(params).promise();
foundIdentityId = response.IdentityId;
foundEmail = token.email;
}
if (foundIdentityId !== requestIdentityId) {
sLog.error('Account hijack attempt', { requestIdentityId, foundIdentityId });
//TODO: send to sns queue
emptyResult(500, cb);
return;
}
okObjectResult({ identity: foundIdentityId, email: foundEmail }, cb);
};
Hope this helps someone.
This issue has become the most commented issue of all times (in this repo), and has 5 more days left to become 1 year old.
@hectomg What didn't you like about my solution above?
+1 for this feature request.
@ffxsam , the problem with doing anything client side is you cannot trust the client. Anything coming from the client must be treated as potentially compromised and must be validated on the back-end against known good sources.
Fair point.
Please add this feature. It is clearly already present in some fashion on the backend, as @baharev has explained. Ridiculous that it's taken this long and still no satisfactory resolution!
+1 for this. It is really hard to grab (probably no way) the identity id in the cognito post confirmation trigger when you use the cognito identity id as a leading key. (Though we could use sub, but we have a special use case for not using sub in the user attributes).
If identityId was available in the claims object for a lambda proxy, like the sub / userId is. All my problems would go away.
+1 for this! I was happy to stumble across this and I'm surprised that it's still open.
My use case is to allow "host" users to upload "protected" images to S3, then let all types of users view the images when viewing a particular host. I couldn't find a way to attach the identity id to the hosts on the server side, since stateful authentication is required to retrieve the identity id, which only makes sense from the browser.
My understanding is that this is similar to or the same as what @baharev had to workaround:
I looked at the Cognito API reference, and it is weird too. For example:
- AdminGetUser does not seem to give me the identity ID.
- DescribeIdentity does not seem give me any user attributes.
- Somehow the mapping between users and identity IDs seem to be hidden. The only way I could recover it is through the login tokens.
My problem is namely:
- AdminGetUser does not seem to give me the identity ID.
This isn't really an AWS Amplify issue though, since the fault seems to lie with the AWS SDK. I hope I'm not commenting on the wrong thread. 🙈
@dylan-westbury & @chadgarlandscg ,
I'm a bit confused as to which IdentityId you're after.
If you're after the IdentityPool IdentityId, this in a lambdaa event, this is available via the
APIGatewayEvent.requestContext.identity.cognitoIdentityId
property, the APIGEvent class is available in the lambda event.
I can't find the docs for this class but it's listed at the below type link.
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/index.d.ts
Apologies if I misunderstand :)
@thrixton apologies for the late reply! I'm actually trying to do this in a Node server, not a Lambda.
My users ("guests" and "hosts") authenticate with Cognito via Amplify. Hosts can upload an image via Amplify, which saves the image under their protected folder in S3. Then, guests (authenticated or not) as well as other hosts can browse for hosts and see their saved image.
Hosts are registered via an admin API call, which signs them up with Cognito via the AWS SDK's adminCreateUser
call. Neither this call, nor adminGetUser
return the cognito identity id, which I need to store in my DB in order for all users to see the host's uploaded image in S3 via Amplify Storage. Therefore, I am forced (at least with my architecture) to rely on my web application to send up the cognito identity id on the initial host login.
Perhaps I am the one misunderstanding 🙈I'm so sorry if that's the case! My situation just seemed to closely mirror one of the original problems mentioned by @baharev here:
AdminGetUser does not seem to give me the identity ID.
Feel free to let me know if I'm doing something crazy or missing something obvious.
Thanks a bunch!!
@dylan-westbury & @chadgarlandscg , I'm a bit confused as to which IdentityId you're after. If you're after the IdentityPool IdentityId, this in a lambdaa event, this is available via the
APIGatewayEvent.requestContext.identity.cognitoIdentityId
property, the APIGEvent class is available in the lambda event. I can't find the docs for this class but it's listed at the below type link. https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/index.d.tsApologies if I misunderstand :)
Cognito Identity id can obtained from Lambda context yes, but it cannot be mapped to an actual user account in Cognito's user pool
@dylan-westbury & @chadgarlandscg , I'm a bit confused as to which IdentityId you're after. If you're after the IdentityPool IdentityId, this in a lambdaa event, this is available via the
APIGatewayEvent.requestContext.identity.cognitoIdentityId
property, the APIGEvent class is available in the lambda event. I can't find the docs for this class but it's listed at the below type link. https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/index.d.tsApologies if I misunderstand :)
@dylan-westbury & @chadgarlandscg , I'm a bit confused as to which IdentityId you're after. If you're after the IdentityPool IdentityId, this in a lambdaa event, this is available via the
APIGatewayEvent.requestContext.identity.cognitoIdentityId
property, the APIGEvent class is available in the lambda event. I can't find the docs for this class but it's listed at the below type link. https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/aws-lambda/index.d.tsApologies if I misunderstand :)
Yes that is the correct identityId, but it's only available if the authorizer is set to AWS_IAM, as opposed to a cognito user pool authorizer
+1 for this feature request.
Throwing my +1 in the ring here, I was pretty stunned to see this was even an issue given that Amplify leads you into this scenario ie. Storage
module using Federated IDs but no way to relate them to User Pool IDs.
A simple extra field in one of the response or trigger payloads would seem to resolve this issue, no?
Alright, I spent way too long trying to come up with a reasonable approach to linking the user's sub
value from my Cognito User Pool to the IdentityId
value from the Cognito Federated Id, and the solution I came up with isn't perfect, but it's somewhat sane and at least verifiable.
I noticed that requests to the AppSync GraphQL API's are authorized using the idToken
value that is returned after a user authenticates via Cognito User Pools. ~That same token is also used in calls to the getId
method of the AWS.CognitoIdentity
JS SDK. (ahhaaaaaa)~
I decided to query the User's record that is stored within my custom DynamoDB User
table based on the user's sub
value that is returned after login. You can get this from the user claims object, ie.
<Authenticator
hideDefault={true}
amplifyConfig={awsconfig}
onStateChange={async authState => {
if (authState === "signedIn") {
const user = await Auth.currentAuthenticatedUser();
const { sub } = user.attributes;
try {
const user = await API.graphql(
graphqlOperation(getUser, { id: sub })
);
console.dir(user);
} catch (err) {
console.log("error loading user...: ", err);
}
}
>
Then, I wrote a custom lambda resolver for the federatedId
field on my User
schema that will fetch the DynamoDB record's federatedId
field if it isn't empty. If it is empty, I then use the authorization token which has already been verified as valid by AppSync and send it to the AWS.CognitoIdentity.getId
method.
The resolver (Query.federatedId.req.vtl):
{
"version": "2017-02-28",
"operation": "Invoke",
"payload": {
"type": "Query",
"field": "federatedId",
"arguments": $utils.toJson($context.arguments),
"identity": $utils.toJson($context.identity),
"source": $utils.toJson($context.source),
"headers": $util.toJson($ctx.request.headers)
}
}
The lambda body:
// check your DynamoDB record here and only do the below
// if your record doesn't already contain the federatedId
// ...
const { authorization } = event.headers;
const { sub, iss, aud, token_use, email } = event.identity.claims;
const userName = event.identity.claims["cognito:username"];
if (iss !== `https://${ProviderName}`) {
//fail
callback("Unauthorized", null);
}
if (token_use !== "id") {
//fail
callback("Unauthorized", null);
}
if (aud !== clientId) {
// fail
callback("Unauthorized", null);
}
const params = {
IdentityPoolId,
Logins: {
"cognito-idp.us-east-1.amazonaws.com/us-east-1_UsErPoOLiDLoL": authorization
}
};
try {
const result = await cognitoidentity.getId(params).promise();
const { IdentityId } = result;
// todo: update DynamoDB record with this info where User.id == sub
// or User.userName === userName
callback(null, IdentityId);
} catch (err) {
console.log(err);
callback("Unable to resolve" + err, null);
}
There's also a few sanity checks above to ensure the claims are valid against my stack.
const IdentityPoolId = "us-east-1:12345678-this-aint-real-abcdefghijkl";
const ProviderName = "cognito-idp.us-east-1.amazonaws.com/us-east-1_UsErPoOLiDLoL";
const clientId = "YOUR_ISSUER_CLIENT_ID";
It's still a bummer that this is even required, it requires a user login event, and, I'm technically making a mutation on a User query which is bad news, but it feels like a better approach than others.
The other approach I explored was using adminLinkProviderForUser
on the User Pool Sign Up Confirmation trigger to proactively create the User's Federated ID, but the ProviderName
value generated by Amplify is too long to pass the Preflight Validation performed by Cognito (limited to 32 characters) and this approach would also only work for new users, not existing users.
Hope this helps someone!
EDIT Upon further inspection, it looks like the idToken
is only used as the authorization
token in the AppSync Console and not in the amplify-js
library. You'd have to also override the library authorization method in your Amplify.configure
call in order to send the idToken
instead of the accessToken
@davekiss Thanks for sharing. Unfortunately, your struggle only underlines my point: It is unnecessarily complicated and brings in other services and libraries (GraphQL, AppSync, DynamoDB, Lambda in your workaround).
I see no good technical reason why the Cognito REST API could not support it directly for the user pool owner.
Pecked out from my iPhone
On Apr 7, 2019, at 1:46 PM, Ali Baharev notifications@github.com wrote:
@davekiss Thanks for sharing. Unfortunately, your struggle only underlines my point: It is unnecessarily complicated and brings in other services and libraries (GraphQL, AppSync, DynamoDB, Lambda in your workaround).
I see no good technical reason why the Cognito REST API could not support it directly.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
After working with AWS and DynamoDB, it seems that management must be making technical decisions in order to increase revenue. Forcing these ugly workrounds which force you to use other services. DynamoDB can’t do some basic things without doing scans, etc
Hi,
The serverless-stack.com have this in their tutorial:
"Mapping Cognito Identity Id and User Pool Id"
https://serverless-stack.com/chapters/mapping-cognito-identity-id-and-user-pool-id.html
Thoug it only at runtime inside a Lambda function.
export async function main(event, context, callback) {
const authProvider = event.requestContext.identity.cognitoAuthenticationProvider;
// Cognito authentication provider looks like:
// cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxx,cognito-idp.us-east-1.amazonaws.com/us-east-1_aaaaaaaaa:CognitoSignIn:qqqqqqqq-1111-2222-3333-rrrrrrrrrrrr
// Where us-east-1_aaaaaaaaa is the User Pool id
// And qqqqqqqq-1111-2222-3333-rrrrrrrrrrrr is the User Pool User Id
const parts = authProvider.split(':');
const userPoolIdParts = parts[parts.length - 3].split('/');
const userPoolId = userPoolIdParts[userPoolIdParts.length - 1];
const userPoolUserId = parts[parts.length - 1];
}
It literally costed me half a day to realize it isn't doable.
I cannot express how misleading ${cognito-identity.amazonaws.com:sub}
is. Took me half a day to find out it isn't Cognito Pool's user sub, since it is the last thing I debugged.
Bridge between User Pool user attributes is a must I'd say.
Sad to see that the issue is from 2 years ago!!!
I hope this sample will your help. (using lambda-proxy integration and cognito userpool authorizer in serverless framework) https://github.com/terukizm/sls-lambda-proxy-userpool-auth-sample
@terukizm We know that it can be solved, but we think it should be solvable with the SDK only, that is, without any extra services, frameworks, and hoops to jump. Your solution underlines the problem: You needed an extra framework (serverless) and a lambda-proxy integration. It is not simple.
@baharev I'm chiming for another user who wants this functionality. Right now I'm using Cognito to manage all my users in my app, lambda to communicate with a dynamodb, and a JS front end using amplify accessing lambda without API gateway.
In Lambda I have access to context.identity.cognitoIdentityId and nothing else. I need access to a user's attributes in the user pool via cognitoIdentityId. Or vice versa being able to take a username in the user pool and access the cognitoIdentityId.
@Shadaeiou OK. And how can I help you? This is the feature that I have been asking for; I don't have an easy way of doing it either. I think you should address one of the developers at AWS to do something about it.
@baharev I wasn't asking for help I was just saying I'm also in the same boat and desire this feature.
@Shadaeiou Then please tell that to one of the AWS developers on this thread. This issue is the oldest open issue and also the most commented one. I don't understand why it has such low priority.
We all do. It’s shouldn’t be this hard. Not this hard on Google or Azure and bet. Or Oracle even
Pecked out from my iPhone
On Jul 27, 2019, at 7:43 PM, Shadaeiou notifications@github.com wrote:
@baharev I wasn't asking for help I was just saying I'm also in the same boat and desire this feature.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
ah @baharev, you deserve a medal! Like @Can-Sahin said, it took me a day to realize that it still isn't possible and sad to see this has been a point of discussion for the last 2 years comparing how AWS is promoting Amplify as an inhouse serverless stack out there. Has this been raised in amplify-cli repo? I just have hit with the same issue but on a different context. Giving up on this one for now.
@babu-upcomer As for amplify-cli, the first red flag was when its predecessor (awsmobile-cli) silently and irrecoverably deleted the S3 bucket with the users' files. More red flags followed, then I ultimately stopped using amplify-cli when it required full admin access to my AWS account, and I refuse to use it. Due to the bugs I encountered, I simply don't trust it. Just look at the issues I raised in the awsmobile-cli, amplify-cli and amplify-js repos.
I have rewritten everything from Amplify on the top of the AWS JavaScript SDK that I need except Auth. The reason for not rewriting Auth is that it is non-trivial and I don't have the time at the moment to do it. But it is coming...
By the way, it is fairly easy to rewrite, for example, Storage (S3) on the top of the AWS JavaScript SDK: 15 lines of code, and then you have full control. Accessing DynamoDB is equally easy with the AWS JavaScript SDK.
I rolled my own deployment script, less than 200 lines and it does pretty sophisticated things (for example compression and cache control for CloudFront the way I want it). Now I control how Storage works, or how deployment is done. Again, look at the issues I raised in the awsmobile-cli, amplify-cli and amplify-js repos.
As for this particular issue #54, I am working towards an approach similar to what @lestephane sketched in his comment. It turns out that after restructuring my application, a similar approach works for me too. It is admittedly a workaround, but at least I will have full control. I will still depend on Auth though...
@babu-upcomer As a side note: Even if this issue is resolved, you would want to assign your unique ID to each user in a way you control. From the comment of @RossWilliams:
I’d much rather have a choice of claim to use and I’d like to avoid sub as it’s not under my control and cannot be recreated when restoring a Cognito User Pool. Anything that relies on a sub would be a large operations risk and require a lot of tooling and time to overcome.
in the related issue Can we use the sub instead of identity id for private/protected storage?
I cannot believe this problem has not been fixed yet. People are burning so much time!!!!
So, I also jump on the bandwagon. Getting another user's protected
file through AWS Amplify requires the identityId
such as:
Storage.get('test.txt', {
level: 'protected',
identityId: 'xxxxxxx' // the identityId of that user
})
.then(result => console.log(result))
.catch(err => console.log(err));
So, I should get that identityId
not for the current user, but also for other ones!
Lol, I was not expecting an issue this old to keep open. I'm facing exactly the same problem. I come from Google firebase and this was super easy to accomplish with the SDK. +1 to please solve this
This took us about 8H to solve, the tidiest secure solution we currently have for our closed AppSync + Cognito UP + Cognito IP / AWS system is running a Lambda as a mutation that takes no parameters. The user's exact current JWT is put into the Lambda request by the AppSync VTL resolver along with the CUP ID and then the Lambda requests the Cognito IP user-identity using the CognitoIdentity module and then writes it into the "Users" DDB table using the CUP ID so it can be looked up when needed.
AppSync Lambda-request:
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": $util.toJson({
"sub": $ctx.identity.sub,
"jwt": $ctx.request.headers.authorization
})
}
Lambda:
const AWS = require('aws-sdk')
const cip = new AWS.CognitoIdentity()
const ddb = new AWS.DynamoDB.DocumentClient()
exports.handler = async ({ sub, jwt }, context, callback) => {
let { IdentityId: id } = await cip.getId({ IdentityPoolId: process.env.IDENTITY_POOL_ID, Logins: { [process.env.USER_POOL_ID]: jwt } }).promise()
await ddb.update({ TableName: 'Users', Key: { id: sub }, UpdateExpression: 'set identityToken = :id', ExpressionAttributeValues: { ':id': id } }).promise()
callback(null, {})
}
Hi all, I'm going to be honest and say that despite a fair amount of reading I'm not entirely sure if the question that I have is related to this ticket or not. I'm just getting into Amplify really, and Cognito, so it's a bit confusing to me at the moment.
My specific use case (I'm hoping somebody can tell me if I'm just crazy) is that I am using PubSub
with Amplify, and when a user registers I need to setup some permissions - basically I need to do the equivalent of aws iot attach-principal-policy --policy-name 'myIoTPolicy' --principal '<YOUR_COGNITO_IDENTITY_ID>'
but I'd like to automate this on user signup.
This would require that in the PostAuthentication_Authentication
trigger I am able to get the users Cognito Identity ID... but from what I can tell, that's not possible?
It seems like perhaps the reason this isn't possible should be more obvious, but there seems like there should be SOME relationship between the user pool user and the federated cognitio identity? But from what I can tell, within these hooks I don't have access.
I'm guessing the fact that this is so confusing to me shows there is a fundamental (and significant!) gap in my understanding of how these systems should be used.
My plan for now, to work around this, is to use a different trigger (an API call) where I know I have access to the Cognito Identity ID. I guess this is likely because when you are making API calls, you're doing so as a federated user, not as a user from a "user pool"?
@kevin-mitchell If I interpret your post properly: Yes, problem well spotted, and yes, apparently that's the best workaround for the time being. Welcome to the club!
My specific use case (I'm hoping somebody can tell me if I'm just crazy) is that I am using
PubSub
with Amplify, and when a user registers I need to setup some permissions - basically I need to do the equivalent ofaws iot attach-principal-policy --policy-name 'myIoTPolicy' --principal '<YOUR_COGNITO_IDENTITY_ID>'
but I'd like to automate this on user signup.This would require that in the
PostAuthentication_Authentication
trigger I am able to get the users Cognito Identity ID... but from what I can tell, that's not possible?My plan for now, to work around this, is to use a different trigger (an API call) where I know I have access to the Cognito Identity ID. I guess this is likely because when you are making API calls, you're doing so as a federated user, not as a user from a "user pool"?
This is exactly my use case. We're using an AppSync mutation for that right now to trigger the policy attachment. But, yeah, this is definetily not the clean way...
What we are doing to solve this problem, which has worked ok so far, is we set the user pool Username
to match the IdentityId
from the identity pool when creating a new user. Since they match, the bidirectional mapping between the two services is now pretty trivial ;)
The new user signup flow goes like this:
IdentityId
from the identity pool using getId()
signUp()
on the user pool, passing in the IdentityId
from the previous call as the new user's Username
(we put their human-readable username in preferred_username
)getCredentialsForIdentity()
using same IdentityId
/Username
from before along with the IdToken
from the user poolWe implemented this first with the lower-level SDK's linked to above. I didn't handle the mapping of this up to amplify but I understand that was a non-trivial task.
And obviously this won't work so well if you already have a bunch of users, but if you're building a new app like we are, hopefully this works for you too.
I am going to add in another possible solution here, but it may be of limited value and may have other drawbacks. I will not profess to be any kind of AWS or Amplify expert so if you see an issue with using this approach I would be happy to hear from you.
I found that it is possible to use a lambda authorizer (of type TOKEN, other types may be possible, but I did not test). We were already utilizing a lambda authorizer to add additional context information into our APIs so this seems like a good fit. It's still early days so I'm not sure if we'll hit any rate limits or other problems. Consider this to be an untested/alpha solution.
get_id
method from the cognito-identity
client.IdentityId
. Use this IdentityId
to call attach_principal_policy
from boto3's iot
client.Example snippet from my API's lambda authorizer:
import os
import boto3
CLIENT_COGNITO = boto3.client('cognito-identity')
CLIENT_IOT = boto3.client('iot')
IDENTITY_POOL_ID = os.environ.get('IDENTITY_POOL_ID')
IOT_TOPIC_POLICY = os.environ.get('IOT_TOPIC_POLICY')
REGION = os.environ.get('REGION', 'us-east-1')
USER_POOL_ID = os.environ.get('USER_POOL_ID')
def setup_iot(token, context):
account_id = context.invoked_function_arn.split(":")[4]
logins = {}
logins['cognito-idp.{}.amazonaws.com/{}'.format(
REGION, USER_POOL_ID)] = token
id_response = CLIENT_COGNITO.get_id(
AccountId=account_id,
IdentityPoolId=IDENTITY_POOL_ID,
Logins=logins
)
identity_id = id_response['IdentityId']
CLIENT_IOT.attach_principal_policy(
policyName=IOT_TOPIC_POLICY,
principal=identity_id)
def lambda_handler(event, context):
token = event['authorizationToken']
claims = verify(token) # not shown, but responsible for verifying the JWT
principal_id = claims.get('cognito:username', None)
if not principal_id:
raise Exception('Unathorized')
setup_iot(token, context)
<other code removed>
Surprised to see that this issue is open since Dec 2017. Neither has this been fixed nor documented to help customers. Based on a cursory read and the no. of hacks listed on this issue, it seems obvious that it should not be left to customers and should be a P0 priority in terms of features.
Ours is a SaaS application using AWS Amplify and we need a link between the Cognito Identity ID and the username for the below-mentioned use cases:
Not sure which team is taking it up (Cognito or Amplify) but it seems that this is a major issue for a lot of customers. Sorry if this sounds rude but it's a valid critical concern and we haven't been able to get around this.
Due to this issue, I will never use AWS Cognito again. Likewise, I will not be using or recommending Amplify as well due to this issue being completely disregarded.
I think we should make a template and send a support inquiry to AWS with the same content pointing to this issue, demanding an answer. We're paid customers, and it's been 2 years and counting that we had no conclusive response other than someone coming and adding a few labels to the issue saying that it's on a backlog.
Given the Cognito identity ID, I would like to programmatically find the user name, e-mail address, etc. For example, one issue is that each user gets his/her own folder in S3 (e.g.
private/${cognito-identity.amazonaws.com:sub}/
according to themyproject_userfiles_MOBILEHUB_123456789
IAM policy) but I cannot relate that folder name (S3 prefix) to the user attributes in my user pool. The closest thing that I have found is this rather complicated code:AWS Lambda API gateway with Cognito - how to use IdentityId to access and update UserPool attributes?
Is it my best bet? Is it really this difficult?
(As a workaround, I would be happy with a post confirmation lambda trigger that creates for example a
${cognito-identity.amazonaws.com:sub}/info.txt
file in some S3 bucket, and in the info.txt file it could place the user sub from the user pool. I am not sure that this is feasible at all, it was just an idea.)