Detection rules › Kusto
Tailscale: Unauthorized device connected to control plane
Identifies devices actively connected to the Tailscale control plane (ConnectedToControl=true) but not yet authorized by an admin (Authorized=false). Often benign onboarding but can indicate rogue joins.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Initial Access | |
| Persistence |
Rule body
id: a1b2c3d4-5678-9012-3456-789012340042
name: "Tailscale: Unauthorized device connected to control plane"
description: Identifies devices actively connected to the Tailscale control plane (ConnectedToControl=true) but not yet authorized by an admin (Authorized=false). Often benign onboarding but can indicate rogue joins.
description-detailed: |
Identifies devices actively connected to the Tailscale control plane (ConnectedToControl=true) but not yet authorized by an admin (Authorized=false). With device approval enabled, persistent entries warrant review; without approval, persistence may indicate a node-key injection attempt.
severity: High
status: Available
requiredDataConnectors:
- connectorId: TailscaleCCF
dataTypes:
- Tailscale_Devices_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
- Persistence
relevantTechniques:
- T1078
- T1098
query: |
Tailscale_Devices_CL
| where TimeGenerated > ago(1h)
| summarize arg_max(TimeGenerated, *) by DeviceId
| where Authorized == false and ConnectedToControl == true
| project TimeGenerated, DeviceName, Hostname, User, Os, ClientVersion, Created, LastSeen, MachineKey, NodeKey
entityMappings:
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: Hostname
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: User
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: P1D
matchingMethod: AllEntities
kind: Scheduled
version: 1.0.0
Stages and Predicates
Stage 1: source
Tailscale_Devices_CL
Stage 2: where
| where TimeGenerated > ago(1h)
Stage 3: summarize
| summarize arg_max(TimeGenerated, *) by DeviceId
Stage 4: where
| where Authorized == false and ConnectedToControl == true
Stage 5: project
| project TimeGenerated, DeviceName, Hostname, User, Os, ClientVersion, Created, LastSeen, MachineKey, NodeKey
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Authorized | eq |
| field:"Authorized" kind:eq value:"false" |
ConnectedToControl | eq |
| field:"ConnectedToControl" kind:eq value:"true" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
ClientVersion | project |
Created | project |
DeviceName | project |
Hostname | project |
LastSeen | project |
MachineKey | project |
NodeKey | project |
Os | project |
TimeGenerated | project |
User | project |