Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws/session: Add support for AssumeRoles with MFA #1088

Merged
merged 10 commits into from
Feb 22, 2017

Conversation

jasdel
Copy link
Contributor

@jasdel jasdel commented Feb 18, 2017

Adds support for assuming IAM roles with MFA enabled. A TokenProvider
func was added tostscreds.AssumeRoleProvider that will be called each
time the role's credentials need to be refreshed. A basic token provider
that sources the MFA token from stdin as stscreds.StdinTokenProvider.

This change also adds a new session option, AssumeRoleTokenProvider.
The value of this field will be passed to the stscreds.AssumeRoleProvider
if the shared configuration is enabled and the config (~/.aws/config) or
credentials files (~/.aws/credentials) specify a role to assume
with MFA.

In order for the SDK to assume a role with MFA the SharedConfigState
session option must be set to SharedConfigEnable, or AWS_SDK_LOAD_CONFIG
environment variable set.

Creating an AssumeRoleProvider with MFA:

// Initial credentials loaded from SDK's default credential chain. Such as
// the environment, shared credentials (~/.aws/credentials), or EC2 Instance
// Role. These credentials will be used to to make the STS Assume Role API.
sess := session.Must(session.NewSession())

// Create the credentials from AssumeRoleProvider to assume the role
// referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin.
creds := stscreds.NewCredentials(sess, "myRoleARN", func(p *stscreds.AssumeRoleProvider) {
    p.SerialNumber = aws.String("myTokenSerialNumberOrARN")
    p.TokenProvider = stscreds.StdinTokenProvider
})

// Create service client value configured for credentials
// from assumed role.
svc := s3.New(sess, &aws.Config{Credentials: creds})

Creating a Session with shared config enabled to assume a role with MFA:

sess := session.Must(session.NewSessionWithOptions(session.Options{
    AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
    SharedConfigState:       session.SharedConfigEnable,
}))

// Create service client value configured for credentials
// from assumed role.
svc := s3.New(sess)

Fix #842
Related To hashicorp/terraform#9349

@@ -73,7 +73,7 @@ func New(cfgs ...*aws.Config) *Session {
return s
}

return oldNewSession(cfgs...)
return deprecatedNewSession(cfgs...)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, way better name

//
// This field is only used if the shared config enables assume role with
// MFA support.
AssumeRoleTokenProvider func() (string, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why this isn't an interface but a function pointer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switch here was focused on simplicity. Since an isolated piece of logic was being provided an function pointer was simpler and provided the same functionality.

@jasdel
Copy link
Contributor Author

jasdel commented Feb 20, 2017

Added more detailed docs and verified with the stdin token provider is able to assume roles that require MFA.

Adds support for assuming IAM roles with MFA enabled. A TokenProvider
func was added to stscreds.AssumeRoleProvider that will be called each
time the role's credentials need to be refreshed. A basic
token provider that sources the MFA token from stdin as
stscreds.StdinTokenProvider.

In addition when creating a session a new session option was added,
AssumeRoleTokenProvider. The value of this field will be passed to the
stscreds.AssumeRoleProvider if the shared config enables assume role
with MFA, and the SDK will be assuming the role. This allows you to
configure the SDK via the shared config to assume a role with MFA
tokens.

Note to use the SDK with the shared config and assume role the
SharedConfigState session option must be SharedConfigEnable, or the
AWS_SDK_LOAD_CONFIG environment variable set.

Assume role with MFA is enabled via the shared config when the
serial_number field is set.

Creating an AssumeRoleProvider with MFA

    // Initial credentials loaded from SDK's default credential chain. Such as
    // the environment, shared credentials (~/.aws/credentials), or EC2 Instance
    // Role. These credentials will be used to to make the STS Assume Role API.
    sess := session.Must(session.NewSession())

    // Create the credentials from AssumeRoleProvider to assume the role
    // referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin.
    creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
	p.SerialNumber = aws.String("myTokenSerialNumber")
	p.TokenProvider = stscreds.StdinTokenProvider
    })

    // Create service client value configured for credentials
    // from assumed role.
    svc := s3.New(sess, &aws.Config{Credentials: creds})

Creating a Session with shared config enabled to assume a role with MFA

    sess := session.Must(session.NewSessionWithOptions(session.Options{
	AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
	SharedConfigState:       session.SharedConfigEnable,
    }))

    // Create service client value configured for credentials
    // from assumed role.
    svc := s3.New(sess)

Fix # 842
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants