Package: cognito-assume-role
Currently supports USER_SRP_AUTH and USER_PASSWORD_AUTH using enhanced Cognito auth flow.
Custom auth flows or administrative auth are not currently supported although I suppose
you could monkey patch the needed code. It was written using only public methods exposed by the boto3/botocore
API’s to help ensure that changes to boto3 won’t break any (what would be otherwise) monkey patched code.
This should also maintain the ability to use this library for your boto3 calls that are not using Cognito within
the same script by simply passing a normal boto3 client credential argument.USAGE:
This module can insert a botocore.credentials.CredentialProvider into the provider chain.
Using this provider we can assume an IAM role through get_credentials_for_identity(). To do this
we provide three functions:
- client (wraps boto3.client())
- resource (wraps boto3.resource())
- Session (wraps boto3.session.Session())All three of these functions accept all normal boto3 args and kwargs plus some that are specific to this module.
We provide three ways of providing the initial credentials.Env varsThese will take affect before any other credential provider, including the standard env provider that looks for AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID.
If one or more of the following non-optional variables are found in environ then we will automatically go to env based credential mappingCOGNITO_USERNAMECOGNITO_PASSWORDCOGNITO_USER_POOL_IDCOGNITO_IDENTITY_POOL_IDCOGNITO_APP_IDCOGNITO_METADATA (Deserialized and passed as ClientMetadata in boto3.client(“cognito-idp”).initiate_auth()) - OptionalAWS_ROLE_ARN - OptionalProfileCredential file locations, if not specified, will be resolved in the order of <argument to client>, “COGNITO_CREDENTIALS_FILE”, “~/.aws/cognito_credentials”.
Config files take the following form:[default]username=myusernamepassword=***********app_id=1234567890user_pool_id=abcdefgidentity_pool_id=us-east-1:1234567890region=us-east-1metadata={"foo":"bar"}auth_type=user_srpAll values except for region and metadata are required if using a profile. Using a profile is done by passing the kwarg “cognito_profile=<profile name>” to client, Session, or resource.Direct configuration{"username":"myusername","password":"***********","app_id":"1234567890","user_pool_id":"abcdefg","identity_pool_id":"us-east-1:1234567890","region":"us-east-1","metadata":{"foo":"bar"},"auth_type":"user_srp"}Same rules apply for required values as when using a profile. Direct configuration is done by passing the config dictionary to kwarg cognito_config when creating a client, resource, or Session.
Note that cognito_profile and cognito_config are mutually exclusive. Trying to use both at once will raise an Assertion exception.Auth typesThe client, resource, and Session functions also accept an argument of auth_type. This can be “user_srp” (default) or “user_password”.Accessing Cognito tokens from a SessionIf creating a Session directly the cognito id, refresh, and access tokens, as well as the expires time are available as properties on the Session object.
Tokens are stored in memory by default, but passing a file name as “token_cache=/file/path.txt” into Session() will write cause the tokens to be written to the specified
file as JSON. Passing a path to a file that does not exist will raise a FileNotFoundError. Passing a path to a file that is not writeable will raise OSError. Properties
to access tokens:Session().id_tokenSession().access_tokenSession().refresh_tokenSession().token_expiresSession().cognito_tokens (All of the above in a dict)Because of how boto3 generates clients there is no way to access the “parent” session. This means that to use this feature you will need to create a Session()
object and then create your clients/resources off of that Session(). Example:fromcognito_assume_roleimportSessionsession=Session()s3=session.s3()s3.list_buckets()print(session.token_expires)# Outputs 2020-09-19T23:17:28CDTfromcognito_assume_roleimportTokenFetchers=TokenFetcher()# Strings shortened for brevityprint(s.id_token[-10:-1])print(s.access_token[-10:-1])print(s.refresh_token[-10:-1])print(s.expires)"""
Results in:
  6xAb_vMKv
  4Ruc_TB_h
  m3Htft_Op
  2020-09-19T05:16:31
"""**GettingCognitocredentialtokenswithoutarole**Ifyoudon't want to assume a role but would still like to access cognito id tokens directly, for instance to make Appsync calls using the requests library, youcanusetheTokenFetcherclass.Itprovidesthefollowingproperties:-tokens(dict):Adictionarycontainingid_token,access_token,token_expires,andrefresh_token-id_token-access_token-refresh_token-token_expiresMethods:-fetch():Updatesandreturnsself.tokensAllpropertiesareavailableuponinstantiation.TheconstructoracceptsthesamekwargsasSession(),alongwithoption"server (bool)".Setting"server=True"willstartabackgroundprocesstokeeptokensrefreshedautomatically,whichmeansthatyourtokenswillalwaysbeuptodate.**Example**..code-block::pythonfromcognito_assume_roleimportTokenFetchercognito_credentials=TokenFetcher()print(cognito_credentials)print(cognito_credentials.id_token)print(cognito_credentials.access_token)print(cognito_credentials.token_expires)print(cognito_credentials.refresh_token)Creating a client that uses a configfromcognito_assume_roleimportclientclient=boto3.client("s3",profile="my_profile")client.list_buckets()Using resource with env vars and specifying auth_type and regionfromcognito_assume_roleimportresourceresource=boto3.resource("s3",auth_type="user_password",region_name="us-east-2")resource.create_bucket(Bucket="my-file-dump-woot-woot")Creating a session that we can reuse for multiple clientsfromcognito_assume_roleimportSessionsession=Session(auth_type="user_srp",region_name="us-east-2")s3=session.client("s3")dynamo=resource("dynamodb")table=dynamo.Table("my_table")Precedence of CredentialProvidersThe order of resolution for credential providers remains unchanged except for setting environment variables for Cognito will take affect
before any AWS credential environment variables.Precedence of argumentsAny value that can be defined in either an environment variable, explicitly passed as a kwarg ( passed to client, resource, or Session)
or can be part of a config or profile is resolved in the following order:explicit argumentsspecified by config or profileenvironment variables