Redirect URL, unless WARP for Teams is active

I have an application where the administration runs at .com/, but client access runs at .com/client/.

What I’d LOVE to do is:

  • Anyone in my WARP for Teams should bypass the challenge and just let us see the login page. I’d authenticate to the app and continue as normal.
  • At the same time, anyone who is NOT part of my WARP for Teams group would be silently redirected to .com/client/.

I have the URL set up to challenge access for .com/ via our Identity Provider, which is fine, but not the best user experience. .com/client/* is not protected by Access, which is just fine.

Anyone have ideas on how to achieve this?

You could create a HTTP policy in Cloudflare Zero Trust that adds a header with a secret key.

Then rewrite the path in Transform Rules if the request does not contain that header.

This should cause any visitors who don’t use Cloudflare Warp and aren’t in your Cloudflare Access organization to reach /client.

3 Likes

@Albert , first off, THANK YOU for the post.

So far I’m not able to get this to work. Here’s where I’m at:
Zero Trust:

  • Gateway/Policies → HTTP Policies
  • Step 1: Redirect Public
  • Step 2: Domain in sub.domain.com
  • Step 3: Allow
  • Step 4: x-secret random_64_char_id

With that set, I visit sub.domain.com, go to network tab and checkout the doc headers. They are:

Summary

Request
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15

Response
Content-Encoding: br
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Content-Security-Policy: default-src ‘self’; base-uri ‘self’; form-action ‘self’; frame-ancestors ‘none’; media-src ‘self’; style-src ‘self’ ‘unsafe-inline’; font-src ‘self’ data:; script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’ https://unpkg.com https://cdn.jsdelivr.net https://cdn.onesignal.com https://.Cloudflare.com https://.cloudflareinsights.com; connect-src ‘self’ https://unpkg.com https://.bugsnag.com https://.github.io https://.us.auth0.com https://.algolia.net https://.algolianet.com https://fonts.gstatic.com; img-src ‘self’ data:; object-src ‘none’; frame-src ‘self’ https://.vimeo.com https://.videodelivery.net https://.akamaized.net;, Upgrade-Insecure-Requests
Cache-Control: private, must-revalidate
Access-Control-Allow-Origin: *
Pragma: no-cache
Report-To: {“endpoints”:[{“url”:“https://a.nel.cloudflare.com/report/v3?s=g3OLma5xdw4iF%2BY6If%2B%2F1uk6aoE9%2FMvND9Nd4uBzKxyPsbXYP4x2ha307eYYEZVcHbQJ%2BvOI0hcVmzaQDJdattPSqrpQqHFcHAiBsbGLSz%2Bcg%2BrP2lqsMWZIdkevqM3KaUI7lG%2BcpCE%3D"}],“group”:“cf-nel”,"max_age”:604800}
Access-Control-Allow-Headers: X-API-PASSWORD-BASE64,X-API-COMPANY-KEY,X-API-SECRET,X-API-TOKEN,X-API-PASSWORD,DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-CSRF-TOKEN,X-XSRF-TOKEN,X-LIVEWIRE
X-XSS-Protection: 1; mode=block
Date: Fri, 18 Mar 2022 17:14:29 GMT
Vary: Accept-Encoding
Expires: -1
Access-Control-Expose-Headers: X-APP-VERSION,X-MINIMUM-CLIENT-VERSION
X-Frame-Options: SAMEORIGIN, SAMEORIGIN, SAMEORIGIN
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
p3p: policyref="/w3c/p3p.xml", CP=“IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT”
x-robots-tag: noindex, nofollow
Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
Server: Cloudflare
Alt-Svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
x-minimum-client-version: 5.0.16
x-app-version: 5.3.68
expect-ct: max-age=604800, report-uri=“https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct
nel: {“success_fraction”:0,“report_to”:“cf-nel”,“max_age”:604800}
cf-cache-status: DYNAMIC
cf-ray: 6edf9adb88e19e70-SJC

I would assume that I SHOULD see my custom x-secret header in that list, but it is nowhere to be found.

Domain:

  • Rules/Transform Rules
  • Name: Redirect Public
  • (Edit Expression- so I can enter my own) (http.request.headers["x-secret"][0] != "random_64_char_id")
  • Path/Rewrite to…" Dynamic concat("/client",http.request.uri.path)
  • Query: Preserve

When I enable this, my primary domain (domain.com), pretty much breaks (it’s a workers site). This is aside from the task at hand, but worth noting, I think.

On sub.domain.com, with WARP enabled, I am redirected to .com/public/client. Since the x-secret header isn’t applying the redirect make sense. Also, the app I’m trying to hide is a larvel app and I understand that sometimes the routes are a little screwy with them. Since I’m concatenating sub.domain.com with /client, and apparently the plain .com is REALLY .com/public this too makes sense.

When I change the Rewrite to… to concat("/client", "sub.domain.com") it looks like the app’s URLs are being rewritten, which is breaking the site and preventing it from rendering at all.

Any tips for my next steps?

I’ve tried changing the Rewrite to… to static and client and the URL appears to be better, but the page says too many redirects

Giving up and just setting up a forwarding URL. Thankfully there’s an admin app, and while this isn’t ideal, I don’t think there’s a way to do what I want.