Tag customization for the Tailscale Kubernetes Operator

Last validated:

The Tailscale Kubernetes Operator uses tags to identify and control access to the devices it manages. Tags control which tailnet identities can reach operator-managed devices, and which devices can advertise Tailscale Services.

The operator uses two default tags:

  • tag:k8s-operator: Applied to the operator device itself.
  • tag:k8s: Applied to all proxy devices the operator creates (ingress proxies, egress proxies, connectors, and ProxyGroup replicas).

Default tags

You configure default tags during operator installation using Helm values:

  • operatorConfig.defaultTags: Tags for the operator device. Defaults to tag:k8s-operator.
  • proxyConfig.defaultTags: Tags for all proxy devices the operator creates. Defaults to tag:k8s.

To set custom defaults during installation:

helm upgrade --install tailscale-operator tailscale/tailscale-operator \
  --namespace=tailscale \
  --set-json 'operatorConfig.defaultTags=["tag:k8s-operator"]' \
  --set-json 'proxyConfig.defaultTags=["tag:k8s","tag:prod"]'

Tag ownership

The operator's tag must own the proxy tags in your tailnet policy file. Without this, the operator cannot create devices with those tags.

For the default tags, add the following to your tailnet policy file from the Access controls:

"tagOwners": {
  "tag:k8s-operator": [],
  "tag:k8s": ["tag:k8s-operator"]
}

This configuration makes tag:k8s-operator owned by tailnet admins, and allows devices tagged tag:k8s-operator (the operator) to create devices tagged tag:k8s.

If you use custom tags, the operator's tag must also own those tags. For example, if you tag proxies with tag:prod:

"tagOwners": {
  "tag:k8s-operator": [],
  "tag:k8s": ["tag:k8s-operator"],
  "tag:prod": ["tag:k8s-operator"]
}

Customize tags per resource

You can override default proxy tags on individual resources.

Connector

Set tags in the Connector spec:

apiVersion: tailscale.com/v1alpha1
kind: Connector
metadata:
  name: my-connector
spec:
  tags:
    - "tag:k8s"
    - "tag:subnet-prod"
  subnetRouter:
    advertiseRoutes:
      - "10.40.0.0/14"

ProxyGroup

Set tags in the ProxyGroup spec:

apiVersion: tailscale.com/v1alpha1
kind: ProxyGroup
metadata:
  name: my-proxy-group
spec:
  tags:
    - "tag:k8s"
    - "tag:eu-cluster"

Service or Ingress (standalone proxies)

Use the tailscale.com/tags annotation:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  annotations:
    tailscale.com/expose: "true"
    tailscale.com/tags: "tag:k8s,tag:monitoring"
spec:
  selector:
    app: my-app
  ports:
    - port: 80

As with all custom tags, the operator's tag must be a tagOwner of these tags. Refer to tag ownership for details.

Tags in access control

Tags are the primary mechanism for controlling access to operator-managed devices. Use tags in your tailnet policy file to:

  • Grant access with ACLs or grants: Allow specific tailnet identities to reach devices with a given tag. Refer to grants and ACLs.
  • Approve Tailscale Service advertisers: Use autoApprovers to permit ProxyGroup devices to advertise Tailscale Services. Refer to permissions and RBAC for examples.

Tags and the API server proxy

When a tagged device connects to the API server proxy, the proxy impersonates the request using the device's tags as Kubernetes groups. For example, a device tagged tag:ci-runner is impersonated with the Kubernetes group tag:ci-runner. You can bind these groups to Kubernetes roles using standard RBAC.

If grants define additional Kubernetes groups for the device, those take precedence over tag-based groups.

Limitations

  • The operator applies tags only during initial device provisioning. If you modify the tailscale.com/tags annotation on an already-exposed Service, the tags do not update until you recreate the Service.
  • Connector tags cannot be changed after the connector device is created.

For a full list, refer to limitations.

Next steps