// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package sts

import (
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/request"
)

const opAssumeRole = "AssumeRole"

// AssumeRoleRequest generates a "aws/request.Request" representing the
// client's request for the AssumeRole operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AssumeRole for more information on using the AssumeRole
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AssumeRoleRequest method.
//    req, resp := client.AssumeRoleRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) {
	op := &request.Operation{
		Name:       opAssumeRole,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AssumeRoleInput{}
	}

	output = &AssumeRoleOutput{}
	req = c.newRequest(op, input, output)
	return
}

// AssumeRole API operation for 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. These temporary
// credentials consist of an access key ID, a secret access key, and a security
// token. Typically, you use AssumeRole within your account or for cross-account
// access. For a comparison of AssumeRole with other API operations that produce
// temporary credentials, see Requesting Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
// in the IAM User Guide.
//
// You cannot use AWS account root user credentials to call AssumeRole. You
// must use credentials for an IAM user or an IAM role to call AssumeRole.
//
// For cross-account access, imagine that you own multiple accounts and need
// to access resources in each account. You could create long-term credentials
// in each account to access those resources. However, managing all those credentials
// and remembering which one can access which account can be time consuming.
// Instead, you can create one set of long-term credentials in one account.
// Then use temporary security credentials to access all the other accounts
// by assuming roles in those accounts. For more information about roles, see
// IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)
// in the IAM User Guide.
//
// Session Duration
//
// By default, the temporary security credentials created by AssumeRole last
// for one hour. However, you can use the optional DurationSeconds parameter
// to specify the duration of your session. You can provide a value from 900
// seconds (15 minutes) up to the maximum session duration setting for the role.
// This setting can have a value from 1 hour to 12 hours. To learn how to view
// the maximum value for your role, see View the Maximum Session Duration Setting
// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
// in the IAM User Guide. The maximum session duration limit applies when you
// use the AssumeRole* API operations or the assume-role* CLI commands. However
// the limit does not apply when you use those operations to create a console
// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
// in the IAM User Guide.
//
// Permissions
//
// The temporary security credentials created by AssumeRole can be used to make
// API calls to any AWS service with the following exception: You cannot call
// the AWS STS GetFederationToken or GetSessionToken API operations.
//
// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline
// and managed session policies can't exceed 2,048 characters. Passing policies
// to this operation returns new temporary credentials. The resulting session's
// permissions are the intersection of the role's identity-based policy and
// the session policies. You can use the role's temporary credentials in subsequent
// AWS API calls to access resources in the account that owns the role. You
// cannot use session policies to grant more permissions than those allowed
// by the identity-based policy of the role that is being assumed. For more
// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide.
//
// To assume a role from a different account, your AWS account must be trusted
// by the role. The trust relationship is defined in the role's trust policy
// when the role is created. That trust policy states which accounts are allowed
// to delegate that access to users in the account.
//
// A user who wants to access a role in a different account must also have permissions
// that are delegated from the user account administrator. The administrator
// must attach a policy that allows the user to call AssumeRole for the ARN
// of the role in the other account. If the user is in the same account as the
// role, then you can do either of the following:
//
//    * Attach a policy to the user (identical to the previous user in a different
//    account).
//
//    * Add the user as a principal directly in the role's trust policy.
//
// In this case, the trust policy acts as an IAM resource-based policy. Users
// in the same account as the role do not need explicit permission to assume
// the role. For more information about trust policies and resource-based policies,
// see IAM Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)
// in the IAM User Guide.
//
// Tags
//
// (Optional) You can pass tag key-value pairs to your session. These tags are
// called session tags. For more information about session tags, see Passing
// Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// You can set the session tags as transitive. Transitive tags persist during
// role chaining. For more information, see Chaining Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// Using MFA with AssumeRole
//
// (Optional) You can include multi-factor authentication (MFA) information
// when you call AssumeRole. This is useful for cross-account scenarios to ensure
// that the user that assumes the role has been authenticated with an AWS MFA
// device. In that scenario, the trust policy of the role being assumed includes
// a condition that tests for MFA authentication. If the caller does not include
// valid MFA information, the request to assume the role is denied. The condition
// in a trust policy that tests for MFA authentication might look like the following
// example.
//
// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}}
//
// For more information, see Configuring MFA-Protected API Access (https://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html)
// in the IAM User Guide guide.
//
// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode
// parameters. The SerialNumber value identifies the user's hardware or virtual
// MFA device. The TokenCode is the time-based one-time password (TOTP) that
// the MFA device produces.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation AssumeRole for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
//   The request was rejected because the policy document was malformed. The error
//   message describes the specific error.
//
//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
//   The request was rejected because the total packed size of the session policies
//   and session tags combined was too large. An AWS conversion compresses the
//   session policy document, session policy ARNs, and session tags into a packed
//   binary format that has a separate limit. The error message indicates by percentage
//   how close the policies and tags are to the upper size limit. For more information,
//   see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
//   in the IAM User Guide.
//
//   You could receive this error even though you meet other defined session policy
//   and session tag limits. For more information, see IAM and STS Entity Character
//   Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
//   * ErrCodeRegionDisabledException "RegionDisabledException"
//   STS is not activated in the requested region for the account that is being
//   asked to generate credentials. The account administrator must use the IAM
//   console to activate STS in that region. For more information, see Activating
//   and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole
func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) {
	req, out := c.AssumeRoleRequest(input)
	return out, req.Send()
}

// AssumeRoleWithContext is the same as AssumeRole with the addition of
// the ability to pass a context and additional request options.
//
// See AssumeRole for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) AssumeRoleWithContext(ctx aws.Context, input *AssumeRoleInput, opts ...request.Option) (*AssumeRoleOutput, error) {
	req, out := c.AssumeRoleRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opAssumeRoleWithSAML = "AssumeRoleWithSAML"

// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the
// client's request for the AssumeRoleWithSAML operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AssumeRoleWithSAML for more information on using the AssumeRoleWithSAML
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AssumeRoleWithSAMLRequest method.
//    req, resp := client.AssumeRoleWithSAMLRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) {
	op := &request.Operation{
		Name:       opAssumeRoleWithSAML,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AssumeRoleWithSAMLInput{}
	}

	output = &AssumeRoleWithSAMLOutput{}
	req = c.newRequest(op, input, output)
	req.Config.Credentials = credentials.AnonymousCredentials
	return
}

// AssumeRoleWithSAML API operation for AWS Security Token Service.
//
// Returns a set of temporary security credentials for users who have been authenticated
// via a SAML authentication response. This operation provides a mechanism for
// tying an enterprise identity store or directory to role-based AWS access
// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML
// with the other API operations that produce temporary credentials, see Requesting
// Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
// in the IAM User Guide.
//
// The temporary security credentials returned by this operation consist of
// an access key ID, a secret access key, and a security token. Applications
// can use these temporary security credentials to sign calls to AWS services.
//
// Session Duration
//
// By default, the temporary security credentials created by AssumeRoleWithSAML
// last for one hour. However, you can use the optional DurationSeconds parameter
// to specify the duration of your session. Your role session lasts for the
// duration that you specify, or until the time specified in the SAML authentication
// response's SessionNotOnOrAfter value, whichever is shorter. You can provide
// a DurationSeconds value from 900 seconds (15 minutes) up to the maximum session
// duration setting for the role. This setting can have a value from 1 hour
// to 12 hours. To learn how to view the maximum value for your role, see View
// the Maximum Session Duration Setting for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
// in the IAM User Guide. The maximum session duration limit applies when you
// use the AssumeRole* API operations or the assume-role* CLI commands. However
// the limit does not apply when you use those operations to create a console
// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
// in the IAM User Guide.
//
// Permissions
//
// The temporary security credentials created by AssumeRoleWithSAML can be used
// to make API calls to any AWS service with the following exception: you cannot
// call the STS GetFederationToken or GetSessionToken API operations.
//
// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline
// and managed session policies can't exceed 2,048 characters. Passing policies
// to this operation returns new temporary credentials. The resulting session's
// permissions are the intersection of the role's identity-based policy and
// the session policies. You can use the role's temporary credentials in subsequent
// AWS API calls to access resources in the account that owns the role. You
// cannot use session policies to grant more permissions than those allowed
// by the identity-based policy of the role that is being assumed. For more
// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide.
//
// Calling AssumeRoleWithSAML does not require the use of AWS security credentials.
// The identity of the caller is validated by using keys in the metadata document
// that is uploaded for the SAML provider entity for your identity provider.
//
// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail
// logs. The entry includes the value in the NameID element of the SAML assertion.
// We recommend that you use a NameIDType that is not associated with any personally
// identifiable information (PII). For example, you could instead use the persistent
// identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent).
//
// Tags
//
// (Optional) You can configure your IdP to pass attributes into your SAML assertion
// as session tags. Each session tag consists of a key name and an associated
// value. For more information about session tags, see Passing Session Tags
// in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You can pass up to 50 session tags. The plain text session tag keys can’t
// exceed 128 characters and the values can’t exceed 256 characters. For these
// and additional limits, see IAM and STS Character Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
//
// You can pass a session tag with the same key as a tag that is attached to
// the role. When you do, session tags override the role's tags with the same
// key.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// You can set the session tags as transitive. Transitive tags persist during
// role chaining. For more information, see Chaining Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// SAML Configuration
//
// Before your application can call AssumeRoleWithSAML, you must configure your
// SAML identity provider (IdP) to issue the claims required by AWS. Additionally,
// you must use AWS Identity and Access Management (IAM) to create a SAML provider
// entity in your AWS account that represents your identity provider. You must
// also create an IAM role that specifies this SAML provider in its trust policy.
//
// For more information, see the following resources:
//
//    * About SAML 2.0-based Federation (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html)
//    in the IAM User Guide.
//
//    * Creating SAML Identity Providers (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html)
//    in the IAM User Guide.
//
//    * Configuring a Relying Party and Claims (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html)
//    in the IAM User Guide.
//
//    * Creating a Role for SAML 2.0 Federation (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html)
//    in the IAM User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation AssumeRoleWithSAML for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
//   The request was rejected because the policy document was malformed. The error
//   message describes the specific error.
//
//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
//   The request was rejected because the total packed size of the session policies
//   and session tags combined was too large. An AWS conversion compresses the
//   session policy document, session policy ARNs, and session tags into a packed
//   binary format that has a separate limit. The error message indicates by percentage
//   how close the policies and tags are to the upper size limit. For more information,
//   see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
//   in the IAM User Guide.
//
//   You could receive this error even though you meet other defined session policy
//   and session tag limits. For more information, see IAM and STS Entity Character
//   Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
//   * ErrCodeIDPRejectedClaimException "IDPRejectedClaim"
//   The identity provider (IdP) reported that authentication failed. This might
//   be because the claim is invalid.
//
//   If this error is returned for the AssumeRoleWithWebIdentity operation, it
//   can also mean that the claim has expired or has been explicitly revoked.
//
//   * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken"
//   The web identity token that was passed could not be validated by AWS. Get
//   a new identity token from the identity provider and then retry the request.
//
//   * ErrCodeExpiredTokenException "ExpiredTokenException"
//   The web identity token that was passed is expired or is not valid. Get a
//   new identity token from the identity provider and then retry the request.
//
//   * ErrCodeRegionDisabledException "RegionDisabledException"
//   STS is not activated in the requested region for the account that is being
//   asked to generate credentials. The account administrator must use the IAM
//   console to activate STS in that region. For more information, see Activating
//   and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML
func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) {
	req, out := c.AssumeRoleWithSAMLRequest(input)
	return out, req.Send()
}

// AssumeRoleWithSAMLWithContext is the same as AssumeRoleWithSAML with the addition of
// the ability to pass a context and additional request options.
//
// See AssumeRoleWithSAML for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) AssumeRoleWithSAMLWithContext(ctx aws.Context, input *AssumeRoleWithSAMLInput, opts ...request.Option) (*AssumeRoleWithSAMLOutput, error) {
	req, out := c.AssumeRoleWithSAMLRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity"

// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the
// client's request for the AssumeRoleWithWebIdentity operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AssumeRoleWithWebIdentity for more information on using the AssumeRoleWithWebIdentity
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AssumeRoleWithWebIdentityRequest method.
//    req, resp := client.AssumeRoleWithWebIdentityRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) {
	op := &request.Operation{
		Name:       opAssumeRoleWithWebIdentity,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AssumeRoleWithWebIdentityInput{}
	}

	output = &AssumeRoleWithWebIdentityOutput{}
	req = c.newRequest(op, input, output)
	req.Config.Credentials = credentials.AnonymousCredentials
	return
}

// AssumeRoleWithWebIdentity API operation for AWS Security Token Service.
//
// Returns a set of temporary security credentials for users who have been authenticated
// in a mobile or web application with a web identity provider. Example providers
// include Amazon Cognito, Login with Amazon, Facebook, Google, or any OpenID
// Connect-compatible identity provider.
//
// For mobile applications, we recommend that you use Amazon Cognito. You can
// use Amazon Cognito with the AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/)
// and the AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/)
// to uniquely identify a user. You can also supply the user with a consistent
// identity throughout the lifetime of an application.
//
// To learn more about Amazon Cognito, see Amazon Cognito Overview (https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840)
// in AWS SDK for Android Developer Guide and Amazon Cognito Overview (https://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664)
// in the AWS SDK for iOS Developer Guide.
//
// Calling AssumeRoleWithWebIdentity does not require the use of AWS security
// credentials. Therefore, you can distribute an application (for example, on
// mobile devices) that requests temporary security credentials without including
// long-term AWS credentials in the application. You also don't need to deploy
// server-based proxy services that use long-term AWS credentials. Instead,
// the identity of the caller is validated by using a token from the web identity
// provider. For a comparison of AssumeRoleWithWebIdentity with the other API
// operations that produce temporary credentials, see Requesting Temporary Security
// Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
// in the IAM User Guide.
//
// The temporary security credentials returned by this API consist of an access
// key ID, a secret access key, and a security token. Applications can use these
// temporary security credentials to sign calls to AWS service API operations.
//
// Session Duration
//
// By default, the temporary security credentials created by AssumeRoleWithWebIdentity
// last for one hour. However, you can use the optional DurationSeconds parameter
// to specify the duration of your session. You can provide a value from 900
// seconds (15 minutes) up to the maximum session duration setting for the role.
// This setting can have a value from 1 hour to 12 hours. To learn how to view
// the maximum value for your role, see View the Maximum Session Duration Setting
// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
// in the IAM User Guide. The maximum session duration limit applies when you
// use the AssumeRole* API operations or the assume-role* CLI commands. However
// the limit does not apply when you use those operations to create a console
// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
// in the IAM User Guide.
//
// Permissions
//
// The temporary security credentials created by AssumeRoleWithWebIdentity can
// be used to make API calls to any AWS service with the following exception:
// you cannot call the STS GetFederationToken or GetSessionToken API operations.
//
// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline
// and managed session policies can't exceed 2,048 characters. Passing policies
// to this operation returns new temporary credentials. The resulting session's
// permissions are the intersection of the role's identity-based policy and
// the session policies. You can use the role's temporary credentials in subsequent
// AWS API calls to access resources in the account that owns the role. You
// cannot use session policies to grant more permissions than those allowed
// by the identity-based policy of the role that is being assumed. For more
// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide.
//
// Tags
//
// (Optional) You can configure your IdP to pass attributes into your web identity
// token as session tags. Each session tag consists of a key name and an associated
// value. For more information about session tags, see Passing Session Tags
// in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You can pass up to 50 session tags. The plain text session tag keys can’t
// exceed 128 characters and the values can’t exceed 256 characters. For these
// and additional limits, see IAM and STS Character Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
//
// You can pass a session tag with the same key as a tag that is attached to
// the role. When you do, the session tag overrides the role tag with the same
// key.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// You can set the session tags as transitive. Transitive tags persist during
// role chaining. For more information, see Chaining Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// Identities
//
// Before your application can call AssumeRoleWithWebIdentity, you must have
// an identity token from a supported identity provider and create a role that
// the application can assume. The role that your application assumes must trust
// the identity provider that is associated with the identity token. In other
// words, the identity provider must be specified in the role's trust policy.
//
// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail
// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims)
// of the provided Web Identity Token. We recommend that you avoid using any
// personally identifiable information (PII) in this field. For example, you
// could instead use a GUID or a pairwise identifier, as suggested in the OIDC
// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes).
//
// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity
// API, see the following resources:
//
//    * Using Web Identity Federation API Operations for Mobile Apps (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html)
//    and Federation Through a Web-based Identity Provider (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity).
//
//    * Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html).
//    Walk through the process of authenticating through Login with Amazon,
//    Facebook, or Google, getting temporary security credentials, and then
//    using those credentials to make a request to AWS.
//
//    * AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) and
//    AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/).
//    These toolkits contain sample apps that show how to invoke the identity
//    providers. The toolkits then show how to use the information from these
//    providers to get and use temporary security credentials.
//
//    * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications).
//    This article discusses web identity federation and shows an example of
//    how to use web identity federation to get access to content in Amazon
//    S3.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation AssumeRoleWithWebIdentity for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
//   The request was rejected because the policy document was malformed. The error
//   message describes the specific error.
//
//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
//   The request was rejected because the total packed size of the session policies
//   and session tags combined was too large. An AWS conversion compresses the
//   session policy document, session policy ARNs, and session tags into a packed
//   binary format that has a separate limit. The error message indicates by percentage
//   how close the policies and tags are to the upper size limit. For more information,
//   see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
//   in the IAM User Guide.
//
//   You could receive this error even though you meet other defined session policy
//   and session tag limits. For more information, see IAM and STS Entity Character
//   Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
//   * ErrCodeIDPRejectedClaimException "IDPRejectedClaim"
//   The identity provider (IdP) reported that authentication failed. This might
//   be because the claim is invalid.
//
//   If this error is returned for the AssumeRoleWithWebIdentity operation, it
//   can also mean that the claim has expired or has been explicitly revoked.
//
//   * ErrCodeIDPCommunicationErrorException "IDPCommunicationError"
//   The request could not be fulfilled because the identity provider (IDP) that
//   was asked to verify the incoming identity token could not be reached. This
//   is often a transient error caused by network conditions. Retry the request
//   a limited number of times so that you don't exceed the request rate. If the
//   error persists, the identity provider might be down or not responding.
//
//   * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken"
//   The web identity token that was passed could not be validated by AWS. Get
//   a new identity token from the identity provider and then retry the request.
//
//   * ErrCodeExpiredTokenException "ExpiredTokenException"
//   The web identity token that was passed is expired or is not valid. Get a
//   new identity token from the identity provider and then retry the request.
//
//   * ErrCodeRegionDisabledException "RegionDisabledException"
//   STS is not activated in the requested region for the account that is being
//   asked to generate credentials. The account administrator must use the IAM
//   console to activate STS in that region. For more information, see Activating
//   and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity
func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) {
	req, out := c.AssumeRoleWithWebIdentityRequest(input)
	return out, req.Send()
}

// AssumeRoleWithWebIdentityWithContext is the same as AssumeRoleWithWebIdentity with the addition of
// the ability to pass a context and additional request options.
//
// See AssumeRoleWithWebIdentity for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) AssumeRoleWithWebIdentityWithContext(ctx aws.Context, input *AssumeRoleWithWebIdentityInput, opts ...request.Option) (*AssumeRoleWithWebIdentityOutput, error) {
	req, out := c.AssumeRoleWithWebIdentityRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage"

// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the
// client's request for the DecodeAuthorizationMessage operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DecodeAuthorizationMessage for more information on using the DecodeAuthorizationMessage
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DecodeAuthorizationMessageRequest method.
//    req, resp := client.DecodeAuthorizationMessageRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) {
	op := &request.Operation{
		Name:       opDecodeAuthorizationMessage,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DecodeAuthorizationMessageInput{}
	}

	output = &DecodeAuthorizationMessageOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DecodeAuthorizationMessage API operation for AWS Security Token Service.
//
// Decodes additional information about the authorization status of a request
// from an encoded message returned in response to an AWS request.
//
// For example, if a user is not authorized to perform an operation that he
// or she has requested, the request returns a Client.UnauthorizedOperation
// response (an HTTP 403 response). Some AWS operations additionally return
// an encoded message that can provide details about this authorization failure.
//
// Only certain AWS operations return an encoded authorization message. The
// documentation for an individual operation indicates whether that operation
// returns an encoded message in addition to returning an HTTP code.
//
// The message is encoded because the details of the authorization status can
// constitute privileged information that the user who requested the operation
// should not see. To decode an authorization status message, a user must be
// granted permissions via an IAM policy to request the DecodeAuthorizationMessage
// (sts:DecodeAuthorizationMessage) action.
//
// The decoded message includes the following type of information:
//
//    * Whether the request was denied due to an explicit deny or due to the
//    absence of an explicit allow. For more information, see Determining Whether
//    a Request is Allowed or Denied (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow)
//    in the IAM User Guide.
//
//    * The principal who made the request.
//
//    * The requested action.
//
//    * The requested resource.
//
//    * The values of condition keys in the context of the user's request.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation DecodeAuthorizationMessage for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidAuthorizationMessageException "InvalidAuthorizationMessageException"
//   The error returned if the message passed to DecodeAuthorizationMessage was
//   invalid. This can happen if the token contains invalid characters, such as
//   linebreaks.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) {
	req, out := c.DecodeAuthorizationMessageRequest(input)
	return out, req.Send()
}

// DecodeAuthorizationMessageWithContext is the same as DecodeAuthorizationMessage with the addition of
// the ability to pass a context and additional request options.
//
// See DecodeAuthorizationMessage for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) DecodeAuthorizationMessageWithContext(ctx aws.Context, input *DecodeAuthorizationMessageInput, opts ...request.Option) (*DecodeAuthorizationMessageOutput, error) {
	req, out := c.DecodeAuthorizationMessageRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetAccessKeyInfo = "GetAccessKeyInfo"

// GetAccessKeyInfoRequest generates a "aws/request.Request" representing the
// client's request for the GetAccessKeyInfo operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetAccessKeyInfo for more information on using the GetAccessKeyInfo
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetAccessKeyInfoRequest method.
//    req, resp := client.GetAccessKeyInfoRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetAccessKeyInfo
func (c *STS) GetAccessKeyInfoRequest(input *GetAccessKeyInfoInput) (req *request.Request, output *GetAccessKeyInfoOutput) {
	op := &request.Operation{
		Name:       opGetAccessKeyInfo,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetAccessKeyInfoInput{}
	}

	output = &GetAccessKeyInfoOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetAccessKeyInfo API operation for AWS Security Token Service.
//
// Returns the account identifier for the specified access key ID.
//
// Access keys consist of two parts: an access key ID (for example, AKIAIOSFODNN7EXAMPLE)
// and a secret access key (for example, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY).
// For more information about access keys, see Managing Access Keys for IAM
// Users (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)
// in the IAM User Guide.
//
// When you pass an access key ID to this operation, it returns the ID of the
// AWS account to which the keys belong. Access key IDs beginning with AKIA
// are long-term credentials for an IAM user or the AWS account root user. Access
// key IDs beginning with ASIA are temporary credentials that are created using
// STS operations. If the account in the response belongs to you, you can sign
// in as the root user and review your root user access keys. Then, you can
// pull a credentials report (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html)
// to learn which IAM user owns the keys. To learn who requested the temporary
// credentials for an ASIA access key, view the STS events in your CloudTrail
// logs (https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html)
// in the IAM User Guide.
//
// This operation does not indicate the state of the access key. The key might
// be active, inactive, or deleted. Active keys might not have permissions to
// perform an operation. Providing a deleted access key might return an error
// that the key doesn't exist.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation GetAccessKeyInfo for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetAccessKeyInfo
func (c *STS) GetAccessKeyInfo(input *GetAccessKeyInfoInput) (*GetAccessKeyInfoOutput, error) {
	req, out := c.GetAccessKeyInfoRequest(input)
	return out, req.Send()
}

// GetAccessKeyInfoWithContext is the same as GetAccessKeyInfo with the addition of
// the ability to pass a context and additional request options.
//
// See GetAccessKeyInfo for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) GetAccessKeyInfoWithContext(ctx aws.Context, input *GetAccessKeyInfoInput, opts ...request.Option) (*GetAccessKeyInfoOutput, error) {
	req, out := c.GetAccessKeyInfoRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetCallerIdentity = "GetCallerIdentity"

// GetCallerIdentityRequest generates a "aws/request.Request" representing the
// client's request for the GetCallerIdentity operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetCallerIdentity for more information on using the GetCallerIdentity
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetCallerIdentityRequest method.
//    req, resp := client.GetCallerIdentityRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) {
	op := &request.Operation{
		Name:       opGetCallerIdentity,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetCallerIdentityInput{}
	}

	output = &GetCallerIdentityOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetCallerIdentity API operation for AWS Security Token Service.
//
// Returns details about the IAM user or role whose credentials are used to
// call the operation.
//
// No permissions are required to perform this operation. If an administrator
// adds a policy to your IAM user or role that explicitly denies access to the
// sts:GetCallerIdentity action, you can still perform this operation. Permissions
// are not required because the same information is returned when an IAM user
// or role is denied access. To view an example response, see I Am Not Authorized
// to Perform: iam:DeleteVirtualMFADevice (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa)
// in the IAM User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation GetCallerIdentity for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity
func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) {
	req, out := c.GetCallerIdentityRequest(input)
	return out, req.Send()
}

// GetCallerIdentityWithContext is the same as GetCallerIdentity with the addition of
// the ability to pass a context and additional request options.
//
// See GetCallerIdentity for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) GetCallerIdentityWithContext(ctx aws.Context, input *GetCallerIdentityInput, opts ...request.Option) (*GetCallerIdentityOutput, error) {
	req, out := c.GetCallerIdentityRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetFederationToken = "GetFederationToken"

// GetFederationTokenRequest generates a "aws/request.Request" representing the
// client's request for the GetFederationToken operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetFederationToken for more information on using the GetFederationToken
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetFederationTokenRequest method.
//    req, resp := client.GetFederationTokenRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) {
	op := &request.Operation{
		Name:       opGetFederationToken,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetFederationTokenInput{}
	}

	output = &GetFederationTokenOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetFederationToken API operation for AWS Security Token Service.
//
// Returns a set of temporary security credentials (consisting of an access
// key ID, a secret access key, and a security token) for a federated user.
// A typical use is in a proxy application that gets temporary security credentials
// on behalf of distributed applications inside a corporate network. You must
// call the GetFederationToken operation using the long-term security credentials
// of an IAM user. As a result, this call is appropriate in contexts where those
// credentials can be safely stored, usually in a server-based application.
// For a comparison of GetFederationToken with the other API operations that
// produce temporary credentials, see Requesting Temporary Security Credentials
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
// in the IAM User Guide.
//
// You can create a mobile-based or browser-based app that can authenticate
// users using a web identity provider like Login with Amazon, Facebook, Google,
// or an OpenID Connect-compatible identity provider. In this case, we recommend
// that you use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity.
// For more information, see Federation Through a Web-based Identity Provider
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity)
// in the IAM User Guide.
//
// You can also call GetFederationToken using the security credentials of an
// AWS account root user, but we do not recommend it. Instead, we recommend
// that you create an IAM user for the purpose of the proxy application. Then
// attach a policy to the IAM user that limits federated users to only the actions
// and resources that they need to access. For more information, see IAM Best
// Practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
// in the IAM User Guide.
//
// Session duration
//
// The temporary credentials are valid for the specified duration, from 900
// seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours). The default
// session duration is 43,200 seconds (12 hours). Temporary credentials that
// are obtained by using AWS account root user credentials have a maximum duration
// of 3,600 seconds (1 hour).
//
// Permissions
//
// You can use the temporary credentials created by GetFederationToken in any
// AWS service except the following:
//
//    * You cannot call any IAM operations using the AWS CLI or the AWS API.
//
//    * You cannot call any STS operations except GetCallerIdentity.
//
// You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline
// and managed session policies can't exceed 2,048 characters.
//
// Though the session policy parameters are optional, if you do not pass a policy,
// then the resulting federated user session has no permissions. When you pass
// session policies, the session permissions are the intersection of the IAM
// user policies and the session policies that you pass. This gives you a way
// to further restrict the permissions for a federated user. You cannot use
// session policies to grant more permissions than those that are defined in
// the permissions policy of the IAM user. For more information, see Session
// Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide. For information about using GetFederationToken to
// create temporary security credentials, see GetFederationToken—Federation
// Through a Custom Identity Broker (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken).
//
// You can use the credentials to access a resource that has a resource-based
// policy. If that policy specifically references the federated user session
// in the Principal element of the policy, the session has the permissions allowed
// by the policy. These permissions are granted in addition to the permissions
// granted by the session policies.
//
// Tags
//
// (Optional) You can pass tag key-value pairs to your session. These are called
// session tags. For more information about session tags, see Passing Session
// Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// Tag key–value pairs are not case sensitive, but case is preserved. This
// means that you cannot have separate Department and department tag keys. Assume
// that the user that you are federating has the Department=Marketing tag and
// you pass the department=engineering session tag. Department and department
// are not saved as separate tags, and the session tag passed in the request
// takes precedence over the user tag.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation GetFederationToken for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument"
//   The request was rejected because the policy document was malformed. The error
//   message describes the specific error.
//
//   * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
//   The request was rejected because the total packed size of the session policies
//   and session tags combined was too large. An AWS conversion compresses the
//   session policy document, session policy ARNs, and session tags into a packed
//   binary format that has a separate limit. The error message indicates by percentage
//   how close the policies and tags are to the upper size limit. For more information,
//   see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
//   in the IAM User Guide.
//
//   You could receive this error even though you meet other defined session policy
//   and session tag limits. For more information, see IAM and STS Entity Character
//   Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
//   * ErrCodeRegionDisabledException "RegionDisabledException"
//   STS is not activated in the requested region for the account that is being
//   asked to generate credentials. The account administrator must use the IAM
//   console to activate STS in that region. For more information, see Activating
//   and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken
func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) {
	req, out := c.GetFederationTokenRequest(input)
	return out, req.Send()
}

// GetFederationTokenWithContext is the same as GetFederationToken with the addition of
// the ability to pass a context and additional request options.
//
// See GetFederationToken for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) GetFederationTokenWithContext(ctx aws.Context, input *GetFederationTokenInput, opts ...request.Option) (*GetFederationTokenOutput, error) {
	req, out := c.GetFederationTokenRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetSessionToken = "GetSessionToken"

// GetSessionTokenRequest generates a "aws/request.Request" representing the
// client's request for the GetSessionToken operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetSessionToken for more information on using the GetSessionToken
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetSessionTokenRequest method.
//    req, resp := client.GetSessionTokenRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) {
	op := &request.Operation{
		Name:       opGetSessionToken,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetSessionTokenInput{}
	}

	output = &GetSessionTokenOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetSessionToken API operation for AWS Security Token Service.
//
// Returns a set of temporary credentials for an AWS account or IAM user. The
// credentials consist of an access key ID, a secret access key, and a security
// token. Typically, you use GetSessionToken if you want to use MFA to protect
// programmatic calls to specific AWS API operations like Amazon EC2 StopInstances.
// MFA-enabled IAM users would need to call GetSessionToken and submit an MFA
// code that is associated with their MFA device. Using the temporary security
// credentials that are returned from the call, IAM users can then make programmatic
// calls to API operations that require MFA authentication. If you do not supply
// a correct MFA code, then the API returns an access denied error. For a comparison
// of GetSessionToken with the other API operations that produce temporary credentials,
// see Requesting Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
// in the IAM User Guide.
//
// Session Duration
//
// The GetSessionToken operation must be called by using the long-term AWS security
// credentials of the AWS account root user or an IAM user. Credentials that
// are created by IAM users are valid for the duration that you specify. This
// duration can range from 900 seconds (15 minutes) up to a maximum of 129,600
// seconds (36 hours), with a default of 43,200 seconds (12 hours). Credentials
// based on account credentials can range from 900 seconds (15 minutes) up to
// 3,600 seconds (1 hour), with a default of 1 hour.
//
// Permissions
//
// The temporary security credentials created by GetSessionToken can be used
// to make API calls to any AWS service with the following exceptions:
//
//    * You cannot call any IAM API operations unless MFA authentication information
//    is included in the request.
//
//    * You cannot call any STS API except AssumeRole or GetCallerIdentity.
//
// We recommend that you do not call GetSessionToken with AWS account root user
// credentials. Instead, follow our best practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users)
// by creating one or more IAM users, giving them the necessary permissions,
// and using IAM users for everyday interaction with AWS.
//
// The credentials that are returned by GetSessionToken are based on permissions
// associated with the user whose credentials were used to call the operation.
// If GetSessionToken is called using AWS account root user credentials, the
// temporary credentials have root user permissions. Similarly, if GetSessionToken
// is called using the credentials of an IAM user, the temporary credentials
// have the same permissions as the IAM user.
//
// For more information about using GetSessionToken to create temporary credentials,
// go to Temporary Credentials for Users in Untrusted Environments (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken)
// in the IAM User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for AWS Security Token Service's
// API operation GetSessionToken for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeRegionDisabledException "RegionDisabledException"
//   STS is not activated in the requested region for the account that is being
//   asked to generate credentials. The account administrator must use the IAM
//   console to activate STS in that region. For more information, see Activating
//   and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
//   in the IAM User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken
func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) {
	req, out := c.GetSessionTokenRequest(input)
	return out, req.Send()
}

// GetSessionTokenWithContext is the same as GetSessionToken with the addition of
// the ability to pass a context and additional request options.
//
// See GetSessionToken for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionTokenInput, opts ...request.Option) (*GetSessionTokenOutput, error) {
	req, out := c.GetSessionTokenRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

type AssumeRoleInput struct {
	_ struct{} `type:"structure"`

	// The duration, in seconds, of the role session. The value can range from 900
	// seconds (15 minutes) up to the maximum session duration setting for the role.
	// This setting can have a value from 1 hour to 12 hours. If you specify a value
	// higher than this setting, the operation fails. For example, if you specify
	// a session duration of 12 hours, but your administrator set the maximum session
	// duration to 6 hours, your operation fails. To learn how to view the maximum
	// value for your role, see View the Maximum Session Duration Setting for a
	// Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
	// in the IAM User Guide.
	//
	// By default, the value is set to 3600 seconds.
	//
	// The DurationSeconds parameter is separate from the duration of a console
	// session that you might request using the returned credentials. The request
	// to the federation endpoint for a console sign-in token takes a SessionDuration
	// parameter that specifies the maximum length of the console session. For more
	// information, see Creating a URL that Enables Federated Users to Access the
	// AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html)
	// in the IAM User Guide.
	DurationSeconds *int64 `min:"900" type:"integer"`

	// A unique identifier that might be required when you assume a role in another
	// account. If the administrator of the account to which the role belongs provided
	// you with an external ID, then provide that value in the ExternalId parameter.
	// This value can be any string, such as a passphrase or account number. A cross-account
	// role is usually set up to trust everyone in an account. Therefore, the administrator
	// of the trusting account might send an external ID to the administrator of
	// the trusted account. That way, only someone with the ID can assume the role,
	// rather than everyone in the account. For more information about the external
	// ID, see How to Use an External ID When Granting Access to Your AWS Resources
	// to a Third Party (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)
	// in the IAM User Guide.
	//
	// The regex used to validate this parameter is a string of characters consisting
	// of upper- and lower-case alphanumeric characters with no spaces. You can
	// also include underscores or any of the following characters: =,.@:/-
	ExternalId *string `min:"2" type:"string"`

	// An IAM policy in JSON format that you want to use as an inline session policy.
	//
	// This parameter is optional. Passing policies to this operation returns new
	// temporary credentials. The resulting session's permissions are the intersection
	// of the role's identity-based policy and the session policies. You can use
	// the role's temporary credentials in subsequent AWS API calls to access resources
	// in the account that owns the role. You cannot use session policies to grant
	// more permissions than those allowed by the identity-based policy of the role
	// that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	//
	// The plain text that you use for both inline and managed session policies
	// can't exceed 2,048 characters. The JSON policy characters can be any ASCII
	// character from the space character to the end of the valid character list
	// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
	// and carriage return (\u000D) characters.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	Policy *string `min:"1" type:"string"`

	// The Amazon Resource Names (ARNs) of the IAM managed policies that you want
	// to use as managed session policies. The policies must exist in the same account
	// as the role.
	//
	// This parameter is optional. You can provide up to 10 managed policy ARNs.
	// However, the plain text that you use for both inline and managed session
	// policies can't exceed 2,048 characters. For more information about ARNs,
	// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// in the AWS General Reference.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	//
	// Passing policies to this operation returns new temporary credentials. The
	// resulting session's permissions are the intersection of the role's identity-based
	// policy and the session policies. You can use the role's temporary credentials
	// in subsequent AWS API calls to access resources in the account that owns
	// the role. You cannot use session policies to grant more permissions than
	// those allowed by the identity-based policy of the role that is being assumed.
	// For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	PolicyArns []*PolicyDescriptorType `type:"list"`

	// The Amazon Resource Name (ARN) of the role to assume.
	//
	// RoleArn is a required field
	RoleArn *string `min:"20" type:"string" required:"true"`

	// An identifier for the assumed role session.
	//
	// Use the role session name to uniquely identify a session when the same role
	// is assumed by different principals or for different reasons. In cross-account
	// scenarios, the role session name is visible to, and can be logged by the
	// account that owns the role. The role session name is also used in the ARN
	// of the assumed role principal. This means that subsequent cross-account API
	// requests that use the temporary security credentials will expose the role
	// session name to the external account in their AWS CloudTrail logs.
	//
	// The regex used to validate this parameter is a string of characters consisting
	// of upper- and lower-case alphanumeric characters with no spaces. You can
	// also include underscores or any of the following characters: =,.@-
	//
	// RoleSessionName is a required field
	RoleSessionName *string `min:"2" type:"string" required:"true"`

	// The identification number of the MFA device that is associated with the user
	// who is making the AssumeRole call. Specify this value if the trust policy
	// of the role being assumed includes a condition that requires MFA authentication.
	// The value is either the serial number for a hardware device (such as GAHT12345678)
	// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
	//
	// The regex used to validate this parameter is a string of characters consisting
	// of upper- and lower-case alphanumeric characters with no spaces. You can
	// also include underscores or any of the following characters: =,.@-
	SerialNumber *string `min:"9" type:"string"`

	// A list of session tags that you want to pass. Each session tag consists of
	// a key name and an associated value. For more information about session tags,
	// see Tagging AWS STS Sessions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
	// in the IAM User Guide.
	//
	// This parameter is optional. You can pass up to 50 session tags. The plain
	// text session tag keys can’t exceed 128 characters, and the values can’t
	// exceed 256 characters. For these and additional limits, see IAM and STS Character
	// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
	// in the IAM User Guide.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	//
	// You can pass a session tag with the same key as a tag that is already attached
	// to the role. When you do, session tags override a role tag with the same
	// key.
	//
	// Tag key–value pairs are not case sensitive, but case is preserved. This
	// means that you cannot have separate Department and department tag keys. Assume
	// that the role has the Department=Marketing tag and you pass the department=engineering
	// session tag. Department and department are not saved as separate tags, and
	// the session tag passed in the request takes precedence over the role tag.
	//
	// Additionally, if you used temporary credentials to perform this operation,
	// the new session inherits any transitive session tags from the calling session.
	// If you pass a session tag with the same key as an inherited tag, the operation
	// fails. To view the inherited tags for a session, see the AWS CloudTrail logs.
	// For more information, see Viewing Session Tags in CloudTrail (https://docs.aws.amazon.com/IAM/latest/UserGuide/session-tags.html#id_session-tags_ctlogs)
	// in the IAM User Guide.
	Tags []*Tag `type:"list"`

	// The value provided by the MFA device, if the trust policy of the role being
	// assumed requires MFA (that is, if the policy includes a condition that tests
	// for MFA). If the role being assumed requires MFA and if the TokenCode value
	// is missing or expired, the AssumeRole call returns an "access denied" error.
	//
	// The format for this parameter, as described by its regex pattern, is a sequence
	// of six numeric digits.
	TokenCode *string `min:"6" type:"string"`

	// A list of keys for session tags that you want to set as transitive. If you
	// set a tag key as transitive, the corresponding key and value passes to subsequent
	// sessions in a role chain. For more information, see Chaining Roles with Session
	// Tags (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
	// in the IAM User Guide.
	//
	// This parameter is optional. When you set session tags as transitive, the
	// session policy and session tags packed binary limit is not affected.
	//
	// If you choose not to specify a transitive tag key, then no tags are passed
	// from this session to any subsequent sessions.
	TransitiveTagKeys []*string `type:"list"`
}

// String returns the string representation
func (s AssumeRoleInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumeRoleInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AssumeRoleInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AssumeRoleInput"}
	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
	}
	if s.ExternalId != nil && len(*s.ExternalId) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("ExternalId", 2))
	}
	if s.Policy != nil && len(*s.Policy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
	}
	if s.RoleArn == nil {
		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
	}
	if s.RoleArn != nil && len(*s.RoleArn) < 20 {
		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
	}
	if s.RoleSessionName == nil {
		invalidParams.Add(request.NewErrParamRequired("RoleSessionName"))
	}
	if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2))
	}
	if s.SerialNumber != nil && len(*s.SerialNumber) < 9 {
		invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9))
	}
	if s.TokenCode != nil && len(*s.TokenCode) < 6 {
		invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6))
	}
	if s.PolicyArns != nil {
		for i, v := range s.PolicyArns {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams))
			}
		}
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDurationSeconds sets the DurationSeconds field's value.
func (s *AssumeRoleInput) SetDurationSeconds(v int64) *AssumeRoleInput {
	s.DurationSeconds = &v
	return s
}

// SetExternalId sets the ExternalId field's value.
func (s *AssumeRoleInput) SetExternalId(v string) *AssumeRoleInput {
	s.ExternalId = &v
	return s
}

// SetPolicy sets the Policy field's value.
func (s *AssumeRoleInput) SetPolicy(v string) *AssumeRoleInput {
	s.Policy = &v
	return s
}

// SetPolicyArns sets the PolicyArns field's value.
func (s *AssumeRoleInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleInput {
	s.PolicyArns = v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *AssumeRoleInput) SetRoleArn(v string) *AssumeRoleInput {
	s.RoleArn = &v
	return s
}

// SetRoleSessionName sets the RoleSessionName field's value.
func (s *AssumeRoleInput) SetRoleSessionName(v string) *AssumeRoleInput {
	s.RoleSessionName = &v
	return s
}

// SetSerialNumber sets the SerialNumber field's value.
func (s *AssumeRoleInput) SetSerialNumber(v string) *AssumeRoleInput {
	s.SerialNumber = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *AssumeRoleInput) SetTags(v []*Tag) *AssumeRoleInput {
	s.Tags = v
	return s
}

// SetTokenCode sets the TokenCode field's value.
func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput {
	s.TokenCode = &v
	return s
}

// SetTransitiveTagKeys sets the TransitiveTagKeys field's value.
func (s *AssumeRoleInput) SetTransitiveTagKeys(v []*string) *AssumeRoleInput {
	s.TransitiveTagKeys = v
	return s
}

// Contains the response to a successful AssumeRole request, including temporary
// AWS credentials that can be used to make AWS requests.
type AssumeRoleOutput struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
	// that you can use to refer to the resulting temporary security credentials.
	// For example, you can reference these credentials as a principal in a resource-based
	// policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName
	// that you specified when you called AssumeRole.
	AssumedRoleUser *AssumedRoleUser `type:"structure"`

	// The temporary security credentials, which include an access key ID, a secret
	// access key, and a security (or session) token.
	//
	// The size of the security token that STS API operations return is not fixed.
	// We strongly recommend that you make no assumptions about the maximum size.
	Credentials *Credentials `type:"structure"`

	// A percentage value that indicates the packed size of the session policies
	// and session tags combined passed in the request. The request fails if the
	// packed size is greater than 100 percent, which means the policies and tags
	// exceeded the allowed space.
	PackedPolicySize *int64 `type:"integer"`
}

// String returns the string representation
func (s AssumeRoleOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumeRoleOutput) GoString() string {
	return s.String()
}

// SetAssumedRoleUser sets the AssumedRoleUser field's value.
func (s *AssumeRoleOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleOutput {
	s.AssumedRoleUser = v
	return s
}

// SetCredentials sets the Credentials field's value.
func (s *AssumeRoleOutput) SetCredentials(v *Credentials) *AssumeRoleOutput {
	s.Credentials = v
	return s
}

// SetPackedPolicySize sets the PackedPolicySize field's value.
func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput {
	s.PackedPolicySize = &v
	return s
}

type AssumeRoleWithSAMLInput struct {
	_ struct{} `type:"structure"`

	// The duration, in seconds, of the role session. Your role session lasts for
	// the duration that you specify for the DurationSeconds parameter, or until
	// the time specified in the SAML authentication response's SessionNotOnOrAfter
	// value, whichever is shorter. You can provide a DurationSeconds value from
	// 900 seconds (15 minutes) up to the maximum session duration setting for the
	// role. This setting can have a value from 1 hour to 12 hours. If you specify
	// a value higher than this setting, the operation fails. For example, if you
	// specify a session duration of 12 hours, but your administrator set the maximum
	// session duration to 6 hours, your operation fails. To learn how to view the
	// maximum value for your role, see View the Maximum Session Duration Setting
	// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
	// in the IAM User Guide.
	//
	// By default, the value is set to 3600 seconds.
	//
	// The DurationSeconds parameter is separate from the duration of a console
	// session that you might request using the returned credentials. The request
	// to the federation endpoint for a console sign-in token takes a SessionDuration
	// parameter that specifies the maximum length of the console session. For more
	// information, see Creating a URL that Enables Federated Users to Access the
	// AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html)
	// in the IAM User Guide.
	DurationSeconds *int64 `min:"900" type:"integer"`

	// An IAM policy in JSON format that you want to use as an inline session policy.
	//
	// This parameter is optional. Passing policies to this operation returns new
	// temporary credentials. The resulting session's permissions are the intersection
	// of the role's identity-based policy and the session policies. You can use
	// the role's temporary credentials in subsequent AWS API calls to access resources
	// in the account that owns the role. You cannot use session policies to grant
	// more permissions than those allowed by the identity-based policy of the role
	// that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	//
	// The plain text that you use for both inline and managed session policies
	// can't exceed 2,048 characters. The JSON policy characters can be any ASCII
	// character from the space character to the end of the valid character list
	// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
	// and carriage return (\u000D) characters.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	Policy *string `min:"1" type:"string"`

	// The Amazon Resource Names (ARNs) of the IAM managed policies that you want
	// to use as managed session policies. The policies must exist in the same account
	// as the role.
	//
	// This parameter is optional. You can provide up to 10 managed policy ARNs.
	// However, the plain text that you use for both inline and managed session
	// policies can't exceed 2,048 characters. For more information about ARNs,
	// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// in the AWS General Reference.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	//
	// Passing policies to this operation returns new temporary credentials. The
	// resulting session's permissions are the intersection of the role's identity-based
	// policy and the session policies. You can use the role's temporary credentials
	// in subsequent AWS API calls to access resources in the account that owns
	// the role. You cannot use session policies to grant more permissions than
	// those allowed by the identity-based policy of the role that is being assumed.
	// For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	PolicyArns []*PolicyDescriptorType `type:"list"`

	// The Amazon Resource Name (ARN) of the SAML provider in IAM that describes
	// the IdP.
	//
	// PrincipalArn is a required field
	PrincipalArn *string `min:"20" type:"string" required:"true"`

	// The Amazon Resource Name (ARN) of the role that the caller is assuming.
	//
	// RoleArn is a required field
	RoleArn *string `min:"20" type:"string" required:"true"`

	// The base-64 encoded SAML authentication response provided by the IdP.
	//
	// For more information, see Configuring a Relying Party and Adding Claims (https://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html)
	// in the IAM User Guide.
	//
	// SAMLAssertion is a required field
	SAMLAssertion *string `min:"4" type:"string" required:"true"`
}

// String returns the string representation
func (s AssumeRoleWithSAMLInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumeRoleWithSAMLInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AssumeRoleWithSAMLInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"}
	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
	}
	if s.Policy != nil && len(*s.Policy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
	}
	if s.PrincipalArn == nil {
		invalidParams.Add(request.NewErrParamRequired("PrincipalArn"))
	}
	if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 {
		invalidParams.Add(request.NewErrParamMinLen("PrincipalArn", 20))
	}
	if s.RoleArn == nil {
		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
	}
	if s.RoleArn != nil && len(*s.RoleArn) < 20 {
		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
	}
	if s.SAMLAssertion == nil {
		invalidParams.Add(request.NewErrParamRequired("SAMLAssertion"))
	}
	if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 {
		invalidParams.Add(request.NewErrParamMinLen("SAMLAssertion", 4))
	}
	if s.PolicyArns != nil {
		for i, v := range s.PolicyArns {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDurationSeconds sets the DurationSeconds field's value.
func (s *AssumeRoleWithSAMLInput) SetDurationSeconds(v int64) *AssumeRoleWithSAMLInput {
	s.DurationSeconds = &v
	return s
}

// SetPolicy sets the Policy field's value.
func (s *AssumeRoleWithSAMLInput) SetPolicy(v string) *AssumeRoleWithSAMLInput {
	s.Policy = &v
	return s
}

// SetPolicyArns sets the PolicyArns field's value.
func (s *AssumeRoleWithSAMLInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleWithSAMLInput {
	s.PolicyArns = v
	return s
}

// SetPrincipalArn sets the PrincipalArn field's value.
func (s *AssumeRoleWithSAMLInput) SetPrincipalArn(v string) *AssumeRoleWithSAMLInput {
	s.PrincipalArn = &v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *AssumeRoleWithSAMLInput) SetRoleArn(v string) *AssumeRoleWithSAMLInput {
	s.RoleArn = &v
	return s
}

// SetSAMLAssertion sets the SAMLAssertion field's value.
func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAMLInput {
	s.SAMLAssertion = &v
	return s
}

// Contains the response to a successful AssumeRoleWithSAML request, including
// temporary AWS credentials that can be used to make AWS requests.
type AssumeRoleWithSAMLOutput struct {
	_ struct{} `type:"structure"`

	// The identifiers for the temporary security credentials that the operation
	// returns.
	AssumedRoleUser *AssumedRoleUser `type:"structure"`

	// The value of the Recipient attribute of the SubjectConfirmationData element
	// of the SAML assertion.
	Audience *string `type:"string"`

	// The temporary security credentials, which include an access key ID, a secret
	// access key, and a security (or session) token.
	//
	// The size of the security token that STS API operations return is not fixed.
	// We strongly recommend that you make no assumptions about the maximum size.
	Credentials *Credentials `type:"structure"`

	// The value of the Issuer element of the SAML assertion.
	Issuer *string `type:"string"`

	// A hash value based on the concatenation of the Issuer response value, the
	// AWS account ID, and the friendly name (the last part of the ARN) of the SAML
	// provider in IAM. The combination of NameQualifier and Subject can be used
	// to uniquely identify a federated user.
	//
	// The following pseudocode shows how the hash value is calculated:
	//
	// BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP"
	// ) )
	NameQualifier *string `type:"string"`

	// A percentage value that indicates the packed size of the session policies
	// and session tags combined passed in the request. The request fails if the
	// packed size is greater than 100 percent, which means the policies and tags
	// exceeded the allowed space.
	PackedPolicySize *int64 `type:"integer"`

	// The value of the NameID element in the Subject element of the SAML assertion.
	Subject *string `type:"string"`

	// The format of the name ID, as defined by the Format attribute in the NameID
	// element of the SAML assertion. Typical examples of the format are transient
	// or persistent.
	//
	// If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format,
	// that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient
	// is returned as transient. If the format includes any other prefix, the format
	// is returned with no modifications.
	SubjectType *string `type:"string"`
}

// String returns the string representation
func (s AssumeRoleWithSAMLOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumeRoleWithSAMLOutput) GoString() string {
	return s.String()
}

// SetAssumedRoleUser sets the AssumedRoleUser field's value.
func (s *AssumeRoleWithSAMLOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithSAMLOutput {
	s.AssumedRoleUser = v
	return s
}

// SetAudience sets the Audience field's value.
func (s *AssumeRoleWithSAMLOutput) SetAudience(v string) *AssumeRoleWithSAMLOutput {
	s.Audience = &v
	return s
}

// SetCredentials sets the Credentials field's value.
func (s *AssumeRoleWithSAMLOutput) SetCredentials(v *Credentials) *AssumeRoleWithSAMLOutput {
	s.Credentials = v
	return s
}

// SetIssuer sets the Issuer field's value.
func (s *AssumeRoleWithSAMLOutput) SetIssuer(v string) *AssumeRoleWithSAMLOutput {
	s.Issuer = &v
	return s
}

// SetNameQualifier sets the NameQualifier field's value.
func (s *AssumeRoleWithSAMLOutput) SetNameQualifier(v string) *AssumeRoleWithSAMLOutput {
	s.NameQualifier = &v
	return s
}

// SetPackedPolicySize sets the PackedPolicySize field's value.
func (s *AssumeRoleWithSAMLOutput) SetPackedPolicySize(v int64) *AssumeRoleWithSAMLOutput {
	s.PackedPolicySize = &v
	return s
}

// SetSubject sets the Subject field's value.
func (s *AssumeRoleWithSAMLOutput) SetSubject(v string) *AssumeRoleWithSAMLOutput {
	s.Subject = &v
	return s
}

// SetSubjectType sets the SubjectType field's value.
func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLOutput {
	s.SubjectType = &v
	return s
}

type AssumeRoleWithWebIdentityInput struct {
	_ struct{} `type:"structure"`

	// The duration, in seconds, of the role session. The value can range from 900
	// seconds (15 minutes) up to the maximum session duration setting for the role.
	// This setting can have a value from 1 hour to 12 hours. If you specify a value
	// higher than this setting, the operation fails. For example, if you specify
	// a session duration of 12 hours, but your administrator set the maximum session
	// duration to 6 hours, your operation fails. To learn how to view the maximum
	// value for your role, see View the Maximum Session Duration Setting for a
	// Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session)
	// in the IAM User Guide.
	//
	// By default, the value is set to 3600 seconds.
	//
	// The DurationSeconds parameter is separate from the duration of a console
	// session that you might request using the returned credentials. The request
	// to the federation endpoint for a console sign-in token takes a SessionDuration
	// parameter that specifies the maximum length of the console session. For more
	// information, see Creating a URL that Enables Federated Users to Access the
	// AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html)
	// in the IAM User Guide.
	DurationSeconds *int64 `min:"900" type:"integer"`

	// An IAM policy in JSON format that you want to use as an inline session policy.
	//
	// This parameter is optional. Passing policies to this operation returns new
	// temporary credentials. The resulting session's permissions are the intersection
	// of the role's identity-based policy and the session policies. You can use
	// the role's temporary credentials in subsequent AWS API calls to access resources
	// in the account that owns the role. You cannot use session policies to grant
	// more permissions than those allowed by the identity-based policy of the role
	// that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	//
	// The plain text that you use for both inline and managed session policies
	// can't exceed 2,048 characters. The JSON policy characters can be any ASCII
	// character from the space character to the end of the valid character list
	// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
	// and carriage return (\u000D) characters.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	Policy *string `min:"1" type:"string"`

	// The Amazon Resource Names (ARNs) of the IAM managed policies that you want
	// to use as managed session policies. The policies must exist in the same account
	// as the role.
	//
	// This parameter is optional. You can provide up to 10 managed policy ARNs.
	// However, the plain text that you use for both inline and managed session
	// policies can't exceed 2,048 characters. For more information about ARNs,
	// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// in the AWS General Reference.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	//
	// Passing policies to this operation returns new temporary credentials. The
	// resulting session's permissions are the intersection of the role's identity-based
	// policy and the session policies. You can use the role's temporary credentials
	// in subsequent AWS API calls to access resources in the account that owns
	// the role. You cannot use session policies to grant more permissions than
	// those allowed by the identity-based policy of the role that is being assumed.
	// For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	PolicyArns []*PolicyDescriptorType `type:"list"`

	// The fully qualified host component of the domain name of the identity provider.
	//
	// Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com
	// and graph.facebook.com are the only supported identity providers for OAuth
	// 2.0 access tokens. Do not include URL schemes and port numbers.
	//
	// Do not specify this value for OpenID Connect ID tokens.
	ProviderId *string `min:"4" type:"string"`

	// The Amazon Resource Name (ARN) of the role that the caller is assuming.
	//
	// RoleArn is a required field
	RoleArn *string `min:"20" type:"string" required:"true"`

	// An identifier for the assumed role session. Typically, you pass the name
	// or identifier that is associated with the user who is using your application.
	// That way, the temporary security credentials that your application will use
	// are associated with that user. This session name is included as part of the
	// ARN and assumed role ID in the AssumedRoleUser response element.
	//
	// The regex used to validate this parameter is a string of characters consisting
	// of upper- and lower-case alphanumeric characters with no spaces. You can
	// also include underscores or any of the following characters: =,.@-
	//
	// RoleSessionName is a required field
	RoleSessionName *string `min:"2" type:"string" required:"true"`

	// The OAuth 2.0 access token or OpenID Connect ID token that is provided by
	// the identity provider. Your application must get this token by authenticating
	// the user who is using your application with a web identity provider before
	// the application makes an AssumeRoleWithWebIdentity call.
	//
	// WebIdentityToken is a required field
	WebIdentityToken *string `min:"4" type:"string" required:"true"`
}

// String returns the string representation
func (s AssumeRoleWithWebIdentityInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumeRoleWithWebIdentityInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AssumeRoleWithWebIdentityInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"}
	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
	}
	if s.Policy != nil && len(*s.Policy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
	}
	if s.ProviderId != nil && len(*s.ProviderId) < 4 {
		invalidParams.Add(request.NewErrParamMinLen("ProviderId", 4))
	}
	if s.RoleArn == nil {
		invalidParams.Add(request.NewErrParamRequired("RoleArn"))
	}
	if s.RoleArn != nil && len(*s.RoleArn) < 20 {
		invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
	}
	if s.RoleSessionName == nil {
		invalidParams.Add(request.NewErrParamRequired("RoleSessionName"))
	}
	if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2))
	}
	if s.WebIdentityToken == nil {
		invalidParams.Add(request.NewErrParamRequired("WebIdentityToken"))
	}
	if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 {
		invalidParams.Add(request.NewErrParamMinLen("WebIdentityToken", 4))
	}
	if s.PolicyArns != nil {
		for i, v := range s.PolicyArns {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDurationSeconds sets the DurationSeconds field's value.
func (s *AssumeRoleWithWebIdentityInput) SetDurationSeconds(v int64) *AssumeRoleWithWebIdentityInput {
	s.DurationSeconds = &v
	return s
}

// SetPolicy sets the Policy field's value.
func (s *AssumeRoleWithWebIdentityInput) SetPolicy(v string) *AssumeRoleWithWebIdentityInput {
	s.Policy = &v
	return s
}

// SetPolicyArns sets the PolicyArns field's value.
func (s *AssumeRoleWithWebIdentityInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleWithWebIdentityInput {
	s.PolicyArns = v
	return s
}

// SetProviderId sets the ProviderId field's value.
func (s *AssumeRoleWithWebIdentityInput) SetProviderId(v string) *AssumeRoleWithWebIdentityInput {
	s.ProviderId = &v
	return s
}

// SetRoleArn sets the RoleArn field's value.
func (s *AssumeRoleWithWebIdentityInput) SetRoleArn(v string) *AssumeRoleWithWebIdentityInput {
	s.RoleArn = &v
	return s
}

// SetRoleSessionName sets the RoleSessionName field's value.
func (s *AssumeRoleWithWebIdentityInput) SetRoleSessionName(v string) *AssumeRoleWithWebIdentityInput {
	s.RoleSessionName = &v
	return s
}

// SetWebIdentityToken sets the WebIdentityToken field's value.
func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRoleWithWebIdentityInput {
	s.WebIdentityToken = &v
	return s
}

// Contains the response to a successful AssumeRoleWithWebIdentity request,
// including temporary AWS credentials that can be used to make AWS requests.
type AssumeRoleWithWebIdentityOutput struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
	// that you can use to refer to the resulting temporary security credentials.
	// For example, you can reference these credentials as a principal in a resource-based
	// policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName
	// that you specified when you called AssumeRole.
	AssumedRoleUser *AssumedRoleUser `type:"structure"`

	// The intended audience (also known as client ID) of the web identity token.
	// This is traditionally the client identifier issued to the application that
	// requested the web identity token.
	Audience *string `type:"string"`

	// The temporary security credentials, which include an access key ID, a secret
	// access key, and a security token.
	//
	// The size of the security token that STS API operations return is not fixed.
	// We strongly recommend that you make no assumptions about the maximum size.
	Credentials *Credentials `type:"structure"`

	// A percentage value that indicates the packed size of the session policies
	// and session tags combined passed in the request. The request fails if the
	// packed size is greater than 100 percent, which means the policies and tags
	// exceeded the allowed space.
	PackedPolicySize *int64 `type:"integer"`

	// The issuing authority of the web identity token presented. For OpenID Connect
	// ID tokens, this contains the value of the iss field. For OAuth 2.0 access
	// tokens, this contains the value of the ProviderId parameter that was passed
	// in the AssumeRoleWithWebIdentity request.
	Provider *string `type:"string"`

	// The unique user identifier that is returned by the identity provider. This
	// identifier is associated with the WebIdentityToken that was submitted with
	// the AssumeRoleWithWebIdentity call. The identifier is typically unique to
	// the user and the application that acquired the WebIdentityToken (pairwise
	// identifier). For OpenID Connect ID tokens, this field contains the value
	// returned by the identity provider as the token's sub (Subject) claim.
	SubjectFromWebIdentityToken *string `min:"6" type:"string"`
}

// String returns the string representation
func (s AssumeRoleWithWebIdentityOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumeRoleWithWebIdentityOutput) GoString() string {
	return s.String()
}

// SetAssumedRoleUser sets the AssumedRoleUser field's value.
func (s *AssumeRoleWithWebIdentityOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithWebIdentityOutput {
	s.AssumedRoleUser = v
	return s
}

// SetAudience sets the Audience field's value.
func (s *AssumeRoleWithWebIdentityOutput) SetAudience(v string) *AssumeRoleWithWebIdentityOutput {
	s.Audience = &v
	return s
}

// SetCredentials sets the Credentials field's value.
func (s *AssumeRoleWithWebIdentityOutput) SetCredentials(v *Credentials) *AssumeRoleWithWebIdentityOutput {
	s.Credentials = v
	return s
}

// SetPackedPolicySize sets the PackedPolicySize field's value.
func (s *AssumeRoleWithWebIdentityOutput) SetPackedPolicySize(v int64) *AssumeRoleWithWebIdentityOutput {
	s.PackedPolicySize = &v
	return s
}

// SetProvider sets the Provider field's value.
func (s *AssumeRoleWithWebIdentityOutput) SetProvider(v string) *AssumeRoleWithWebIdentityOutput {
	s.Provider = &v
	return s
}

// SetSubjectFromWebIdentityToken sets the SubjectFromWebIdentityToken field's value.
func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v string) *AssumeRoleWithWebIdentityOutput {
	s.SubjectFromWebIdentityToken = &v
	return s
}

// The identifiers for the temporary security credentials that the operation
// returns.
type AssumedRoleUser struct {
	_ struct{} `type:"structure"`

	// The ARN of the temporary security credentials that are returned from the
	// AssumeRole action. For more information about ARNs and how to use them in
	// policies, see IAM Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
	// in the IAM User Guide.
	//
	// Arn is a required field
	Arn *string `min:"20" type:"string" required:"true"`

	// A unique identifier that contains the role ID and the role session name of
	// the role that is being assumed. The role ID is generated by AWS when the
	// role is created.
	//
	// AssumedRoleId is a required field
	AssumedRoleId *string `min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s AssumedRoleUser) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AssumedRoleUser) GoString() string {
	return s.String()
}

// SetArn sets the Arn field's value.
func (s *AssumedRoleUser) SetArn(v string) *AssumedRoleUser {
	s.Arn = &v
	return s
}

// SetAssumedRoleId sets the AssumedRoleId field's value.
func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser {
	s.AssumedRoleId = &v
	return s
}

// AWS credentials for API authentication.
type Credentials struct {
	_ struct{} `type:"structure"`

	// The access key ID that identifies the temporary security credentials.
	//
	// AccessKeyId is a required field
	AccessKeyId *string `min:"16" type:"string" required:"true"`

	// The date on which the current credentials expire.
	//
	// Expiration is a required field
	Expiration *time.Time `type:"timestamp" required:"true"`

	// The secret access key that can be used to sign requests.
	//
	// SecretAccessKey is a required field
	SecretAccessKey *string `type:"string" required:"true"`

	// The token that users must pass to the service API to use the temporary credentials.
	//
	// SessionToken is a required field
	SessionToken *string `type:"string" required:"true"`
}

// String returns the string representation
func (s Credentials) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Credentials) GoString() string {
	return s.String()
}

// SetAccessKeyId sets the AccessKeyId field's value.
func (s *Credentials) SetAccessKeyId(v string) *Credentials {
	s.AccessKeyId = &v
	return s
}

// SetExpiration sets the Expiration field's value.
func (s *Credentials) SetExpiration(v time.Time) *Credentials {
	s.Expiration = &v
	return s
}

// SetSecretAccessKey sets the SecretAccessKey field's value.
func (s *Credentials) SetSecretAccessKey(v string) *Credentials {
	s.SecretAccessKey = &v
	return s
}

// SetSessionToken sets the SessionToken field's value.
func (s *Credentials) SetSessionToken(v string) *Credentials {
	s.SessionToken = &v
	return s
}

type DecodeAuthorizationMessageInput struct {
	_ struct{} `type:"structure"`

	// The encoded message that was returned with the response.
	//
	// EncodedMessage is a required field
	EncodedMessage *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DecodeAuthorizationMessageInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DecodeAuthorizationMessageInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DecodeAuthorizationMessageInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"}
	if s.EncodedMessage == nil {
		invalidParams.Add(request.NewErrParamRequired("EncodedMessage"))
	}
	if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("EncodedMessage", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetEncodedMessage sets the EncodedMessage field's value.
func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAuthorizationMessageInput {
	s.EncodedMessage = &v
	return s
}

// A document that contains additional information about the authorization status
// of a request from an encoded message that is returned in response to an AWS
// request.
type DecodeAuthorizationMessageOutput struct {
	_ struct{} `type:"structure"`

	// An XML document that contains the decoded message.
	DecodedMessage *string `type:"string"`
}

// String returns the string representation
func (s DecodeAuthorizationMessageOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DecodeAuthorizationMessageOutput) GoString() string {
	return s.String()
}

// SetDecodedMessage sets the DecodedMessage field's value.
func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAuthorizationMessageOutput {
	s.DecodedMessage = &v
	return s
}

// Identifiers for the federated user that is associated with the credentials.
type FederatedUser struct {
	_ struct{} `type:"structure"`

	// The ARN that specifies the federated user that is associated with the credentials.
	// For more information about ARNs and how to use them in policies, see IAM
	// Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
	// in the IAM User Guide.
	//
	// Arn is a required field
	Arn *string `min:"20" type:"string" required:"true"`

	// The string that identifies the federated user associated with the credentials,
	// similar to the unique ID of an IAM user.
	//
	// FederatedUserId is a required field
	FederatedUserId *string `min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s FederatedUser) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s FederatedUser) GoString() string {
	return s.String()
}

// SetArn sets the Arn field's value.
func (s *FederatedUser) SetArn(v string) *FederatedUser {
	s.Arn = &v
	return s
}

// SetFederatedUserId sets the FederatedUserId field's value.
func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser {
	s.FederatedUserId = &v
	return s
}

type GetAccessKeyInfoInput struct {
	_ struct{} `type:"structure"`

	// The identifier of an access key.
	//
	// This parameter allows (through its regex pattern) a string of characters
	// that can consist of any upper- or lowercase letter or digit.
	//
	// AccessKeyId is a required field
	AccessKeyId *string `min:"16" type:"string" required:"true"`
}

// String returns the string representation
func (s GetAccessKeyInfoInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetAccessKeyInfoInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetAccessKeyInfoInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetAccessKeyInfoInput"}
	if s.AccessKeyId == nil {
		invalidParams.Add(request.NewErrParamRequired("AccessKeyId"))
	}
	if s.AccessKeyId != nil && len(*s.AccessKeyId) < 16 {
		invalidParams.Add(request.NewErrParamMinLen("AccessKeyId", 16))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAccessKeyId sets the AccessKeyId field's value.
func (s *GetAccessKeyInfoInput) SetAccessKeyId(v string) *GetAccessKeyInfoInput {
	s.AccessKeyId = &v
	return s
}

type GetAccessKeyInfoOutput struct {
	_ struct{} `type:"structure"`

	// The number used to identify the AWS account.
	Account *string `type:"string"`
}

// String returns the string representation
func (s GetAccessKeyInfoOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetAccessKeyInfoOutput) GoString() string {
	return s.String()
}

// SetAccount sets the Account field's value.
func (s *GetAccessKeyInfoOutput) SetAccount(v string) *GetAccessKeyInfoOutput {
	s.Account = &v
	return s
}

type GetCallerIdentityInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s GetCallerIdentityInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetCallerIdentityInput) GoString() string {
	return s.String()
}

// Contains the response to a successful GetCallerIdentity request, including
// information about the entity making the request.
type GetCallerIdentityOutput struct {
	_ struct{} `type:"structure"`

	// The AWS account ID number of the account that owns or contains the calling
	// entity.
	Account *string `type:"string"`

	// The AWS ARN associated with the calling entity.
	Arn *string `min:"20" type:"string"`

	// The unique identifier of the calling entity. The exact value depends on the
	// type of entity that is making the call. The values returned are those listed
	// in the aws:userid column in the Principal table (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable)
	// found on the Policy Variables reference page in the IAM User Guide.
	UserId *string `type:"string"`
}

// String returns the string representation
func (s GetCallerIdentityOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetCallerIdentityOutput) GoString() string {
	return s.String()
}

// SetAccount sets the Account field's value.
func (s *GetCallerIdentityOutput) SetAccount(v string) *GetCallerIdentityOutput {
	s.Account = &v
	return s
}

// SetArn sets the Arn field's value.
func (s *GetCallerIdentityOutput) SetArn(v string) *GetCallerIdentityOutput {
	s.Arn = &v
	return s
}

// SetUserId sets the UserId field's value.
func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput {
	s.UserId = &v
	return s
}

type GetFederationTokenInput struct {
	_ struct{} `type:"structure"`

	// The duration, in seconds, that the session should last. Acceptable durations
	// for federation sessions range from 900 seconds (15 minutes) to 129,600 seconds
	// (36 hours), with 43,200 seconds (12 hours) as the default. Sessions obtained
	// using AWS account root user credentials are restricted to a maximum of 3,600
	// seconds (one hour). If the specified duration is longer than one hour, the
	// session obtained by using root user credentials defaults to one hour.
	DurationSeconds *int64 `min:"900" type:"integer"`

	// The name of the federated user. The name is used as an identifier for the
	// temporary security credentials (such as Bob). For example, you can reference
	// the federated user name in a resource-based policy, such as in an Amazon
	// S3 bucket policy.
	//
	// The regex used to validate this parameter is a string of characters consisting
	// of upper- and lower-case alphanumeric characters with no spaces. You can
	// also include underscores or any of the following characters: =,.@-
	//
	// Name is a required field
	Name *string `min:"2" type:"string" required:"true"`

	// An IAM policy in JSON format that you want to use as an inline session policy.
	//
	// You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// to this operation. You can pass a single JSON policy document to use as an
	// inline session policy. You can also specify up to 10 managed policies to
	// use as managed session policies.
	//
	// This parameter is optional. However, if you do not pass any session policies,
	// then the resulting federated user session has no permissions.
	//
	// When you pass session policies, the session permissions are the intersection
	// of the IAM user policies and the session policies that you pass. This gives
	// you a way to further restrict the permissions for a federated user. You cannot
	// use session policies to grant more permissions than those that are defined
	// in the permissions policy of the IAM user. For more information, see Session
	// Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	//
	// The resulting credentials can be used to access a resource that has a resource-based
	// policy. If that policy specifically references the federated user session
	// in the Principal element of the policy, the session has the permissions allowed
	// by the policy. These permissions are granted in addition to the permissions
	// that are granted by the session policies.
	//
	// The plain text that you use for both inline and managed session policies
	// can't exceed 2,048 characters. The JSON policy characters can be any ASCII
	// character from the space character to the end of the valid character list
	// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
	// and carriage return (\u000D) characters.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	Policy *string `min:"1" type:"string"`

	// The Amazon Resource Names (ARNs) of the IAM managed policies that you want
	// to use as a managed session policy. The policies must exist in the same account
	// as the IAM user that is requesting federated access.
	//
	// You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// to this operation. You can pass a single JSON policy document to use as an
	// inline session policy. You can also specify up to 10 managed policies to
	// use as managed session policies. The plain text that you use for both inline
	// and managed session policies can't exceed 2,048 characters. You can provide
	// up to 10 managed policy ARNs. For more information about ARNs, see Amazon
	// Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// in the AWS General Reference.
	//
	// This parameter is optional. However, if you do not pass any session policies,
	// then the resulting federated user session has no permissions.
	//
	// When you pass session policies, the session permissions are the intersection
	// of the IAM user policies and the session policies that you pass. This gives
	// you a way to further restrict the permissions for a federated user. You cannot
	// use session policies to grant more permissions than those that are defined
	// in the permissions policy of the IAM user. For more information, see Session
	// Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
	// in the IAM User Guide.
	//
	// The resulting credentials can be used to access a resource that has a resource-based
	// policy. If that policy specifically references the federated user session
	// in the Principal element of the policy, the session has the permissions allowed
	// by the policy. These permissions are granted in addition to the permissions
	// that are granted by the session policies.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	PolicyArns []*PolicyDescriptorType `type:"list"`

	// A list of session tags. Each session tag consists of a key name and an associated
	// value. For more information about session tags, see Passing Session Tags
	// in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
	// in the IAM User Guide.
	//
	// This parameter is optional. You can pass up to 50 session tags. The plain
	// text session tag keys can’t exceed 128 characters and the values can’t
	// exceed 256 characters. For these and additional limits, see IAM and STS Character
	// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
	// in the IAM User Guide.
	//
	// An AWS conversion compresses the passed session policies and session tags
	// into a packed binary format that has a separate limit. Your request can fail
	// for this limit even if your plain text meets the other requirements. The
	// PackedPolicySize response element indicates by percentage how close the policies
	// and tags for your request are to the upper size limit.
	//
	// You can pass a session tag with the same key as a tag that is already attached
	// to the user you are federating. When you do, session tags override a user
	// tag with the same key.
	//
	// Tag key–value pairs are not case sensitive, but case is preserved. This
	// means that you cannot have separate Department and department tag keys. Assume
	// that the role has the Department=Marketing tag and you pass the department=engineering
	// session tag. Department and department are not saved as separate tags, and
	// the session tag passed in the request takes precedence over the role tag.
	Tags []*Tag `type:"list"`
}

// String returns the string representation
func (s GetFederationTokenInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetFederationTokenInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetFederationTokenInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetFederationTokenInput"}
	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
	}
	if s.Name == nil {
		invalidParams.Add(request.NewErrParamRequired("Name"))
	}
	if s.Name != nil && len(*s.Name) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("Name", 2))
	}
	if s.Policy != nil && len(*s.Policy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
	}
	if s.PolicyArns != nil {
		for i, v := range s.PolicyArns {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams))
			}
		}
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDurationSeconds sets the DurationSeconds field's value.
func (s *GetFederationTokenInput) SetDurationSeconds(v int64) *GetFederationTokenInput {
	s.DurationSeconds = &v
	return s
}

// SetName sets the Name field's value.
func (s *GetFederationTokenInput) SetName(v string) *GetFederationTokenInput {
	s.Name = &v
	return s
}

// SetPolicy sets the Policy field's value.
func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput {
	s.Policy = &v
	return s
}

// SetPolicyArns sets the PolicyArns field's value.
func (s *GetFederationTokenInput) SetPolicyArns(v []*PolicyDescriptorType) *GetFederationTokenInput {
	s.PolicyArns = v
	return s
}

// SetTags sets the Tags field's value.
func (s *GetFederationTokenInput) SetTags(v []*Tag) *GetFederationTokenInput {
	s.Tags = v
	return s
}

// Contains the response to a successful GetFederationToken request, including
// temporary AWS credentials that can be used to make AWS requests.
type GetFederationTokenOutput struct {
	_ struct{} `type:"structure"`

	// The temporary security credentials, which include an access key ID, a secret
	// access key, and a security (or session) token.
	//
	// The size of the security token that STS API operations return is not fixed.
	// We strongly recommend that you make no assumptions about the maximum size.
	Credentials *Credentials `type:"structure"`

	// Identifiers for the federated user associated with the credentials (such
	// as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You
	// can use the federated user's ARN in your resource-based policies, such as
	// an Amazon S3 bucket policy.
	FederatedUser *FederatedUser `type:"structure"`

	// A percentage value that indicates the packed size of the session policies
	// and session tags combined passed in the request. The request fails if the
	// packed size is greater than 100 percent, which means the policies and tags
	// exceeded the allowed space.
	PackedPolicySize *int64 `type:"integer"`
}

// String returns the string representation
func (s GetFederationTokenOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetFederationTokenOutput) GoString() string {
	return s.String()
}

// SetCredentials sets the Credentials field's value.
func (s *GetFederationTokenOutput) SetCredentials(v *Credentials) *GetFederationTokenOutput {
	s.Credentials = v
	return s
}

// SetFederatedUser sets the FederatedUser field's value.
func (s *GetFederationTokenOutput) SetFederatedUser(v *FederatedUser) *GetFederationTokenOutput {
	s.FederatedUser = v
	return s
}

// SetPackedPolicySize sets the PackedPolicySize field's value.
func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTokenOutput {
	s.PackedPolicySize = &v
	return s
}

type GetSessionTokenInput struct {
	_ struct{} `type:"structure"`

	// The duration, in seconds, that the credentials should remain valid. Acceptable
	// durations for IAM user sessions range from 900 seconds (15 minutes) to 129,600
	// seconds (36 hours), with 43,200 seconds (12 hours) as the default. Sessions
	// for AWS account owners are restricted to a maximum of 3,600 seconds (one
	// hour). If the duration is longer than one hour, the session for AWS account
	// owners defaults to one hour.
	DurationSeconds *int64 `min:"900" type:"integer"`

	// The identification number of the MFA device that is associated with the IAM
	// user who is making the GetSessionToken call. Specify this value if the IAM
	// user has a policy that requires MFA authentication. The value is either the
	// serial number for a hardware device (such as GAHT12345678) or an Amazon Resource
	// Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
	// You can find the device for an IAM user by going to the AWS Management Console
	// and viewing the user's security credentials.
	//
	// The regex used to validate this parameter is a string of characters consisting
	// of upper- and lower-case alphanumeric characters with no spaces. You can
	// also include underscores or any of the following characters: =,.@:/-
	SerialNumber *string `min:"9" type:"string"`

	// The value provided by the MFA device, if MFA is required. If any policy requires
	// the IAM user to submit an MFA code, specify this value. If MFA authentication
	// is required, the user must provide a code when requesting a set of temporary
	// security credentials. A user who fails to provide the code receives an "access
	// denied" response when requesting resources that require MFA authentication.
	//
	// The format for this parameter, as described by its regex pattern, is a sequence
	// of six numeric digits.
	TokenCode *string `min:"6" type:"string"`
}

// String returns the string representation
func (s GetSessionTokenInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetSessionTokenInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetSessionTokenInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetSessionTokenInput"}
	if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
		invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
	}
	if s.SerialNumber != nil && len(*s.SerialNumber) < 9 {
		invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9))
	}
	if s.TokenCode != nil && len(*s.TokenCode) < 6 {
		invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDurationSeconds sets the DurationSeconds field's value.
func (s *GetSessionTokenInput) SetDurationSeconds(v int64) *GetSessionTokenInput {
	s.DurationSeconds = &v
	return s
}

// SetSerialNumber sets the SerialNumber field's value.
func (s *GetSessionTokenInput) SetSerialNumber(v string) *GetSessionTokenInput {
	s.SerialNumber = &v
	return s
}

// SetTokenCode sets the TokenCode field's value.
func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput {
	s.TokenCode = &v
	return s
}

// Contains the response to a successful GetSessionToken request, including
// temporary AWS credentials that can be used to make AWS requests.
type GetSessionTokenOutput struct {
	_ struct{} `type:"structure"`

	// The temporary security credentials, which include an access key ID, a secret
	// access key, and a security (or session) token.
	//
	// The size of the security token that STS API operations return is not fixed.
	// We strongly recommend that you make no assumptions about the maximum size.
	Credentials *Credentials `type:"structure"`
}

// String returns the string representation
func (s GetSessionTokenOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetSessionTokenOutput) GoString() string {
	return s.String()
}

// SetCredentials sets the Credentials field's value.
func (s *GetSessionTokenOutput) SetCredentials(v *Credentials) *GetSessionTokenOutput {
	s.Credentials = v
	return s
}

// A reference to the IAM managed policy that is passed as a session policy
// for a role session or a federated user session.
type PolicyDescriptorType struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the IAM managed policy to use as a session
	// policy for the role. For more information about ARNs, see Amazon Resource
	// Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// in the AWS General Reference.
	Arn *string `locationName:"arn" min:"20" type:"string"`
}

// String returns the string representation
func (s PolicyDescriptorType) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PolicyDescriptorType) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PolicyDescriptorType) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PolicyDescriptorType"}
	if s.Arn != nil && len(*s.Arn) < 20 {
		invalidParams.Add(request.NewErrParamMinLen("Arn", 20))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetArn sets the Arn field's value.
func (s *PolicyDescriptorType) SetArn(v string) *PolicyDescriptorType {
	s.Arn = &v
	return s
}

// You can pass custom key-value pair attributes when you assume a role or federate
// a user. These are called session tags. You can then use the session tags
// to control access to resources. For more information, see Tagging AWS STS
// Sessions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
type Tag struct {
	_ struct{} `type:"structure"`

	// The key for a session tag.
	//
	// You can pass up to 50 session tags. The plain text session tag keys can’t
	// exceed 128 characters. For these and additional limits, see IAM and STS Character
	// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
	// in the IAM User Guide.
	//
	// Key is a required field
	Key *string `min:"1" type:"string" required:"true"`

	// The value for a session tag.
	//
	// You can pass up to 50 session tags. The plain text session tag values can’t
	// exceed 256 characters. For these and additional limits, see IAM and STS Character
	// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
	// in the IAM User Guide.
	//
	// Value is a required field
	Value *string `type:"string" required:"true"`
}

// String returns the string representation
func (s Tag) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Tag) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *Tag) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Tag"}
	if s.Key == nil {
		invalidParams.Add(request.NewErrParamRequired("Key"))
	}
	if s.Key != nil && len(*s.Key) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
	}
	if s.Value == nil {
		invalidParams.Add(request.NewErrParamRequired("Value"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetKey sets the Key field's value.
func (s *Tag) SetKey(v string) *Tag {
	s.Key = &v
	return s
}

// SetValue sets the Value field's value.
func (s *Tag) SetValue(v string) *Tag {
	s.Value = &v
	return s
}
