Zero Trust in Action: Securing Applications with Cloudflare Tunnel
By Tomer Klein
Looking to secure internal tools or self-hosted applications without exposing them directly to the internet?
This guide shows how to combine Cloudflare Tunnel and Cloudflare Access Policies to create a Zero Trust access layer for your apps — no VPN needed. We’ll walk through the setup and fine-tuning of policies (including IP bypass).
Cloudflare Tunnel (formerly Argo Tunnel) lets you create a secure outbound connection from your infrastructure to Cloudflare’s edge. You don’t need to open any inbound ports on your firewall.
Key benefits:
In my previous articles, I explained how to set up a tunnel.
What Is Cloudflare Access?
Access acts as a zero trust policy layer on top of your Cloudflare Tunnel. It allows you to control who can reach your apps and under what conditions.
You can:
Setting Up Cloudflare Access Policy
In this part of the guide, I’ll show you how you can protect different routes of the same application with different access policies.
First, navigate to the Cloudflare Zero Trust dashboard by clicking on “Zero Trust”:
Now, under “Access”, click on “Policies”:
Now, let’s assume you're running an n8n server and exposing it via Cloudflare Tunnel. The server URL is: “n8n.example.com”, and you have two webhooks:
You want to block access to the UI by assigning 2FA, but you would like to allow bypassing the 2FA when accessing the webhooks.
To do so, we need to create an access application and an access policy for each URL.
Adding a policy and application to protect the n8n application
The first policy we'll create is for assigning 2FA. Click on “Add a policy”:
In the policy name, enter “n8n”, leave the action on “Allow”, and set the session duration for “30 minutes”.
Now, add an include rule to enable access to the application. You can use the following options:
These options are the common ones; there are other options, but I will skip them for now.
For this guide, I will use the “Emails” option. Select “Emails” from the list and set the “Value” to your email address:
Now, scroll down and click on “Save”.
Now, let’s add the Access application that will bind the policy to the application.
On the menu, under Access, click on “Applications”, and then click on “Add an application”:
Next, select “Self-hosted”:
Next, give the application a name, “n8n” in our case, and click on “Add public hostname”:
Recommended by LinkedIn
Next, set the hostname and select the domain from the list
And click on “Select existing policies” and select the Access policy we created in the previous step:
Click on “Confirm”, scroll down, and click on "Next.” In the “Experience settings (optional)” tab, also scroll down and click on “Next”. On the “Advanced settings (optional)” click on “Save” to save the application settings:
Now, if you try to access your n8n instance, you will be asked to provide a valid email address:
If your email is in the allow list, you will get an email with one-time password:
Enter the code you received and click on “Sign in”:
After entering the OTP, you will be redirected to the n8n instance:
Adding a policy and application to bypass the n8n default application and allow access to a specific webhook.
After adding the application and access policy to our n8n application, we also blocked access to the webhook URL.
We can create a bypass policy to overcome this issue and also apply a better security layer to the webhook.
To do so, go back to the Policies page and click on “Add a policy”:
But this time, we will set the action to “Bypass”:
In the Rules section, we will set the selector to “IP ranges” and add the IP ranges of the Telegram servers:
Click on "Save" to apply the new policy settings.
Now we have two policies, and as you can see, each policy has its own action type:
Now, let‘s go back to the application page and create a new Access application to handle the Telegram webhook security.
Click on the “Add an application” button and select “Self-hosted”:
Give the application the same name as the policy name (In our case, “Telegram webhook bypass”), but this time add the webhook path as follows:
Now, click on “Select existing policies”, select the policy we just created, and click on Confirm:
Click on Next until you reach the “Advanced settings” tab, and then click on “Save”:
Now, test the URL, and you will be able to access it without 2FA:
With these policies in place, you’ve added a robust Zero Trust layer to your self-hosted application—securing sensitive routes with strong authentication, while keeping essential integrations accessible where needed. Cloudflare Access and Tunnel together offer a powerful, flexible framework to protect your infrastructure without adding friction.
Show them Tomer, the real thing