Skip to content

Instantly share code, notes, and snippets.

@film42
Created June 30, 2025 14:19
Show Gist options
  • Save film42/7a49b7d3714dbeed702ed0a296851fff to your computer and use it in GitHub Desktop.
Save film42/7a49b7d3714dbeed702ed0a296851fff to your computer and use it in GitHub Desktop.
Make tableau work around

Why a tableau cloud proxy?

It turns out that usage based embedded tableau reports (the kind where you create an SSO token for no specific user) do not work with Safari on Mac or iOS. Why? Because when the Tableau SDK signs in with your single use token, the response contains a session cookie; and, since the browser is receving this from a domain that is not the same as the page you're on, Safari assumes this is an advertiser attempting to track you, and drops the cookie.

To work around this limitation, you need to make Tableau match the domain of your web app. I've seen a few examples out there like deploying an nginx container, or writing a custom app controller, etc. My solution was to make a simple load balancer in Google Cloud that would proxy all traffic to a Tableau endpoint--and it works really well.

Attached is the pulumi code I used for this. If you're following in my footsteps, this should work out of the box after updating the code to use your own domain. Also, if you're like me, and allow customers to bring their own domains, you can provision a cert in this code for them, include it in the Target HTTPS Proxy list, and add the host to the URL Map.

I just have my customers add an A record with the domain pointing to the LB IP, but if you expect very slow response times from your customer's IT department, it may be preferrable to have them CNAME to your host and then add a second DNS Authorization record which you'll need to create for them in GCP.

Hope this helps!

import pulumi
import pulumi_gcp as gcp
def run(gcp_project_name):
# Create Internet Network Endpoint Group for Tableau
tableau_neg = gcp.compute.GlobalNetworkEndpointGroup(
"tableau-proxy-neg",
name="tableau-proxy-neg",
project=gcp_project_name,
network_endpoint_type="INTERNET_FQDN_PORT",
default_port=443,
)
# Add the Tableau endpoint to the NEG
tableau_endpoint = gcp.compute.GlobalNetworkEndpoint(
"tableau-proxy-endpoint",
project=gcp_project_name,
global_network_endpoint_group=tableau_neg.name,
fqdn="10ay.online.tableau.com",
port=443,
)
# Create backend service for Tableau
tableau_backend = gcp.compute.BackendService(
"tableau-proxy-backend",
name="tableau-proxy-backend",
project=gcp_project_name,
protocol="HTTPS",
backends=[
{
"group": tableau_neg.id,
}
],
load_balancing_scheme="EXTERNAL_MANAGED",
)
# Create NEW URL map just for Tableau to cover all proxy domains
tableau_url_map = gcp.compute.URLMap(
"tableau-proxy-url-map",
name="tableau-proxy-url-map",
project=gcp_project_name,
default_service=tableau_backend.id,
host_rules=[
{
"hosts": [
"10ay.tableau.my.own.app",
],
"path_matcher": "tableau-proxy-matcher",
}
],
path_matchers=[
{
"name": "tableau-proxy-matcher",
"default_service": tableau_backend.id,
"path_rules": [
{
"paths": ["/*"],
"service": tableau_backend.id,
"route_action": {
"url_rewrite": {"host_rewrite": "10ay.online.tableau.com"}
},
}
],
}
],
)
# Create SSL certificate
tableau_ssl_cert = gcp.compute.ManagedSslCertificate(
"tableau-proxy-ssl-cert",
name="tableau-proxy-ssl-cert",
project=gcp_project_name,
managed={"domains": ["10ay.tableau.my.own.app"]},
)
# Proxy and forwarding rules
tableau_https_proxy = gcp.compute.TargetHttpsProxy(
"tableau-proxy-https-proxy",
name="tableau-proxy-https-proxy",
project=gcp_project_name,
url_map=tableau_url_map.id,
ssl_certificates=[
tableau_ssl_cert.id,
],
)
tableau_forwarding_rule = gcp.compute.GlobalForwardingRule(
"tableau-proxy-forwarding-rule",
name="tableau-proxy-forwarding-rule",
project=gcp_project_name,
target=tableau_https_proxy.id,
port_range="443",
ip_protocol="TCP",
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment