Access Policy Labels
Complete reference for Labelgate Zero Trust Access Policy labels.
Access Policy labels let you protect services with Cloudflare Zero Trust Access. They work by defining reusable policy templates that are referenced from tunnel or DNS services.
How It Works
- Define an access policy template using
labelgate.access.<name>.*labels - Reference it from a tunnel or DNS service using the
accessproperty
labels:
# Step 1: Define a policy named "internal"
labelgate.access.internal.policy.decision: "allow"
labelgate.access.internal.policy.include.emails: "admin@example.com,dev@example.com"
# Step 2: Reference it from a tunnel service
labelgate.tunnel.web.hostname: "app.example.com"
labelgate.tunnel.web.service: "http://app:80"
labelgate.tunnel.web.access: "internal"Policy Definition Format
labelgate.access.<policy_name>.<property>=<value>Policy Properties
| Property | Default | Description |
|---|---|---|
app_name | labelgate-<name> | Cloudflare Access application name |
session_duration | 24h | Session duration (e.g., 1h, 24h, 720h) |
policy.decision | allow | Policy action: allow, block, bypass, service_auth |
policy.name | - | Policy display name in CF dashboard |
policy.include.<selector> | - | Include rules (OR logic) |
policy.require.<selector> | - | Require rules (AND logic) |
policy.exclude.<selector> | - | Exclude rules (NOT logic) |
Decisions
| Decision | CF API Value | Description |
|---|---|---|
allow | allow | Allow access if rules match |
block | deny | Block access if rules match |
bypass | bypass | Skip authentication entirely |
service_auth | non_identity | Require service token or mTLS certificate |
allow and block decisions require at least one include rule.
Rule Selectors
| Selector | CF Web UI Name | Example Values |
|---|---|---|
emails | Emails | user@example.com,admin@example.com |
emails_ending_in | Emails ending in | @example.com,@company.io |
ip_ranges | IP ranges | 192.168.1.0/24,10.0.0.0/8 |
country | Country | US,GB,JP |
everyone | Everyone | (no value needed) |
service_token | Service Token | <token-id> |
access_groups | Access groups | <group-id> |
certificate | Valid Certificate | (no value needed) |
login_methods | Login Methods | <method-id> |
Multiple values are comma-separated. Selectors like everyone and certificate don't require values.
Rule Logic
- Include rules use OR logic - any matching rule grants/blocks access
- Require rules use AND logic - all rules must match
- Exclude rules use NOT logic - matching rules are exempted
Examples
Allow specific emails
labels:
labelgate.access.team.policy.decision: "allow"
labelgate.access.team.policy.include.emails: "alice@example.com,bob@example.com"
labelgate.access.team.session_duration: "12h"
labelgate.tunnel.admin.hostname: "admin.example.com"
labelgate.tunnel.admin.service: "http://admin:8080"
labelgate.tunnel.admin.access: "team"Allow by email domain
labels:
labelgate.access.company.policy.decision: "allow"
labelgate.access.company.policy.include.emails_ending_in: "@company.io"
labelgate.tunnel.app.hostname: "app.company.io"
labelgate.tunnel.app.service: "http://app:80"
labelgate.tunnel.app.access: "company"IP-restricted access
labels:
labelgate.access.office.policy.decision: "allow"
labelgate.access.office.policy.include.ip_ranges: "203.0.113.0/24,198.51.100.0/24"
labelgate.tunnel.internal.hostname: "internal.example.com"
labelgate.tunnel.internal.service: "http://internal:3000"
labelgate.tunnel.internal.access: "office"Bypass authentication (public access)
labels:
labelgate.access.public.policy.decision: "bypass"
labelgate.access.public.policy.include.everyone: ""
labelgate.tunnel.docs.hostname: "docs.example.com"
labelgate.tunnel.docs.service: "http://docs:80"
labelgate.tunnel.docs.access: "public"Service token authentication
labels:
labelgate.access.machine.policy.decision: "service_auth"
labelgate.access.machine.policy.include.service_token: "your-service-token-id"
labelgate.tunnel.api.hostname: "api.example.com"
labelgate.tunnel.api.service: "http://api:8080"
labelgate.tunnel.api.access: "machine"Combined rules (include + require + exclude)
labels:
# Allow company emails, require US location, exclude contractors
labelgate.access.secure.policy.decision: "allow"
labelgate.access.secure.policy.include.emails_ending_in: "@company.io"
labelgate.access.secure.policy.require.country: "US"
labelgate.access.secure.policy.exclude.emails: "contractor1@company.io,contractor2@company.io"
labelgate.tunnel.secure.hostname: "secure.company.io"
labelgate.tunnel.secure.service: "http://secure:443"
labelgate.tunnel.secure.access: "secure"Shared policy across multiple services
labels:
# Define one policy
labelgate.access.internal.policy.decision: "allow"
labelgate.access.internal.policy.include.emails_ending_in: "@example.com"
# Reuse it across multiple services
labelgate.tunnel.app.hostname: "app.example.com"
labelgate.tunnel.app.service: "http://app:80"
labelgate.tunnel.app.access: "internal"
labelgate.tunnel.admin.hostname: "admin.example.com"
labelgate.tunnel.admin.service: "http://admin:8080"
labelgate.tunnel.admin.access: "internal"Cleanup Behavior
Access policies don't have their own cleanup label. Instead, the cleanup behavior is inherited from the tunnel or DNS service that references the access policy.
labels:
labelgate.access.team.policy.decision: "allow"
labelgate.access.team.policy.include.emails_ending_in: "@company.io"
labelgate.tunnel.web.hostname: "app.company.io"
labelgate.tunnel.web.service: "http://app:80"
labelgate.tunnel.web.access: "team"
labelgate.tunnel.web.cleanup: "true" # This controls access cleanup tooWhen cleanup is enabled on the referencing service:
- If the container stops, the Access Application on Cloudflare will be removed after the configured
sync.remove_delay(default: 30 minutes) - The associated reusable policies are also cleaned up if no other application references them
When cleanup is disabled (default):
- The Access Application is marked as orphaned in labelgate but preserved on Cloudflare
- It will be reactivated automatically if the container restarts