question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

First-class support for AssumeRole in sessions

See original GitHub issue

This is similar to my request for https://github.com/boto/boto/issues/3381, but for the botocore credentials/session system.

When I first looked for this, I got my hopes up because I saw the AssumeRoleProvider in credentials.py, but then it turned out to be fairly awkward to use programmatically with dynamically specified role metadata, as it seemed to assume fairly deeply that you wanted to use it the way aws-cli does, via a config file and static credentials.

What I’d really like to see is composable/fully programmatic solution to this. It would probably use much of the same logic that’s already in AssumeRoleProvider, except with fewer assumptions about where the AssumeRole metadata information is coming from, and an API that makes it easy to create new assumed sessions from existing ones.

For example, here’s an API I might enjoy using:

# Gives me some default session using default credentials that have power 
# to AssumeRole into other accounts
session = botocore.session.get_session() 

session1 = session.assume_role_session('arn:aws:iam::1234567890:role/JumpRole',
    role_session_name='hostile-takeover')
session2 = session.assume_role_session('arn:aws:iam::1111111111:role/SomeOtherJumpRole',
    role_session_name='hostile-takeover')

# arn:aws:iam::1234567890:role/JumpRole has the power to itself assume a role
session3 = session1.assume_role_session('arn:aws:iam::222222222:role/JumpRole',
    role_session_name='hostile-takeover')

# Now we wait for a few hours
time.sleep(3600 * 5)

client3 = session3.create_client('ec2', region_name='us-west-2')

# This should work, and transparently refresh credentials as needed up the
# stack (in this case, two credential refreshes would be needed since we're
# two AssumeRoles deep)
print client3.describe_instances()

I don’t really care much about the API specifics, but I do want the entire AssumeRole session information to be (at least optionally) programmatic, and not implicitly loaded from some config file. The current AssumeRoleProvider also expects a source_profile which makes it hard to stack these things as I show above. Ideally, this would also work nicely with other AssumeRole variants, but that’s far less pressing for me.

cc @jamesls who I think wrote (or at least ported) AssumeRoleProvider in botocore.

Issue Analytics

  • State:open
  • Created 8 years ago
  • Reactions:30
  • Comments:24 (10 by maintainers)

github_iconTop GitHub Comments

8reactions
jstewmoncommented, Oct 1, 2018

FWIW, the code required to assume role has simplified over time. Here’s an example from one of my apps:

from botocore.credentials import (
    AssumeRoleCredentialFetcher,
    CredentialResolver,
    DeferredRefreshableCredentials,
    JSONFileCache
)
from botocore.session import Session


class AssumeRoleProvider(object):
    METHOD = 'assume-role'

    def __init__(self, fetcher):
        self._fetcher = fetcher

    def load(self):
        return DeferredRefreshableCredentials(
            self._fetcher.fetch_credentials,
            self.METHOD
        )


def assume_role(session: Session,
                role_arn: str,
                duration: int = 3600,
                session_name: str = None,
                serial_number: str = None) -> Session:
    fetcher = AssumeRoleCredentialFetcher(
        session.create_client,
        session.get_credentials(),
        role_arn,
        extra_args={
            'DurationSeconds': duration,
            'RoleSessionName': session_name,
            'SerialNumber': serial_number
        },
        cache=JSONFileCache()
    )
    role_session = Session()
    role_session.register_component(
        'credential_provider',
        CredentialResolver([AssumeRoleProvider(fetcher)])
    )
    return role_session

4reactions
vmksuwcommented, Oct 18, 2018

+1 for this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AssumeRole - AWS Security Token Service
Returns a set of temporary security credentials that you can use to access AWS resources that you might not normally have access to....
Read more >
How enable access to AWS STS AssumeRole - Stack Overflow
I ran a test with the policy simulator, to sts assume role, pointing to the ARN of role created at step one; and...
Read more >
AWS IAM deep dive: How roles work
First, the role has to define who is trusted (using the trust policy), then the identity (user or role) needs the sts:AssumeRole permission....
Read more >
boto3 Sessions, and Why You Should Use Them | by Ben Kehoe
The boto3.Session class, according to the docs, “ stores configuration state and allows you to create service clients and resources.” Most ...
Read more >
Mulesoft Kinesis Connector doesn't renew AWS session token ...
Well I think that is actually a bit strange that the connector doesn't support refresh tokens with assume role, as AWS session tokens...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found