types/node, policy/v2: drop taildrive caps from baseline emission

Taildrive (drive:share and drive:access) is policy-driven per
Tailscale's documented behaviour
(https://tailscale.com/docs/features/taildrive). The previous
always-on baseline emission diverged from SaaS for every node not
targeted by a drive nodeAttr -- a real semantic divergence that the
compat suite caught once the test moved to comparing TailNode output
against the captured netmaps.

types.Node.TailNode no longer stamps the drive pair. Operators
wanting taildrive add a nodeAttrs entry:

  "nodeAttrs": [
    { "target": ["*"], "attr": ["drive:share", "drive:access"] }
  ]

unmodelledTailnetStateCaps shrinks accordingly. The baseline-divergence
group is gone; every entry left in the list is genuinely unmodelled
(user-role caps, unimplemented features, tailnet metadata, internal
tuning).

servertest's TestNodeAttrsBaselineCapsAlwaysOn expects the smaller
baseline (admin + ssh + file-sharing). Integration TestGrantCapDrive
grants the drive caps explicitly via NodeAttrs to exercise the
policy-driven emission path.
This commit is contained in:
Kristoffer Dalby
2026-05-11 14:54:03 +00:00
parent 5ebc53c29e
commit 8ea4cd3faa
5 changed files with 42 additions and 69 deletions

View File

@@ -553,6 +553,19 @@ func TestGrantCapDrive(t *testing.T) {
policyv2.Tag("tag:ro-client"): policyv2.Owners{usernameOwner("roclient@")},
policyv2.Tag("tag:no-access"): policyv2.Owners{usernameOwner("noaccess@")},
},
// Taildrive caps (drive:share / drive:access) are policy-driven
// per https://tailscale.com/docs/features/taildrive; no longer
// emitted as TailNode baseline. Stamp on every node so the
// SelfNode.CapMap assertions below remain meaningful.
NodeAttrs: []policyv2.NodeAttrGrant{
{
Targets: policyv2.Aliases{policyv2.Wildcard},
Attrs: []tailcfg.NodeCapability{
tailcfg.NodeAttrsTaildriveShare,
tailcfg.NodeAttrsTaildriveAccess,
},
},
},
Grants: []policyv2.Grant{
// Grant 1: IP connectivity between ALL nodes.
{