AWS amplify assume role in different AWS account

63 Views Asked by At

First of all apologies for the long post.

I have 2 AWS accounts and the scenario is like that:

  • The first AWS account (let's call it 1111) and cognito user pool is configured. This cognito user pool has a SAML integration with Okta. Also, there is cognito identity pool configured, which we use to grant access to a few AWS services to the authorized users.
  • I have a second AWS account (let's call it 2222) and I'd like to deploy an app which needs to use AWS transcribe.

What I want to achieve is that when the user is logging in through Okta (which lives in the account 1111), to provide temporary AWS credentials that give access to the account 2222.

The auth role for the identity pool is called dev-role-auth has this arn arn:aws:iam::1111:role/service-role/dev-role-auth and has these 2 policies attached:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cognito-identity:GetCredentialsForIdentity"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Resource": "arn:aws:iam::2222:role/authRoleToAssume",
            "Action": "sts:AssumeRole"
        }
    ]
}

and this trust policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "cognito-identity.amazonaws.com:aud": "eu-west-2:88aadf47-4e82-4a79-96ea-6adebbe8158c"
                },
                "ForAnyValue:StringLike": {
                    "cognito-identity.amazonaws.com:amr": "authenticated"
                }
            }
        }
    ]
}

On the account 2222, I have created the role with the name authRoleToAssume and the arn is arn:aws:iam::2222:role/authRoleToAssume.

The policy that I attached is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "transcribe:*",
            "Resource": "*"
        }
}

and the trust policy looks like that:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::1111:user/my.user",
                    "arn:aws:sts::1111:assumed-role/dev-role-auth/CognitoIdentityCredentials",
                    "arn:aws:iam::1111:role/service-role/dev-role-auth"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

You can see that I have created the user my.user to be able to check the assume role. I logged in the account 1111 with my.user I have switched my role to account 2222 by using the authRoleToAssume and I managed to use the real time transcription in the account 2222 with the user that exists in the account 1111. So this means that the trust policies are working.

Now my issue is with amplify. I have done the integration with cognito and okta with amplify auth. The users are able to login, get jwt tokens and get temporary AWS credentials. As soon as I have the AWS credentials, I'm using amplify predictions to kick off the real time transcription, but this is coming up with the error:

error "User: arn:aws:sts::1111:assumed-role/dev-role-auth/CognitoIdentityCredentials is not authorized to perform: transcribe:StartStreamTranscriptionWebSocket because no identity-based policy allows the transcribe:StartStreamTranscriptionWebSocket action."

This looks normal because the dev-role-auth does not give access to transcribe for the 1111 account. At this point I think that we need to use the temporary credentials to assume the role arn:aws:iam::2222:role/authRoleToAssume. I manage to do this with a bit of custom code and by using the javascript aws sdk:

import { AssumeRoleCommand } from "@aws-sdk/client-sts";

import defineClient from "./client";

// Credentials are the temp credentials that the user received from the identity pool
export const assumeRole = async (credentials) => {
  try {
    STSClient({
      region: 'eu-west-2',
      credentials: {
        accessKeyId: credentials.accessKeyId,
        secretAccessKey: credentials.secretAccessKey,
        sessionToken: credentials.sessionToken
      }
    });
    // Returns a set of temporary security credentials that you can use to
    // access Amazon Web Services resources that you might not normally
    // have access to.
    const command = new AssumeRoleCommand({
      // The Amazon Resource Name (ARN) of the role to assume.
      RoleArn: "arn:aws:iam::2222:role/authRoleToAssume",
      // An identifier for the assumed role session.
      RoleSessionName: "sessionTest1",
      // The duration, in seconds, of the role session. The value specified
      // can range from 900 seconds (15 minutes) up to the maximum session
      // duration set for the role.
      DurationSeconds: 900,
    });
    const response = await client.send(command);
    console.log('response', response);
    return response;
  } catch (err) {
    console.log('Error', err);
  }
};

I am able to retrieve the assumed credentials (at least there is no error thrown from the function above), but I don't know how to set those credentials within amplify. If we manage to set them within amplify, then amplify should be able to use the assumed credentials. We've tried to use those 2 approaches but with no luck:

Any guidance/help on how to assume the role or a completely different approach is highly appreciated.

0

There are 0 best solutions below