---
title: Tenant control
description: Tenant control in Gateway.
image: https://developers.cloudflare.com/zt-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/cloudflare-one/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers) 

# Tenant control

Tenant control allows your users to access corporate SaaS applications while blocking access to personal accounts on the same service. For example, you can allow access to your company's Google Workspace while blocking personal Gmail logins.

Gateway implements tenant control by injecting custom HTTP headers into matching requests. These headers tell the SaaS application which tenant (organization) is authorized. If the user attempts to authenticate with a personal account, the SaaS application reads the header and rejects the request.

## Add custom headers for a SaaS application

To create an HTTP policy with custom headers:

1. In the [Cloudflare dashboard ↗](https://dash.cloudflare.com/), go to **Zero Trust** \> **Traffic policies** \> **Firewall policies** \> **HTTP**.
2. Select **Add a policy**.
3. Build an expression to match the SaaS traffic you want to control.
4. In **Action**, select _Allow_. In **Untrusted certificate action**, select _Block_.
5. Under **Add headers to matched requests**, select **Add a header**.
6. Add any custom header names and values corresponding to your [SaaS application](#common-policy-configurations).
7. Select **Create policy**.

Your policy is now displayed in your list of HTTP policies. When your users attempt to authenticate your configured SaaS application with a personal account, authentication will fail.

### Verify custom headers

If you save a HAR (HTTP Archive) file from a browser to analyze your web traffic, custom headers defined with Gateway will not appear in the file. This is because Gateway injects the header after the request leaves the browser.

To verify Gateway is applying a custom header:

1. In your policy with custom headers, add a selector to match traffic for [HTTPBin ↗](https://httpbin.org/), an open-source site for testing HTTP requests. For example:  
| Selector    | Operator | Value              | Logic | Action | Untrusted certificate action |  
| ----------- | -------- | ------------------ | ----- | ------ | ---------------------------- |  
| Application | in       | _Google Workspace_ | And   | Allow  | Block                        |  
| Domain      | in       | httpbin.org        |       |        |                              |
2. On your device, go to [httpbin.org/anything ↗](https://httpbin.org/anything). Your custom header will appear in the list of headers.
3. (Optional) Remove the HTTPBin expression from your policy.

## Common policy configurations

Depending on which SaaS application your organization needs access to, different tenant control policies are required.

### Microsoft 365

Microsoft 365 tenant control requires two policies. When you order your policies, make sure they follow [order of precedence](https://developers.cloudflare.com/cloudflare-one/traffic-policies/order-of-enforcement/#order-of-precedence).

| Precedence | Selector | Operator | Value          | Action | Untrusted certificate action |
| ---------- | -------- | -------- | -------------- | ------ | ---------------------------- |
| 1          | Domain   | is       | login.live.com | Allow  | Block                        |

| Custom header name                | Custom header value |
| --------------------------------- | ------------------- |
| Sec-Restrict-Tenant-Access-Policy | restrict-msa        |

| Precedence | Selector    | Operator | Value                 | Action | Untrusted certificate action |
| ---------- | ----------- | -------- | --------------------- | ------ | ---------------------------- |
| 2          | Application | in       | _Microsoft Office365_ | Allow  | Block                        |

| Custom header name                                  | Custom header value        |
| --------------------------------------------------- | -------------------------- |
| Restrict-Access-To-Tenants, Restrict-Access-Context | Your organization's domain |

For more information, refer to the [Microsoft Entra ID documentation ↗](https://learn.microsoft.com/entra/identity/enterprise-apps/tenant-restrictions).

### Google Workspace

| Selector    | Operator | Value              | Action | Untrusted certificate action |
| ----------- | -------- | ------------------ | ------ | ---------------------------- |
| Application | in       | _Google Workspace_ | Allow  | Block                        |

| Custom header name         | Custom header value        |
| -------------------------- | -------------------------- |
| X-GoogApps-Allowed-Domains | Your organization's domain |

For more information, refer to the [Google Workspace documentation ↗](https://support.google.com/a/answer/1668854).

### Slack

| Selector    | Operator | Value   | Action | Untrusted certificate action |
| ----------- | -------- | ------- | ------ | ---------------------------- |
| Application | in       | _Slack_ | Allow  | Block                        |

| Custom header name                                               | Custom header value           |
| ---------------------------------------------------------------- | ----------------------------- |
| X-Slack-Allowed-Workspaces-Requester, X-Slack-Allowed-Workspaces | Your organization's workspace |

For more information, refer to the [Slack documentation ↗](https://slack.com/help/articles/360024821873-Approve-Slack-workspaces-for-your-network).

### Dropbox

| Selector    | Operator | Value     | Action | Untrusted certificate action |
| ----------- | -------- | --------- | ------ | ---------------------------- |
| Application | in       | _Dropbox_ | Allow  | Block                        |

| Custom header name         | Custom header value    |
| -------------------------- | ---------------------- |
| X-Dropbox-allowed-Team-Ids | Your organization's ID |

For more information, refer to the [Dropbox documentation ↗](https://help.dropbox.com/security/network-control).

### ChatGPT

| Selector    | Operator | Value     | Action | Untrusted certificate action |
| ----------- | -------- | --------- | ------ | ---------------------------- |
| Application | in       | _ChatGPT_ | Allow  | Block                        |

| Custom header name           | Custom header value              |
| ---------------------------- | -------------------------------- |
| Chatgpt-Allowed-Workspace-Id | Your organization's workspace ID |

For more information, refer to the [OpenAI documentation ↗](https://help.openai.com/articles/8798594-what-is-a-workspace-how-do-i-access-my-chatgpt-business-workspace).

## Exempt users in Cloudflare WAF

You can include custom headers in an HTTP policy to allow your users through [Cloudflare WAF](https://developers.cloudflare.com/waf/). This is useful for allowing only Cloudflare One Client users through your WAF.

1. Create an Allow policy for an internal domain behind your WAF with a custom header.  
| Selector | Operator | Value           | Action |  
| -------- | -------- | --------------- | ------ |  
| Domain   | in       | internalapp.com | Allow  |  
| Custom header name | Custom header value |  
| ------------------ | ------------------- |  
| X-Example-Header   | example-value       |
2. In Cloudflare WAF, [create a custom rule](https://developers.cloudflare.com/waf/custom-rules/) to [require the same HTTP header](https://developers.cloudflare.com/waf/custom-rules/use-cases/require-specific-headers/#example-2-require-http-header-with-a-specific-value).

## Use tenant control with Browser Isolation

You can configure [Browser Isolation](https://developers.cloudflare.com/cloudflare-one/remote-browser-isolation/) to send custom headers. This is useful for implementing tenant control for isolated SaaS applications or sending arbitrary custom request headers to isolated websites.

To use custom headers with Browser Isolation, create two HTTP policies targeting the same domain or application group. For example, you can create policies for [HTTPBin ↗](https://httpbin.org/), an open-source site for testing HTTP requests:

1. Create an Isolate policy for `httpbin.org`.  
| Selector | Operator | Value       | Action  |  
| -------- | -------- | ----------- | ------- |  
| Domain   | in       | httpbin.org | Isolate |
2. Create an Allow policy for `httpbin.org` with a custom header.  
| Selector | Operator | Value       | Action |  
| -------- | -------- | ----------- | ------ |  
| Domain   | in       | httpbin.org | Allow  |  
| Custom header name | Custom header value |  
| ------------------ | ------------------- |  
| Example-Header     | example-value       |
3. Go to [httpbin.org/anything ↗](https://httpbin.org/anything). Cloudflare will render the site in an isolated browser. Your custom header will appear in the list of headers.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cloudflare-one/","name":"Cloudflare One"}},{"@type":"ListItem","position":3,"item":{"@id":"/cloudflare-one/traffic-policies/","name":"Traffic policies"}},{"@type":"ListItem","position":4,"item":{"@id":"/cloudflare-one/traffic-policies/http-policies/","name":"HTTP policies"}},{"@type":"ListItem","position":5,"item":{"@id":"/cloudflare-one/traffic-policies/http-policies/tenant-control/","name":"Tenant control"}}]}
```
