Skip to main content

TailscaleRoutePolicy API Reference

The TailscaleRoutePolicy resource defines advanced routing policies and traffic management rules for Tailscale Gateway traffic.

Overview

TailscaleRoutePolicy allows you to:

  • Define sophisticated routing rules based on various conditions
  • Implement traffic splitting and canary deployments
  • Configure rate limiting and circuit breaker policies
  • Set up custom authentication and authorization rules

API Version

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy

Basic Example

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy
metadata:
name: api-routing-policy
namespace: production
spec:
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: api-services

rules:
- matches:
- headers:
- name: "X-User-Type"
value: "premium"
actions:
- type: "Route"
route:
backendRefs:
- name: "premium-api-service"
weight: 100

- matches:
- path:
type: PathPrefix
value: "/v2/"
actions:
- type: "Route"
route:
backendRefs:
- name: "api-v2-service"
weight: 100

Specification

TailscaleRoutePolicySpec

FieldTypeRequiredDescription
targetRefLocalPolicyTargetReferenceYesTarget resource this policy applies to
rules[]PolicyRuleYesList of routing rules
defaultsPolicyDefaultsNoDefault policies applied to all traffic

PolicyRule

FieldTypeRequiredDescription
matches[]RouteMatchNoConditions for when this rule applies
actions[]PolicyActionYesActions to take when rule matches
priorityint32NoRule priority (higher number = higher priority)

RouteMatch

FieldTypeRequiredDescription
pathPathMatchNoHTTP path matching criteria
headers[]HeaderMatchNoHTTP header matching criteria
queryParams[]QueryParamMatchNoQuery parameter matching criteria
methodstringNoHTTP method (GET, POST, PUT, DELETE, etc.)

PolicyAction

FieldTypeRequiredDescription
typestringYesAction type: Route, Redirect, RequestHeaderModifier, etc.
routeRouteActionNoRouting configuration (for type: Route)
redirectRedirectActionNoRedirect configuration (for type: Redirect)
requestHeaderModifierHeaderModifierNoRequest header modification
responseHeaderModifierHeaderModifierNoResponse header modification
rateLimitingRateLimitingActionNoRate limiting configuration
authenticationAuthenticationActionNoAuthentication requirements

Usage Examples

Traffic Splitting and Canary Deployment

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy
metadata:
name: canary-deployment-policy
namespace: production
spec:
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: web-services

rules:
# Canary deployment: 10% traffic to v2, 90% to v1
- matches:
- path:
type: PathPrefix
value: "/api/"
actions:
- type: "Route"
route:
backendRefs:
- name: "api-v1-service"
weight: 90
- name: "api-v2-service"
weight: 10
timeout: "30s"
retryPolicy:
numRetries: 3
perTryTimeout: "10s"

# Beta users get v2 exclusively
- matches:
- headers:
- name: "X-Beta-User"
value: "true"
- path:
type: PathPrefix
value: "/api/"
actions:
- type: "Route"
route:
backendRefs:
- name: "api-v2-service"
weight: 100
priority: 100 # Higher priority than general traffic splitting

Authentication and Authorization

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy
metadata:
name: auth-policy
namespace: production
spec:
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: secure-services

rules:
# Admin endpoints require admin token
- matches:
- path:
type: PathPrefix
value: "/admin/"
actions:
- type: "Authentication"
authentication:
type: "JWT"
jwtProvider:
issuer: "https://auth.company.com"
audiences: ["admin-api"]
jwksUri: "https://auth.company.com/.well-known/jwks.json"
requiredClaims:
- name: "role"
value: "admin"

- type: "RequestHeaderModifier"
requestHeaderModifier:
add:
- name: "X-Authenticated-User"
value: "{jwt.sub}"
- name: "X-User-Role"
value: "{jwt.role}"

# Public endpoints allow anonymous access
- matches:
- path:
type: PathPrefix
value: "/public/"
actions:
- type: "Route"
route:
backendRefs:
- name: "public-api-service"
weight: 100

# All other endpoints require basic authentication
- actions:
- type: "Authentication"
authentication:
type: "Basic"
realm: "API Access"

- type: "Route"
route:
backendRefs:
- name: "api-service"
weight: 100

Rate Limiting and Circuit Breaking

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy
metadata:
name: rate-limiting-policy
namespace: production
spec:
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: api-services

rules:
# Premium users get higher rate limits
- matches:
- headers:
- name: "X-API-Tier"
value: "premium"
actions:
- type: "RateLimiting"
rateLimiting:
requestsPerSecond: 1000
burstSize: 2000
keyExtractor:
type: "Header"
header: "X-API-Key"

- type: "Route"
route:
backendRefs:
- name: "premium-api-service"
weight: 100

# Standard users get basic rate limits
- matches:
- headers:
- name: "X-API-Tier"
value: "standard"
actions:
- type: "RateLimiting"
rateLimiting:
requestsPerSecond: 100
burstSize: 200
keyExtractor:
type: "Header"
header: "X-API-Key"

- type: "Route"
route:
backendRefs:
- name: "standard-api-service"
weight: 100

# Anonymous users get very limited access
- actions:
- type: "RateLimiting"
rateLimiting:
requestsPerSecond: 10
burstSize: 20
keyExtractor:
type: "ClientIP"

- type: "Route"
route:
backendRefs:
- name: "public-api-service"
weight: 100

# Global circuit breaker
defaults:
circuitBreaker:
enabled: true
maxConnections: 1000
maxPendingRequests: 100
consecutiveErrors: 5
interval: "30s"
baseEjectionTime: "30s"
maxEjectionPercent: 50

Geographic Routing

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy
metadata:
name: geo-routing-policy
namespace: production
spec:
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: global-services

rules:
# Route EU users to EU servers
- matches:
- headers:
- name: "CF-IPCountry"
type: "RegularExpression"
value: "DE|FR|IT|ES|NL|GB"
actions:
- type: "Route"
route:
backendRefs:
- name: "eu-api-service"
weight: 100

- type: "ResponseHeaderModifier"
responseHeaderModifier:
add:
- name: "X-Served-By"
value: "eu-cluster"

# Route US users to US servers
- matches:
- headers:
- name: "CF-IPCountry"
value: "US"
actions:
- type: "Route"
route:
backendRefs:
- name: "us-api-service"
weight: 100

- type: "ResponseHeaderModifier"
responseHeaderModifier:
add:
- name: "X-Served-By"
value: "us-cluster"

# Default to global service
- actions:
- type: "Route"
route:
backendRefs:
- name: "global-api-service"
weight: 100

Advanced Header Manipulation

apiVersion: gateway.tailscale.com/v1alpha1
kind: TailscaleRoutePolicy
metadata:
name: header-manipulation-policy
namespace: production
spec:
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: api-services

rules:
# API versioning through headers
- matches:
- headers:
- name: "Accept"
type: "RegularExpression"
value: "application/vnd\\.api\\.v2\\+json"
actions:
- type: "RequestHeaderModifier"
requestHeaderModifier:
add:
- name: "X-API-Version"
value: "v2"
- name: "X-Request-ID"
value: "{request_id}"
set:
- name: "Accept"
value: "application/json"

- type: "Route"
route:
backendRefs:
- name: "api-v2-service"
weight: 100

# Legacy API support
- matches:
- path:
type: PathPrefix
value: "/v1/"
actions:
- type: "RequestHeaderModifier"
requestHeaderModifier:
add:
- name: "X-API-Version"
value: "v1"
- name: "X-Legacy-Request"
value: "true"

- type: "ResponseHeaderModifier"
responseHeaderModifier:
add:
- name: "X-Deprecation-Warning"
value: "This API version is deprecated. Please migrate to v2."
- name: "X-Sunset"
value: "2024-12-31"

- type: "Route"
route:
backendRefs:
- name: "api-v1-service"
weight: 100

Policy Inheritance and Precedence

Rule Priority

  • Higher priority number = higher precedence
  • Rules without priority default to 0
  • Rules with same priority are evaluated in order

Target Hierarchy

# Gateway-level policy (lowest precedence)
targetRef:
kind: Gateway
name: envoy-gateway

# TailscaleGateway-level policy (medium precedence)
targetRef:
group: gateway.tailscale.com
kind: TailscaleGateway
name: production-gateway

# TailscaleEndpoints-level policy (highest precedence)
targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: api-services

Status

status:
conditions:
- type: "Ready"
status: "True"
reason: "PolicyApplied"
message: "Policy rules are applied successfully"

targetRef:
group: gateway.tailscale.com
kind: TailscaleEndpoints
name: api-services

appliedRules:
- ruleIndex: 0
matches: 15
lastMatched: "2024-01-15T10:30:00Z"
- ruleIndex: 1
matches: 3
lastMatched: "2024-01-15T10:25:00Z"

Best Practices

1. Rule Organization

# Use descriptive names and organize by function
rules:
# High priority authentication rules
- matches: [...]
priority: 100

# Medium priority routing rules
- matches: [...]
priority: 50

# Default fallback rules
- actions: [...]
priority: 0

2. Performance Considerations

# Order rules by frequency of matching
rules:
# Most common paths first
- matches:
- path:
type: PathPrefix
value: "/api/v1/"
# ...

# Less common paths later
- matches:
- path:
type: PathPrefix
value: "/admin/"
# ...

3. Security Practices

# Always validate and sanitize headers
requestHeaderModifier:
remove:
- "X-Forwarded-For" # Remove potentially spoofed headers
add:
- name: "X-Gateway-Processed"
value: "true"