Zero Trust in Action: Securing Applications with Cloudflare Tunnel

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).

What Is Cloudflare Tunnel?

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:

  • No public IP or port forwarding
  • TLS out of the box
  • Works with any web server or internal app
  • Supports Docker, Kubernetes, Raspberry Pi, etc.

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:

  • Authenticate users via Google, GitHub, Okta, etc.
  • Define granular rules (email, country, IP)
  • Enforce device posture or one-time pins
  • Bypass rules for trusted IPs (e.g. CI/CD).
  • Authenticate using a service access token.

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”:

Article content

Now, under “Access”, click on “Policies”:

Article content

 

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:

  1. Webhook for Telegram: https://n8n.example.com/webhook/6a41ac92-4bc9-45e4-82fe-ea76dc60123b
  2. Http webhook: https://n8n.example.com/webhook/6a41ac92-4bc9-45e4-82fe-ea76dc64567b.

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”:

Article content

In the policy name, enter “n8n”, leave the action on “Allow”, and set the session duration for “30 minutes”.

Article content

Now, add an include rule to enable access to the application. You can use the following options:

  • Service Token.
  • Country.
  • Emails.
  •  IP Range.

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:

Article content

  • You can set multiple email addresses or configure more than one rule.

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”:

Article content

Next, select “Self-hosted”:

Article content

Next, give the application a name, “n8n” in our case, and click on “Add public hostname”:

Article content

Next, set the hostname and select the domain from the list

Article content

And click on “Select existing policies” and select the Access policy we created in the previous step:

Article content

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:

Article content

Now, if you try to access your n8n instance, you will be asked to provide a valid email address:

Article content

If your email is in the allow list, you will get an email with one-time password:

Article content

Enter the code you received and click on “Sign in”:

Article content

After entering the OTP, you will be redirected to the n8n instance:

Article content

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”:

Article content

But this time, we will set the action to “Bypass”:

Article content

In the Rules section, we will set the selector to “IP ranges” and add the IP ranges of the Telegram servers:

Article content

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:

Article content

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”:

Article content

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:

Article content

Now, click on “Select existing policies”, select the policy we just created, and click on Confirm:

Article content

Click on Next until you reach the “Advanced settings” tab, and then click on “Save”:

Article content

Now, test the URL, and you will be able to access it without 2FA:

Article content


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

To view or add a comment, sign in

More articles by MSD Animal Health Technology Labs

Others also viewed

Explore content categories