Labelgate

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

  1. Define an access policy template using labelgate.access.<name>.* labels
  2. Reference it from a tunnel or DNS service using the access property
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

PropertyDefaultDescription
app_namelabelgate-<name>Cloudflare Access application name
session_duration24hSession duration (e.g., 1h, 24h, 720h)
policy.decisionallowPolicy 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

DecisionCF API ValueDescription
allowallowAllow access if rules match
blockdenyBlock access if rules match
bypassbypassSkip authentication entirely
service_authnon_identityRequire service token or mTLS certificate

allow and block decisions require at least one include rule.

Rule Selectors

SelectorCF Web UI NameExample Values
emailsEmailsuser@example.com,admin@example.com
emails_ending_inEmails ending in@example.com,@company.io
ip_rangesIP ranges192.168.1.0/24,10.0.0.0/8
countryCountryUS,GB,JP
everyoneEveryone(no value needed)
service_tokenService Token<token-id>
access_groupsAccess groups<group-id>
certificateValid Certificate(no value needed)
login_methodsLogin 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 too

When 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

On this page