How can I get the identity id of the user (logged in by AWS Cognito) that invoked an AWS Lambda function? Do I have to use the SDK on the Lambda function to get the identity id?
-
Are you talking about Cognito sync as an event source? It should be available in the event as `event.Records[0].cognitosync.identityId`. – William Gaul Apr 28 '15 at 20:01
-
In this case, I am using it from the Javascript SDK on the browser. event.Records doesn't seem to be available in this case. – Renan Apr 28 '15 at 23:46
-
Ahh, got it. Thought you meant Cognito event source instead of authenticating with Cognito. – William Gaul Apr 29 '15 at 02:05
8 Answers
In AWS javascript SDK inside lambda function just use context.identity.cognitoIdentityId It is working for me

- 161
- 1
- 8
-
3I'm doing this, but in a java function so it is context.getIdentity().getIdentityId() and it just returns an empty string. If I log context.getIdentity() it returns 'lambdainternal.api.LambdaCognitoIdentity@42f48531'. Any ideas? – James Parker Jun 09 '16 at 03:47
-
I'm really curious: What are you doing to get this to happen? What special config are you doing with Lambda or API Gateway? – Dan Esparza Aug 22 '17 at 21:02
-
1I would suspect @JamesParker is accidentally using unauthenticated `CognitoIdentityCredentials`, which is far too easy with the example docs for browser usage. – Simon Buchan Aug 22 '17 at 21:44
-
How to test this using POSTMAN... When request is send using postman, lambda is having null value for event.requestContext.identity.cognitoAuthenticationProvider – Dipti Shiralkar Nov 27 '18 at 07:23
-
4
-
If anyone else stumbles upon this, I think this will help you a lot.
Note this only applies if you're using the Cognito User Pool Authorizer. If you want to use AWS_IAM with Cognito Identitys check out my github example https://github.com/VictorioBerra/js-cognito-auth-example (read down to EDIT area below)
If you have "Use Lambda Proxy Integration" checked then you wont have access to Request Template Mappings. But you can get to the claims inside the token in your lambda function:
exports.handler = (event, context, callback) => {
//create a response
const response = {
statusCode: 200,
body: JSON.stringify({
"user email": event.requestContext.authorizer.claims.email,
}),
};
callback(null, response);
};
EDIT - More information for using AWS_IAM as APIG authorizer
Basically you need to have your APIG secured with AWS_IAM AND you must auth via a Cognito Federated Identity which will return a sessionToken example using user pools. This is what makes the AWS IAM credentials temporary. Now you have everything you need to auth to your APIG.
To test this, download the desktop version of postman, toss in your API URI (grab this from the stages area) and then under Authorization fill out the 5 fields you need for Sig4 signing. You will see 'event.identity' object in your lambda function is loaded up with properties such as the user
object.
If you want to use the APIG auto-generated SDK it comes built in with a factory that takes the accessKey
, secret
, and token
and signs everything for you. Same with the aws-sdk. You can init the credentials with those three items and it will automatically sign all requests for you with those temp creds. If you want to straight up manually hit your API with window.fetch, request, curl, (insert http client here) you can calculate your own Sig4 (beware it can be a little complicated or use a modern library to do it for you.
Also for the record, while doing my research I noticed that if you want to NOT use AWS_IAM as an APIG authorizer, and you want to use "Cognito Identity Pool Authorizer" which is a fancy new option in the dropdown in APIG you can still get a ton of info on the user in the lambda event if you just pass the JWT gained from a successful Cognito popl auth to the APIG as the Authorization header. Inside that JWT is a lot of attributes which you can customize in your pool settings.
IMO professional opinion I think using the AWS_IAM temp creds authorizer is preferred. This way, you can use as many different IdPs as you want in Cognito Identities (Facebook, Twitter, pools, etc.)

- 2,760
- 2
- 28
- 53
-
Note that this is authenticating using a user pool, not an identity pool, so there is no identity id. Yeah, Cognito is super confusing. – Simon Buchan Aug 22 '17 at 21:53
-
Thanks Simon I updated my answer. I actually spent some time working on this and created a github project for it. – Victorio Berra Aug 23 '17 at 22:57
-
event.requestContext.authorizer is not available in my lambda. Running with AWS_IAM and "Lambda Proxy Integration". Any ideas? Remark: Cognito & IAM are the pure hell. WAAAY to complex. – Logemann Jun 05 '18 at 22:46
-
@Marc if you dont have `authorizer` chances are you'r call to your APIG was not authed. Basically you need to have your APIG secured with AWS_IAM AND you must auth via a Cognito Federated Identity which will return a sessionToken. – Victorio Berra Jun 07 '18 at 19:09
-
I did all that and its authed. But according to docs authorizer is in fact not there for that scenario. I think its only there for USERPOOL authorizer. You can get the Identity via event.requestContext.identity.cognitoAuthenticationProvider . Unfortunately only the "sub" attribute of the user in the pool. No other fields. – Logemann Jun 08 '18 at 21:11
If you go through API Gateway, you can pass the cognito id (as well as the user arn and other useful information) to Lambda. This solved the issue for me.

- 101
- 1
- 2
-
-
2API gateway we added the cognito authentication. In api method added "$context.identity.cognitoIdentityPoolId" but it is empty when we access it in JAVA lambda function. we using postman as client and set Authorization token. what is missing ? – Mr.Pramod Anarase Jul 22 '17 at 05:36
-
1@Mr.PramodAnarase If you are adding something like `Authorization: Bearer SOME_TOKEN` where SOME_TOKEN is the Id or Auth token returned by [`InitiateAuth`](http://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html) / `RespondToAuthChallenge` flow, you are authenticating using a Cognito User Pool, and therefore do not yet have an identity pool id. Comments are not big enough to describe the full flow here :), but you want to be authenticating with `CognitoIdentityCredentials`, which uses STS under the hood to get temporary access keys which will set that. – Simon Buchan Aug 22 '17 at 04:43
-
@SimonBuchan I am authenticating with the userPool on my login call and updating my aws creds with AWS.CognitoIdentityCredentials and I see it registers the identity in my identity pool, however the accessToken and idToken are still the same. And I use those on my authenticated calls to other endpoints. Should I be using something else for my other api calls to authenticate to get the identity properties to populate? I think I am missing something simple here, but cannot for the life of me figure out what to do after I have registered with the pool. Thanks! – Fostah Jul 22 '20 at 23:35
-
You seem to be confused? TL;DR: you get what you sent: tokens -> user pool auth, credentials -> identity pool auth. You need identity pool auth to get the cognito identity (pool) id in the lambda context (only when calling it directly). If you are using user pool auth, you should instead be using something like the cognito user pool authenticator in API gateway or a JWT verifier to verify and extract the claims from the token, which will give you the readable attributes. – Simon Buchan Aug 06 '20 at 03:28
Per the docs, it looks like information about the identity provider would only be available for an invoke through the Mobile SDK.
To get around this, one option is to pass the identity ID to the function manually as part of the event. Assuming you are doing something like AWS.config.credentials = new AWS.CognitoIdentityCredentials(...)
then you should be able to get the ID via AWS.config.credentials.identityId
(after the credentials are refreshed).
EDIT: A better option for identity validation is to let Cognito/IAM handle it, and assume that if a user can successfully invoke a Lambda function, that means they are allowed to. In this case to manage per-user validation, take a look at whitelisting.

- 3,181
- 2
- 15
- 21
-
3Yes, this works, but I am afraid I won't be able to validate the identity in the Lambda function and can't guarantee the user invoking the function is the same he says he is. Should I be concerned about this and is there a way around it? – Renan Apr 29 '15 at 12:45
-
Hmm...but the only way a user would be able to invoke your function is if they have a "valid" identity. Your Cognito pool sets up the contract you expect, e.g. if you want them to be logged in with Facebook first, or you can even have your own validation methods in a custom identity provider. So the Lambda function should not need to worry about validation. But I feel like I'm missing something here...what case do you see where you would need to validate in the Lambda function? – William Gaul Apr 30 '15 at 03:01
-
2for example: if I would like to invoke a function to create/edit/delete something, say on DynamoDB, but I have to validate the user to make sure he has authorization to do this. – Renan Apr 30 '15 at 18:41
-
[Whitelisting](https://forums.aws.amazon.com/thread.jspa?threadID=157201)? Or the more appropriate solution for this case which is custom provider. IMHO Cognito/IAM/your app should take care of validation and once a user invokes a function that means they're allowed to. – William Gaul May 02 '15 at 04:12
-
Yes, that seems more like what I was looking for! Can you please edit your answer so I can accept it? :) – Renan May 03 '15 at 14:45
-
2@WilliamGaul The docs are unfortunately slightly misleading in this case. The identity should be available regardless of the SDK used, as long as the credentials came from an Amazon Cognito authflow. – Bob Kinney Jul 22 '15 at 00:22
-
'A better option...' this is great, except certain operations (like `iot.attachPrincipalPolicy`) require an identityId as the principal. If you want to perform those operations in Lambda, you need to be able to access the identityId. Please tell me I'm wrong. – Dan Esparza Aug 22 '17 at 00:13
For anyone else still struggling to obtain the IdentityId of a Cognito User in a Lambda Function, after many hours of exploration, I discovered that the IdentityId can be obtained within a Lambda Function in the following ways depending on the method you use to invoke the Lambda Function:
Invocation via an API-Gateway trigger with a Cognito User Pool Authorizer
The IdentityId can be obtained in the following way:
const IDENTITY_POOL_ID = "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
const USER_POOL_ID = "cognito-idp.us-west-2.amazonaws.com/us-west-2_an976DxVk"
const { CognitoIdentityClient } = require("@aws-sdk/client-cognito-identity");
const { fromCognitoIdentityPool } = require("@aws-sdk/credential-provider-cognito-identity");
exports.handler = async (event,context) => {
const cognitoidentity = new CognitoIdentityClient({
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient(),
identityPoolId: IDENTITY_POOL_ID,
logins: {
[USER_POOL_ID]:event.headers.Authorization
}
}),
});
var credentials = await cognitoidentity.config.credentials()
console.log(credentials)
// {
// identityId: 'us-west-2:d393294b-ff23-43t6-d8s5-59876321457d',
// accessKeyId: 'ALALA2RZ7KTS7STD3VXLM',
// secretAccessKey: '/AldkSdt67saAddb6vddRIrs32adQCAo99XM6',
// sessionToken: 'IQoJb3JpZ2luX2VjEJj//////////...', // sessionToken cut for brevity
// expiration: 2022-07-17T08:58:10.000Z
// }
var identity_ID = credentials.identityId
console.log(identity_ID)
// us-west-2:d393294b-ff23-43t6-d8s5-59876321457d
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
},
body:JSON.stringify(identity_ID)
};
return response;
}
Why?
Invoking a Lambda Function using an API-Gateway trigger with a Cognito User Pool Authorizer will result in the following fields (among additional fields which have been removed for brevity) being available in the event
of the invocation:
{
"resource": "/{proxy+}",
"path": "/_",
"httpMethod": "POST",
"headers": {
"Authorization": "eyJrmlaod8(kyC9zdspo0jZIYjRENFlCNVBidnksl89DNm9USDJrT25MSDhjXC9EYkIzMzQ8389iYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI8389yNDg4Ny0wYTRdkiuiOGQtODA4My1kNmIyYzZhYWNhN2YiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLXdlc3QtMi5hbWF6b25hd3MuY29tXC91cy13ZXN0LTJfZ3dPMjlMckR4IiwiY3VzdG9tOmZpcnN0X2tleSI6ImZhbHNlIiwiY29nbml0bzp1c2VybmFtZSI6IjJjNjI0ODg3LTBhNGItNGE4ZC04MDgzLWQ2YjJjNmFhY2E3ZiIsIm9yaWdpbl9qdGkiOiI0ODEzYzk1Ni01MDM0LTQzNmItYjE5OS00MWZjN2U1ZTQ0ODciLCJhdWQiOiJyNjdwOGdxNnQ5cHJrc2JyYmtxMDVoM2NuIiwiZXZlbnRfaWQiOiJmOWRlNWMxOC0yMTNlLTQ2NDgtOGY4MC1mODdhYWJhNWM4NGUiLCJjdXN0b206YXBpX2tleV9JRCI6Imhoa2hpMmw5cTkiLCJjdXN0b206YXBpX2tleSI6InVzLXdlc3QtMjplOTBkYmUzZC0wN2FhLTRjODQtOGQ0Ny04NjJmZDJhNzQ1MGZfcm5Zalk2YmhaT0lkWXhDcDBDcjNYZWVaYzFuT3ViZnkzdEs5aEtFRFVIZ3FJd1BSTVJuQ2pyWlJYdGNBSVpqWTVnMFFyejN3ek1keGoiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTY1ODA0ODg1OSwiZXhwIjoxNjU4MTM2MTk3LCJpYXQiOjE2NTgxMzI1OTcsImp0aSI6IjdmNTdiYWZlLTA1ZGUtNDgwZC1hMDgzLWY1MjlhN2YzNmI2YiIsImVtYWlsIjoidHJldmVuYXc3QGdtYWlsLmNvbSJ9.hk-8ajGP2jO0RQvzwZWp2d5T1BLiWL9q6vvrbXemLBbd2kb1kkBSvklfC_7WWvJoy1ukwNoq8Cx63U2hQfjJB077AHrHfN2PkJu4DG86vSdtSzrZVDQmle331UxopLQvzDZ1mejfmSFbo6x1ZeTbo39PRpox4pzsfeUAM1Rf8H6y8OrdPZa7Gh6gRkiN2IcwdBnXI4-Q6HX5QqiVzr2O4zEnNsqMFfsFA3aO05hnp7EYRWHgS6EgaQjfBirCoyerBkjFJTXynl76Jj4fK3-3KY4tw5EHplxkgAih7a9QTxy8SbRee8kh7fwrIGEO6CtgkM9v0XL7jBPtNtGTpqBRzw"
},
"requestContext": {
"authorizer": {
"claims": {
"sub": "231df9d7-0aab-4dsd-8389-d315d9daca7f",
"email_verified": "true",
"iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-2_an976DxVk",
"custom:first_key": "false",
"cognito:username": "231df9d7-0aab-4dsd-8389-d315d9daca7f",
"origin_jti": "8131rlpo-5123-436b-b199-41315d9d4487",
"aud": "r6315d9dt9sdls315d9d5h3cn",
"event_id": "f3dsp9d8-213e-4648-8f80-f8315d9dc84e",
"custom:name": "my_name",
"token_use": "id",
"auth_time": "1658148859",
"exp": "Mon Jul 18 09:23:17 UTC 2022",
"iat": "Mon Jul 18 08:23:17 UTC 2022",
"jti": "982sdafe-97rs-996l-i899-k315d9d09n7n",
"email": "jeff@amazon.com"
}
},
"extendedRequestId": "dSiT_dLdJdad9oP=",
"requestTime": "18/Jul/2022:08:23:27 +0000",
"requestTimeEpoch": 1658132607750,
"requestId": "387ss00s3-add0-62i9-l9s0-9a8dj8976dfa",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "91.83.769.200",
"principalOrgId": null,
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
"user": null
},
"domainName": "mskd8fpni2.execute-api.us-west-2.amazonaws.com",
"apiId": "mskds98ni2"
},
"body": "{\"name\":\"my_name\"}",
"isBase64Encoded": false
}
and the following fields being available in the context
of the invocation:
{
"callbackWaitsForEmptyEventLoop": true,
"functionVersion": "$LATEST",
"functionName": "hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"memoryLimitInMB": "512",
"logGroupName": "/aws/lambda/hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"logStreamName": "2022/07/15/[$LATEST]95edi84719944bdi84a6cdi8451di849",
"invokedFunctionArn": "arn:aws:lambda:us-west-2:598763214571:function:hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"awsRequestId": "d8s57juq-3g39-49sk-8625-5849sk9be44I"
}
Notice the following things:
- The Cognito User's IdentityId is not available in either the
event
or thecontext
- Other information about the Cognito User is available in the
event
(email, sub, custom attributes, etc.) - The request invocation time is available in the
event
(the time that the lambda function was invoked which is available inevent.requestContext.requestTime
andevent.requestContext.requestTimeEpoch
)
Note: Please leave a comment if you are having a hard time setting up an API-Gateway trigger with a Cognito User Pool Authorizer for your Lambda Function, if people are interested I will add instructions on how to accomplish this.
Direct invocation using a Cognito User's credentials and the AWS SDK for JavaScript v3
The IdentityId can be obtained in the following way:
exports.handler = async (event,context) => {
var identity_ID = context.identity.cognitoIdentityId
console.log(identity_ID)
// us-west-2:d393294b-ff23-43t6-d8s5-59876321457d
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
},
body:JSON.stringify(identity_ID)
};
return response;
}
Why?
Directly invoking a Lambda Function using the AWS SDK for Javascript v3 and a Cognito User's credentials will result in no additional information being available in the event
of the invocation:
{
"name": "my_name"
}
however, the IdentityId is available in the context
of the invocation:
{
"callbackWaitsForEmptyEventLoop": true,
"functionVersion": "$LATEST",
"functionName": "hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"memoryLimitInMB": "512",
"logGroupName": "/aws/lambda/hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"logStreamName": "2022/07/15/[$LATEST]95edi84719944bdi84a6cdi8451di849",
"identity": {
"cognitoIdentityId": "us-west-2:d393294b-ff23-43t6-d8s5-59876321457d",
"cognitoIdentityPoolId": "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
},
"invokedFunctionArn": "arn:aws:lambda:us-west-2:598763214571:function:hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"awsRequestId": "d8s57juq-3g39-49sk-8625-5849sk9be44I"
}
Notice the following things:
- The Cognito User's IdentityId is available in
context.identity.cognitoIdentityId
- Additional information about the Cognito User is not available in the
event
or thecontext
(email, sub, custom attributes, etc.) - The request invocation time is not available in either the
event
orcontext
Note: To directly invoke a Lambda Function using a Cognito User's credentials and the AWS SDK for JavaScript v3, you need to add a custom IAM Permission to the IAM Role assumed by authenticated Users in your Cognito User Pool. To do this:
- Go to IAM -> Roles, and find the role for your user pool such as
amplify-myapp-prod-12987-authRole
- Click "Add permissions"
- Click "Create inline policy"
- Click "JSON"
- Insert the following policy and replace the Function ARN with the ARN of your Lambda Function:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunctionUrl",
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:*:598763214571:function:hello-world-jsHelloWorldFunction-kTdLswTRrkdS"
]
}
]
}
- Click "Review Policy"
- Save the policy
Invocation methods that don't currently support authenticating users from a Cognito User Pool:
- Invoking with caller credentials (this only works if you are using AWS_IAM authentication, not a Cognito User Pool Authorizer)
- Invoking via a function URL (this only supports AWS_IAM authentication as well)

- 256
- 2
- 6
My observation is the following.
If you call the API Gateway with a signed Request where you actually provide the accesskey, secret and sessionToken which you can extract via (JS SDK):
AWS.config.credentials = new AWS.CognitoIdentityCredentials(...)
AWS.config.credentials.get(..)
And assumed that your lambda is called from API-Gateway via LAMBDA_PROXY and Authorizer AWS_IAM. You can only access user stuff in lambda with:
exports.create = function (event, context) {
secdata = event.requestContext.identity.cognitoAuthenticationProvider;
}
Then you will get, apart from other stuff, the "sub" of the cognito UserPool User. So if you really want to know more about the user, it seems you need to ask AWS again via SDK call.

- 2,767
- 33
- 53
-
1The `secdata` in this case will be an string alike `"cognito-idp.us-east-1.amazonaws.com/us-east-1_3UxKMbgEq,cognito-idp.us-east-1.amazonaws.com/us-east-1_3UxLObgEq:CognitoSignIn:c40aabc8-9b21-4aa5-b296-12175450e28e"` that must be parsed and the part after `CognitoSignIn:` is the user id. – MJBZA Feb 08 '21 at 07:45
For a Python Lambda, invoked via Javascript AWS SDK / Cognito / Amplify...
https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html
context.identity.cognito_identity_id
It should look something like this:
{aws region}:{ GUID }
Assuming you are using an Identity Pool, this will return the Cognito Federated Identity, that can be used for fine grained access control. This is safer than relying on the Javascript payload containing the identity id.
The Cognito Identity Pool Auth Role will need to have Lambda:InvokeFunction policy, otherwise the user won't be able to invoke the function in the first place.
Edit: This works when calling the Lambda function DIRECTLY, not via API Gateway.
Edit2: The Cognito user is allowed to call the lambda because it is explicitly set in the IAM Cognito Auth role.

- 3,542
- 30
- 46
I was using Kotlin and my Lambda handler was
override fun handleRequest(event: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent
But event.requestContext
had no authorizer
. The solution was to upgrade the dependency in build.gradle from
com.amazonaws:aws-lambda-java-events:2.1.0
to com.amazonaws:aws-lambda-java-events:2.2.7
. After that, I got the username as follows.
val claims = requestContext.authorizer["claims"] as Map<String, String>
println(claims["cognito:username"])
println(claims["email"])

- 3,907
- 1
- 27
- 18