Connecting AWS Athena to Tableau Cloud with Cognito

AWS
Athena
Cognito
Tableau

This article explains how to connect Tableau Cloud to AWS Athena and configure it as a data source using OAuth authentication.

Create the User Pool

Create a new Cognito User Pool using the default settings. For a step-by-step guide, refer to this tutorial.

Create an App Client

  1. Application Type: Select "Traditional web application"

  2. Name your application: E.g: TableauCloudClient

  3. Store the Client ID and Client Secret values, will be used later on.

  4. Configure the Allowed callback URLs, subdomain is the subdomain of the Tableau's instance:

    • http://localhost:55556/Callback
    • http://localhost:55557/Callback
    • http://localhost:55558/Callback
    • http://localhost:55559/Callback
    • https://subdomain.tableau.com/auth/add_oauth_token
  5. Configure the Allowed sign-out URLs to:

    • http://localhost:8080

Create a new IAM Identity Provider

To create a new Identity Provider, access the IAM page and under Access management and select Identity providers.

  1. Provider type: OpenID Connect
  2. Provider URL: Copy the Token signing key URL from the newly created User Pool (e.g. https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxxxx).
  3. Audience: Client ID from the App Client.

Create a new IAM Role

Create a new IAM Role with the entity type "Web identity" and select the previously created identity provider. Configure the permissions to grant access to the required Glue tables, corresponding S3 buckets, and AWS Athena. For more details, refer to this tutorial.

Configure Tableau Cloud

In Tableau Cloud's dashboard, create a new OAuth client with the following configuration:

  • Connection Type: Amazon Athena
  • OAuth Provider: Custom IDP
  • Client ID: Client ID from the App Client
  • Client Secret: Client Secret from the App Client
  • Redirect URL: https://subdomain.tableau.com/auth/add_oauth_token
  • OAuth Config File:
        <?xml version="1.0" encoding="utf-8"?>
        <pluginOAuthConfig>
            <dbclass>athena</dbclass>
            <oauthConfigId>custom_athena_cognito</oauthConfigId>
            <configLabel>Cognito</configLabel>
            <clientIdDesktop>$clientID</clientIdDesktop>
            <clientSecretDesktop>$clientSecret</clientSecretDesktop>
            <redirectUrisDesktop>http://localhost:55556/Callback</redirectUrisDesktop>
            <redirectUrisDesktop>http://localhost:55557/Callback</redirectUrisDesktop>
            <redirectUrisDesktop>http://localhost:55558/Callback</redirectUrisDesktop>
            <redirectUrisDesktop>http://localhost:55559/Callback</redirectUrisDesktop>
            <authUri>https://eu-central-1_xxxxxx.auth.eu-central-1.amazoncognito.com/oauth2/authorize</authUri>
            <tokenUri>https://eu-central-1_xxxxxx.auth.eu-central-1.amazoncognito.com/oauth2/token</tokenUri>
            <scopes>openid</scopes>
            <scopes>email</scopes>
            <scopes>profile</scopes>
            <capabilities>
                <entry>
                    <key>OAUTH_CAP_FIXED_PORT_IN_CALLBACK_URL</key>
                    <value>true</value>
                </entry>
                <entry>
                    <key>OAUTH_CAP_PKCE_REQUIRES_CODE_CHALLENGE_METHOD</key>
                    <value>true</value>
                </entry>
                <entry>
                    <key>OAUTH_CAP_REQUIRE_PKCE</key>
                    <value>true</value>
                </entry>
                <entry>
                    <key>OAUTH_CAP_SUPPORTS_STATE</key>
                    <value>true</value>
                </entry>
                <entry>
                    <key>OAUTH_CAP_CLIENT_SECRET_IN_URL_QUERY_PARAM</key>
                    <value>false</value>
                </entry>
                <entry>
                    <key>OAUTH_CAP_SUPPORTS_GET_USERINFO_FROM_ID_TOKEN</key>
                    <value>true</value>
                </entry>
            </capabilities>
            <accessTokenResponseMaps>
                <entry>
                    <key>ACCESSTOKEN</key>
                    <value>access_token</value>
                </entry>
                <entry>
                    <key>REFRESHTOKEN</key>
                    <value>refresh_token</value>
                </entry>
                <entry>
                    <key>id-token</key>
                    <value>id_token</value>
                </entry>
                <entry>
                    <key>access-token-issue-time</key>
                    <value>issued_at</value>
                </entry>
                <entry>
                    <key>access-token-expires-in</key>
                    <value>expires_in</value>
                </entry>
                <entry>
                    <key>username</key>
                    <value>email</value>
                </entry>
            </accessTokenResponseMaps>
        </pluginOAuthConfig>