moto icon indicating copy to clipboard operation
moto copied to clipboard

sts should support cross account assume_role

Open itzaliza opened this issue 8 years ago • 1 comments

when calling sts.assume_role, identify if the role arn is pointing to another account and clear the state of all aws resources.

for example:

  1. create a lambda client and create a single function
  2. assume role to another account
  3. create a second lambda client with the credentials returned in step 2
  4. expect to find 0 lambda functions defined (as we are now using a client of another account)

example test case:


import unittest
import boto3
import zipfile
import io
from moto import mock_lambda, mock_iam, mock_sts


def _process_lambda(func_str):
    zip_output = io.BytesIO()
    zip_file = zipfile.ZipFile(zip_output, 'w', zipfile.ZIP_DEFLATED)
    zip_file.writestr('lambda_function.py', func_str)
    zip_file.close()
    zip_output.seek(0)
    return zip_output.read()


def get_test_zip_file1():
    pfunc = """
def lambda_handler(event, context):
    return event
"""
    return _process_lambda(pfunc)

class TestStsAssumeRole(unittest.TestCase):

    @mock_lambda
    @mock_sts
    def test_assume_role(self):
        print('test_assume_role')

        # create lambda function is current aws accoint
        client = boto3.client('lambda', region_name='us-east-1')
        self.create_test_function(client)

        # verify function exists
        functions = client.list_functions()
        self.assertEquals(len(functions['Functions']), 1)

        # assume role to another aws account
        sts = boto3.client('sts')
        response = sts.assume_role(RoleArn='test-arn-with-another-account-id', RoleSessionName='test-session-name', ExternalId='test-external-id')
        client2 = boto3.client('lambda',
                                     aws_access_key_id=response['Credentials']['AccessKeyId'],
                                     aws_secret_access_key=response['Credentials']['SecretAccessKey'],
                                     aws_session_token=response['Credentials']['SessionToken'],
                                     region_name='us-east-1')

        #client2 belongs to another account, where there are no lambda functions defined
        #expect to get 0 functions
        functions = client2.list_functions()
        print('functions=', functions)
        self.assertEquals(len(functions['Functions']), 0)

    def create_test_function(self, client):

        # create function

        response = client.create_function(
            FunctionName='test_function',
            Runtime='python2.7',
            Role='test_role',
            Handler='test_handler',
            Code={
                'ZipFile': get_test_zip_file1(),
            }
        )
        print('response=', response)

itzaliza avatar Nov 13 '17 11:11 itzaliza

Ok Moto has absolutely no concept of the current user, doing this would be a massive undertaking, though I agree would be great if it worked.

terricain avatar Nov 13 '17 11:11 terricain

This feature is now available as of Moto >= 4.0.0.dev3 - see the documentation here: http://docs.getmoto.org/en/latest/docs/multi_account.html

The full release schedule for Moto 4 can be found here: https://github.com/spulec/moto/issues/5366

Please let us know if you have any feedback.

bblommers avatar Aug 13 '22 11:08 bblommers

Moto 4.0.0 is now released containing this feature. Please let us know if you still encounter any issues around this.

bblommers avatar Aug 20 '22 10:08 bblommers