Skip to content

Instantly share code, notes, and snippets.

@DavidArsene
Created November 27, 2025 10:17
Show Gist options
  • Select an option

  • Save DavidArsene/ffaa13ceb50fbdf0444ce2ad07c3ff37 to your computer and use it in GitHub Desktop.

Select an option

Save DavidArsene/ffaa13ceb50fbdf0444ce2ad07c3ff37 to your computer and use it in GitHub Desktop.
{
CapabilityFileSharing: "https://tailscale.com/cap/file-sharing",
CapabilityAdmin: "https://tailscale.com/cap/is-admin",
CapabilityOwner: "https://tailscale.com/cap/is-owner",
// feature enabled/available
CapabilitySSH: "https://tailscale.com/cap/ssh",
// some SSH rule reach this node
CapabilitySSHRuleIn: "https://tailscale.com/cap/ssh-rule-in",
// feature enabled
CapabilityDataPlaneAuditLogs: "https://tailscale.com/cap/data-plane-audit-logs",
// exposes debug endpoints over the PeerAPI
CapabilityDebug: "https://tailscale.com/cap/debug",
CapabilityHTTPS: "https",
// CapabilityMacUIV2 makes the macOS GUI enable its v2 mode.
CapabilityMacUIV2: "https://tailscale.com/cap/mac-ui-v2",
// CapabilityBindToInterfaceByRoute changes how Darwin nodes create
// sockets (in the net/netns package). See that package for more
// details on the behaviour of this capability.
CapabilityBindToInterfaceByRoute: "https://tailscale.com/cap/bind-to-interface-by-route",
// CapabilityDebugDisableAlternateDefaultRouteInterface changes how Darwin
// nodes get the default interface. There is an optional hook (used by the
// macOS and iOS clients) to override the default interface, this capability
// disables that and uses the default behavior (of parsing the routing
// table).
CapabilityDebugDisableAlternateDefaultRouteInterface: "https://tailscale.com/cap/debug-disable-alternate-default-route-interface",
// CapabilityDebugDisableBindConnToInterface disables the automatic binding
// of connections to the default network interface on Darwin nodes.
CapabilityDebugDisableBindConnToInterface: "https://tailscale.com/cap/debug-disable-bind-conn-to-interface",
// CapabilityDebugDisableBindConnToInterface disables the automatic binding
// of connections to the default network interface on Darwin nodes using network extensions
CapabilityDebugDisableBindConnToInterfaceAppleExt: "https://tailscale.com/cap/debug-disable-bind-conn-to-interface-apple-ext",
// CapabilityTailnetLock indicates the node may initialize tailnet lock.
CapabilityTailnetLock: "https://tailscale.com/cap/tailnet-lock",
// Funnel warning capabilities used for reporting errors to the user.
// CapabilityWarnFunnelNoInvite indicates whether Funnel is enabled for the tailnet.
// This cap is no longer used 2023-08-09 onwards.
CapabilityWarnFunnelNoInvite: "https://tailscale.com/cap/warn-funnel-no-invite",
// CapabilityWarnFunnelNoHTTPS indicates HTTPS has not been enabled for the tailnet.
// This cap is no longer used 2023-08-09 onwards.
CapabilityWarnFunnelNoHTTPS: "https://tailscale.com/cap/warn-funnel-no-https",
// Debug logging capabilities
// CapabilityDebugTSDNSResolution enables verbose debug logging for DNS
// resolution for Tailscale-controlled domains (the control server, log
// server, DERP servers, etc.)
CapabilityDebugTSDNSResolution: "https://tailscale.com/cap/debug-ts-dns-resolution",
// CapabilityFunnelPorts specifies the ports that the Funnel is available on.
// The ports are specified as a comma-separated list of port numbers or port
// ranges (e.g. "80,443,8080-8090") in the ports query parameter.
// e.g. https://tailscale.com/cap/funnel-ports?ports=80,443,8080-8090
CapabilityFunnelPorts: "https://tailscale.com/cap/funnel-ports",
// NodeAttrOnlyTCP443 specifies that the client should not attempt to generate
// any outbound traffic that isn't TCP on port 443 (HTTPS). This is used for
// clients in restricted environments where only HTTPS traffic is allowed
// other types of traffic trips outbound firewall alarms. This thus implies
// all traffic is over DERP.
NodeAttrOnlyTCP443: "only-tcp-443",
// NodeAttrFunnel grants the ability for a node to host ingress traffic.
NodeAttrFunnel: "funnel",
// NodeAttrSSHAggregator grants the ability for a node to collect SSH sessions.
NodeAttrSSHAggregator: "ssh-aggregator",
// NodeAttrDebugForceBackgroundSTUN forces a node to always do background
// STUN queries regardless of inactivity.
NodeAttrDebugForceBackgroundSTUN: "debug-always-stun",
// NodeAttrDebugDisableWGTrim disables the lazy WireGuard configuration,
// always giving WireGuard the full netmap, even for idle peers.
NodeAttrDebugDisableWGTrim: "debug-no-wg-trim",
// NodeAttrDisableSubnetsIfPAC controls whether subnet routers should be
// disabled if WPAD is present on the network.
NodeAttrDisableSubnetsIfPAC: "debug-disable-subnets-if-pac",
// NodeAttrDisableUPnP makes the client not perform a UPnP portmapping.
// By default, we want to enable it to see if it works on more clients.
//
// If UPnP catastrophically fails for people, this should be set kill
// new attempts at UPnP connections.
NodeAttrDisableUPnP: "debug-disable-upnp",
// NodeAttrDisableDeltaUpdates makes the client not process updates via the
// delta update mechanism and should instead treat all netmap changes as
// "full" ones as tailscaled did in 1.48.x and earlier.
NodeAttrDisableDeltaUpdates: "disable-delta-updates",
// NodeAttrRandomizeClientPort makes magicsock UDP bind to
// :0 to get a random local port, ignoring any configured
// fixed port.
NodeAttrRandomizeClientPort: "randomize-client-port",
// NodeAttrSilentDisco makes the client suppress disco heartbeats to its
// peers.
NodeAttrSilentDisco: "silent-disco",
// NodeAttrOneCGNATEnable makes the client prefer one big CGNAT /10 route
// rather than a /32 per peer. At most one of this or
// NodeAttrOneCGNATDisable may be set; if neither are, it's automatic.
NodeAttrOneCGNATEnable: "one-cgnat?v=true",
// NodeAttrOneCGNATDisable makes the client prefer a /32 route per peer
// rather than one big /10 CGNAT route. At most one of this or
// NodeAttrOneCGNATEnable may be set; if neither are, it's automatic.
NodeAttrOneCGNATDisable: "one-cgnat?v=false",
// NodeAttrPeerMTUEnable makes the client do path MTU discovery to its
// peers. If it isn't set, it defaults to the client default.
NodeAttrPeerMTUEnable: "peer-mtu-enable",
// NodeAttrDNSForwarderDisableTCPRetries disables retrying truncated
// DNS queries over TCP if the response is truncated.
NodeAttrDNSForwarderDisableTCPRetries: "dns-forwarder-disable-tcp-retries",
// NodeAttrLinuxMustUseIPTables forces Linux clients to use iptables for
// netfilter management.
// This cannot be set simultaneously with NodeAttrLinuxMustUseNfTables.
NodeAttrLinuxMustUseIPTables: "linux-netfilter?v=iptables",
// NodeAttrLinuxMustUseNfTables forces Linux clients to use nftables for
// netfilter management.
// This cannot be set simultaneously with NodeAttrLinuxMustUseIPTables.
NodeAttrLinuxMustUseNfTables: "linux-netfilter?v=nftables",
// NodeAttrDisableSeamlessKeyRenewal disables seamless key renewal, which is
// enabled by default in clients as of 2025-09-17 (1.90 and later).
//
// We will use this attribute to manage the rollout, and disable seamless in
// clients with known bugs.
// http://go/seamless-key-renewal
NodeAttrDisableSeamlessKeyRenewal: "disable-seamless-key-renewal",
// NodeAttrSeamlessKeyRenewal was used to opt-in to seamless key renewal
// during its private alpha.
//
// Deprecated: NodeAttrSeamlessKeyRenewal is deprecated as of CapabilityVersion 126,
// because seamless key renewal is now enabled by default.
NodeAttrSeamlessKeyRenewal: "seamless-key-renewal",
// NodeAttrProbeUDPLifetime makes the client probe UDP path lifetime at the
// tail end of an active direct connection in magicsock.
NodeAttrProbeUDPLifetime: "probe-udp-lifetime",
// NodeAttrsTaildriveShare enables sharing via Taildrive.
NodeAttrsTaildriveShare: "drive:share",
// NodeAttrsTaildriveAccess enables accessing shares via Taildrive.
NodeAttrsTaildriveAccess: "drive:access",
// NodeAttrSuggestExitNode is applied to each exit node which the control plane has determined
// is a recommended exit node.
NodeAttrSuggestExitNode: "suggest-exit-node",
// NodeAttrDisableWebClient disables using the web client.
NodeAttrDisableWebClient: "disable-web-client",
// NodeAttrLogExitFlows enables exit node destinations in network flow logs.
NodeAttrLogExitFlows: "log-exit-flows",
// NodeAttrAutoExitNode permits the automatic exit nodes feature.
NodeAttrAutoExitNode: "auto-exit-node",
// NodeAttrStoreAppCRoutes configures the node to store app connector routes persistently.
NodeAttrStoreAppCRoutes: "store-appc-routes",
// NodeAttrSuggestExitNodeUI allows the currently suggested exit node to appear in the client GUI.
NodeAttrSuggestExitNodeUI: "suggest-exit-node-ui",
// NodeAttrUserDialUseRoutes makes UserDial use either the peer dialer or the system dialer,
// depending on the destination address and the configured routes. When present, it also makes
// the DNS forwarder use UserDial instead of SystemDial when dialing resolvers.
NodeAttrUserDialUseRoutes: "user-dial-routes",
// NodeAttrSSHBehaviorV1 forces SSH to use the V1 behavior (no su, run SFTP in-process)
// Added 2024-05-29 in Tailscale version 1.68.
NodeAttrSSHBehaviorV1: "ssh-behavior-v1",
// NodeAttrSSHBehaviorV2 forces SSH to use the V2 behavior (use su, run SFTP in child process).
// This overrides NodeAttrSSHBehaviorV1 if set.
// See forceV1Behavior in ssh/tailssh/incubator.go for distinction between
// V1 and V2 behavior.
// Added 2024-08-06 in Tailscale version 1.72.
NodeAttrSSHBehaviorV2: "ssh-behavior-v2",
// NodeAttrDisableSplitDNSWhenNoCustomResolvers indicates that the node's
// DNS manager should not adopt a split DNS configuration even though the
// Config of the resolver only contains routes that do not specify custom
// resolver(s), hence all DNS queries can be safely sent to the upstream
// DNS resolver and the node's DNS forwarder doesn't need to handle all
// DNS traffic.
// This is for now (2024-06-06) an iOS-specific battery life optimization,
// and this node attribute allows us to disable the optimization remotely
// if needed.
NodeAttrDisableSplitDNSWhenNoCustomResolvers: "disable-split-dns-when-no-custom-resolvers",
// NodeAttrDisableLocalDNSOverrideViaNRPT indicates that the node's DNS manager should not
// create a default (catch-all) Windows NRPT rule when "Override local DNS" is enabled.
// Without this rule, Windows 8.1 and newer devices issue parallel DNS requests to DNS servers
// associated with all network adapters, even when "Override local DNS" is enabled and/or
// a Mullvad exit node is being used, resulting in DNS leaks.
// We began creating this rule on 2024-06-14, and this node attribute
// allows us to disable the new behavior remotely if needed.
NodeAttrDisableLocalDNSOverrideViaNRPT: "disable-local-dns-override-via-nrpt",
// NodeAttrDisableMagicSockCryptoRouting disables the use of the
// magicsock cryptorouting hook. See tailscale/corp#20732.
//
// Deprecated: NodeAttrDisableMagicSockCryptoRouting is deprecated as of
// CapabilityVersion 124, CryptoRouting is now mandatory. See tailscale/corp#31083.
NodeAttrDisableMagicSockCryptoRouting: "disable-magicsock-crypto-routing",
// NodeAttrDisableCaptivePortalDetection instructs the client to not perform captive portal detection
// automatically when the network state changes.
NodeAttrDisableCaptivePortalDetection: "disable-captive-portal-detection",
// NodeAttrDisableSkipStatusQueue is set when the node should disable skipping
// of queued netmap.NetworkMap between the controlclient and LocalBackend.
// See tailscale/tailscale#14768.
NodeAttrDisableSkipStatusQueue: "disable-skip-status-queue",
// NodeAttrSSHEnvironmentVariables enables logic for handling environment variables sent
// via SendEnv in the SSH server and applying them to the SSH session.
NodeAttrSSHEnvironmentVariables: "ssh-env-vars",
// NodeAttrServiceHost indicates the VIP Services for which the client is
// approved to act as a service host, and which IP addresses are assigned
// to those VIP Services. Any VIP Services that the client is not
// advertising can be ignored.
// Each value of this key in [NodeCapMap] is of type [ServiceIPMappings].
// If multiple values of this key exist, they should be merged in sequence
// (replace conflicting keys).
NodeAttrServiceHost: "service-host",
// NodeAttrMaxKeyDuration represents the MaxKeyDuration setting on the
// tailnet. The value of this key in [NodeCapMap] will be only one entry of
// type float64 representing the duration in seconds. This cap will be
// omitted if the tailnet's MaxKeyDuration is the default.
NodeAttrMaxKeyDuration: "tailnet.maxKeyDuration",
// NodeAttrNativeIPV4 contains the IPV4 address of the node in its
// native tailnet. This is currently only sent to Hello, in its
// peer node list.
NodeAttrNativeIPV4: "native-ipv4",
// NodeAttrDisableRelayServer prevents the node from acting as an underlay
// UDP relay server. There are no expected values for this key; the key
// only needs to be present in [NodeCapMap] to take effect.
NodeAttrDisableRelayServer: "disable-relay-server",
// NodeAttrDisableRelayClient prevents the node from both allocating UDP
// relay server endpoints itself, and from using endpoints allocated by
// its peers. This attribute can be added to the node dynamically; if added
// while the node is already running, the node will be unable to allocate
// endpoints after it next updates its network map, and will be immediately
// unable to use new paths via a UDP relay server. Setting this attribute
// dynamically does not remove any existing paths, including paths that
// traverse a UDP relay server. There are no expected values for this key
// in [NodeCapMap]; the key only needs to be present in [NodeCapMap] to
// take effect.
NodeAttrDisableRelayClient: "disable-relay-client",
// NodeAttrMagicDNSPeerAAAA is a capability that tells the node's MagicDNS
// server to answer AAAA queries about its peers. See tailscale/tailscale#1152.
NodeAttrMagicDNSPeerAAAA: "magicdns-aaaa",
// NodeAttrTrafficSteering configures the node to use the traffic
// steering subsystem for via routes. See tailscale/corp#29966.
NodeAttrTrafficSteering: "traffic-steering",
// NodeAttrTailnetDisplayName is an optional alternate name for the tailnet
// to be displayed to the user.
// If empty or absent, a default is used.
// If this value is present and set by a user this will only include letters,
// numbers, apostrophe, spaces, and hyphens. This may not be true for the default.
// Values can look like "foo.com" or "Foo's Test Tailnet - Staging".
NodeAttrTailnetDisplayName: "tailnet-display-name",
// NodeAttrClientSideReachability configures the node to determine
// reachability itself when choosing connectors. When absent, the
// default behavior is to trust the control plane when it claims that a
// node is no longer online, but that is not a reliable signal.
NodeAttrClientSideReachability: "client-side-reachability",
// NodeAttrDefaultAutoUpdate advertises the default node auto-update setting
// for this tailnet. The node is free to opt-in or out locally regardless of
// this value. Once this has been set and stored in the client, future
// changes from the control plane are ignored.
//
// The value of the key in [NodeCapMap] is a JSON boolean.
NodeAttrDefaultAutoUpdate: "default-auto-update",
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment