18

I've successfully configured IAM-authenticated access to my Lambda function with AWS API Gateway front-end, but unable to find how to pass IAM user identity to my Lambda function.

I need exactly IAM user identity and can not run Lambda function under calling IAM-user credentials. All I need - is to get calling IAM-user identity in my Lambda function.

Is there option for that?

AlexeyVMP
  • 2,386
  • 3
  • 24
  • 31
  • So far, the best solution that I've found is to send user's logins to the script and re-authenticate them there to get user's id... It solves my issue, but definitely is not best solution. – AlexeyVMP Jul 30 '15 at 05:11

2 Answers2

9

Support for accessing identity and other information from the Amazon API Gateway request context hadn't been available when you posted the question, but recently been added, see Announcement: Context Variables:

You can now access context variables from within mapping templates to retrieve contextual information about the API call. You can access data such as stage, resource path, and HTTP method, as well as information about the identity of the caller. This information can then be passed along to your backend integration using the $context variable. [emphasis mine]

The referenced documentation on Accessing the $context Variable features a $context Variable Reference and there are various $context.identity.* parameters that should address your use case.

Cognito Identity

As outlined in Soenke's answer to the OPs similar question in the Amazon API Gateway forum, there is an as of yet undocumented integration parameter that results in the Cognito identifier being included in this $context.identity.* context variables:

in order to have the Cognito (not IAM!) IdentityId and IdentityPoolId available in Lambda, you have to enable "Invoke with caller credentials" on the API Gateway "Integration Request" page of the API GW Resource. This results in a new context struct "identity" (containing "cognitoIdentityId" and "cognitoIdentityPoolId" being passed to the Lambda function).

Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
  • None of the new variables provides Cognito user identifier – AlexeyVMP Aug 24 '15 at 05:39
  • @AlexeyVMP - sorry, but your question did not mention that you are looking for the the Cognito user identifier, you only asked _how to pass IAM user identity_. That being said, I have now added Soenke's resp. answer to your similar API Gateway forum post, which you already dismissed in the subsequent post as non applicable though - I'm not quite sure I can follow what you are after there, either way I'm not aware of any other method to get the Cognito identifier handed over to you directly, and how to retrieve it yourself has already been answered by napalm's comment. – Steffen Opel Aug 24 '15 at 09:05
  • 2
    When I have "Invoke with caller credentials" unchecked, I am able to see the CognitoIdentityId inside the lambda function. To be able to do that I create an _application/json_ mapping template: _{ "context.identity.cognitoIdentityId" : "$context.identity.cognitoIdentityId"}_ in the **Integration Request** section. After doing "Deploy API" I need to wait some extra seconds before trying to access my website. There is a few seconds delay before the "Deploy API" takes effect. – Erik Sjölund Mar 11 '16 at 13:10
  • Can we publish sns or send message to SQS from Lambda using the caller identity that came through Api gate way? In our case we receive a message and an array of queues in our lambda we will direct the message to the all queues, before sending message we would like to check if the gateway Api caller has access to the queues he just passed. – johnny Mar 20 '16 at 01:56
  • 1
    Trying to log my user IAM id here (so as to bill api calls for an SAAS service.). The best I managed to do for the moment is to rework the request body in the integration request, add a mapping template for the body, generate a basic "passthrough" code, and add a value `"MyUserArn" : "$context.identity.userArn"` in it. This fills the body with a large mess, and needs to enable full logging of my requests, for the simple purpose of identifying the caller account. Isn't there a better way ? At least, I'd like to just add my variable in a header, or QSParam. (I use a beanstalk, not lambda) – Balmipour May 17 '16 at 22:40
  • Getting account-id from the integration parameter seems of limited use at the moment - as API gateway doesn't support cross-account authentication. http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html – russau Jul 04 '16 at 06:40
-1

You can use Cognito with a "public" pool id, then attach role to the Cognito pool id, the role being accessing your Lambda, I think it is called InvokeLambdaRole or something

AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'REGION:YOUR_POOL_ID',
});

Use AWS STS to get temporary credentials with limited privileges. After that you can use API Gateway with AWS_IAM authentication, then end point will invoke the Lambda methods for you. Or you can invoke lambda directly with the credentials you got, but then again you have to attache the right roles for the identity pool you created.

NB: Put strictly minimum roles on your pole, that is a publicly available id, every body can use it to get a temporary or a fixed (to track users accross devices) user_/app_ id.

e-nouri
  • 2,576
  • 1
  • 21
  • 36