policy/v2: send an empty SSH policy when no rule applies

Nil SSHPolicy means "unchanged" to clients; removed rules stayed live.
Match SaaS: "rules":[].

Fixes #3508
This commit is contained in:
Kristoffer Dalby authored and Kristoffer Dalby committed 2026-10-08 10:29:23 +02:00
1 parent 82df3e088a
commit 2a0823ca41
3 files changed
+7 -5

No files matched your search

+1 -1
View File
@@ -458,7 +458,7 @@ func TestSSHPolicyRules(t *testing.T) {
} }
] ]
}`, }`,
wantSSH: &tailcfg.SSHPolicy{Rules: nil}, wantSSH: &tailcfg.SSHPolicy{Rules: []*tailcfg.SSHRule{}},
}, },
{ {
name: "invalid-action", name: "invalid-action",
+5 -3
View File
@@ -261,13 +261,15 @@ func (pol *Policy) compileSSHPolicy(
node types.NodeView, node types.NodeView,
nodes views.Slice[types.NodeView], nodes views.Slice[types.NodeView],
) (*tailcfg.SSHPolicy, error) { ) (*tailcfg.SSHPolicy, error) {
if pol == nil || pol.SSHs == nil || len(pol.SSHs) == 0 { // Never nil: clients read a nil SSHPolicy as "keep the previous
return nil, nil //nolint:nilnil // intentional: no SSH policy when none configured // rules", so revoked access would stay. SaaS sends "rules":[].
if pol == nil || len(pol.SSHs) == 0 {
return &tailcfg.SSHPolicy{Rules: []*tailcfg.SSHRule{}}, nil
} }
log.Trace().Caller().Msgf("compiling SSH policy for node %q", node.Hostname()) log.Trace().Caller().Msgf("compiling SSH policy for node %q", node.Hostname())
var rules []*tailcfg.SSHRule rules := []*tailcfg.SSHRule{}
for index, rule := range pol.SSHs { for index, rule := range pol.SSHs {
var autogroupSelfDests, otherDests []Alias var autogroupSelfDests, otherDests []Alias
+1 -1
View File
@@ -618,7 +618,7 @@ func TestCompileSSHPolicy_UserMapping(t *testing.T) {
}, },
}, },
}, },
want: &tailcfg.SSHPolicy{}, want: &tailcfg.SSHPolicy{Rules: []*tailcfg.SSHRule{}},
}, },
} }