0
votes

I am trying to embed Quicksight dashboards, in an application using a Cognito User Pool for authentication. In order to get a url for an embedded dashboard, I allow the user to assume an IAM role that maps to a Quicksight user (automatically created) via a Cognito Identity Pool.

To allow this flow to happen, the assumed-role should have a RoleSessionName that matches a SessionName passed in to the registerUser() call on the Quicksight API (i.e. in this case, an email address)

My issue is that when I get credentials from the Identity Pool, passing a RoleSessionName in the parameters, the assumed role does not appear to have that session name set, so the call to Quicksight then fails.

Example:

AWS.config.credentials = new CognitoIdentityCredentials({
            IdentityPoolId: 'eu-central-1:ea3b7c31-bf53-4a30-9bdc-xxxxxxxxx',
            RoleSessionName: user.email,
            Logins: {
                'cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxxxxxx' : user.id_token
            }
        })

AWS.config.getCredentials((e) => {
   let sts = new STS();
   console.log(await sts.getCallerIdentity().promise());
})

The result from this shows

{ ResponseMetadata: { RequestId: 'e77ea0e7-30b9-11ea-a070-e5aa4c17e68c' },
  UserId: 'AROA6JSEZRBBBBBBBB:CognitoIdentityCredentials',
  Account: '9826XXXXXXXXX',
  Arn:
   'arn:aws:sts::9826XXXXXXXXX:assumed-role/Cognito_quicksightAuth_Role/CognitoIdentityCredentials' }

My understanding is that the RoleSessionName ought to be the last part of the ARN. Compare if I assume the role directly:

➜  aws sts assume-role --role-arn arn:aws:iam::9826XXXXXXXX:role/Cognito_quicksightAuth_Role --role-session-name [email protected]
{
    "Credentials": {
        ...
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROA6JSEZBBBBBBB:[email protected]",
        "Arn": "arn:aws:sts::9826XXXXXXXX:assumed-role/Cognito_quicksightAuth_Role/[email protected]"
    }
}

I can show that the RoleSessionName is the issue in my flow, because I can make everything work by either a) creating a Quicksight user that has CognitoIdentityCredentials as the SessionName, or b) Explicitly assuming the role with the RoleSessionName through sts.assumeRole()

Am I wrong to expect that the call to AWS.config.getCredentials() would return a user with the passed RoleSessionName in the ARN?

1

1 Answers

0
votes

Short answer is yes. You are correct with the mentioned role-base use case. The comprehensive answer is as following.

The registerUser() API allows customer to create two types of user, role-base (--session-name) or galaxy-user (--user-name). The QuickSight user ARN are

role-base-user

arn:aws:quicksight:[region]:9826XXXXXXXX:user/[namespace]/[assumed-role-name]/[session-name]

galaxy-user

arn:aws:quicksight:[region]:9826XXXXXXXX:user/[namespace]/[user-name]

Use 'default' as namespace unless your account contains other namespace. Most account's region is 'us-east-1'.

Once you have the user, you can invoke GetDashboardEmbedUrl() API to retrieve the URL for a specific user. To do so, you can provide the --user-arn argument.

aws quicksight get-dashboard-embed-url --user-arn "arn:aws:quicksight:us-east-1:9826XXXXXXXX:user/..." ...

If --user-arn argument is not provided, the API will generates the role-base userARN from the caller's role-name and session-name. The call will fail if the userARN does not exist in the QuickSight account. That is what you are experiencing. I recommend the use of '--user-arn' argument for deterministic behavior.