policy: update tests for SSH validation rules

Update unit tests to use valid SSH patterns that conform to Tailscale's
security model:

- Change group->user destinations to group->tag
- Change tag->user destinations to tag->tag
- Update expected error messages for new validation format
- Add proper tagged/untagged node setup in filter tests

Updates #3009
Updates #3010
This commit is contained in:
Kristoffer Dalby 2026-01-21 12:14:56 +00:00
parent 5688c201e9
commit d40203e153
3 changed files with 407 additions and 77 deletions

View file

@ -1092,6 +1092,15 @@ func TestSSHPolicyRules(t *testing.T) {
Tags: []string{"tag:client"},
}
// Create a tagged server node for valid SSH patterns
nodeTaggedServer := types.Node{
Hostname: "tagged-server",
IPv4: ap("100.64.0.5"),
UserID: ptr.To(uint(1)),
User: ptr.To(users[0]),
Tags: []string{"tag:server"},
}
tests := []struct {
name string
targetNode types.Node
@ -1102,10 +1111,13 @@ func TestSSHPolicyRules(t *testing.T) {
errorMessage string
}{
{
name: "group-to-user",
targetNode: nodeUser1,
name: "group-to-tag",
targetNode: nodeTaggedServer,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
@ -1113,7 +1125,7 @@ func TestSSHPolicyRules(t *testing.T) {
{
"action": "accept",
"src": ["group:admins"],
"dst": ["user1@"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot"]
}
]
@ -1138,18 +1150,21 @@ func TestSSHPolicyRules(t *testing.T) {
},
{
name: "check-period-specified",
targetNode: nodeUser1,
peers: types.Nodes{&taggedClient},
targetNode: taggedClient,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:client": ["user1@"],
"tag:client": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
"ssh": [
{
"action": "check",
"checkPeriod": "24h",
"src": ["tag:client"],
"dst": ["user1@"],
"src": ["group:admins"],
"dst": ["tag:client"],
"users": ["autogroup:nonroot"]
}
]
@ -1157,7 +1172,7 @@ func TestSSHPolicyRules(t *testing.T) {
wantSSH: &tailcfg.SSHPolicy{Rules: []*tailcfg.SSHRule{
{
Principals: []*tailcfg.SSHPrincipal{
{NodeIP: "100.64.0.4"},
{NodeIP: "100.64.0.2"},
},
SSHUsers: map[string]string{
"*": "=",
@ -1176,16 +1191,19 @@ func TestSSHPolicyRules(t *testing.T) {
{
name: "no-matching-rules",
targetNode: nodeUser2,
peers: types.Nodes{&nodeUser1},
peers: types.Nodes{&nodeUser1, &nodeTaggedServer},
policy: `{
"tagOwners": {
"tag:client": ["user1@"],
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user1@"]
},
"ssh": [
{
"action": "accept",
"src": ["tag:client"],
"dst": ["user1@"],
"src": ["group:admins"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot"]
}
]
@ -1194,14 +1212,20 @@ func TestSSHPolicyRules(t *testing.T) {
},
{
name: "invalid-action",
targetNode: nodeUser1,
targetNode: nodeTaggedServer,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
"ssh": [
{
"action": "invalid",
"src": ["group:admins"],
"dst": ["user1@"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot"]
}
]
@ -1211,15 +1235,21 @@ func TestSSHPolicyRules(t *testing.T) {
},
{
name: "invalid-check-period",
targetNode: nodeUser1,
targetNode: nodeTaggedServer,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
"ssh": [
{
"action": "check",
"checkPeriod": "invalid",
"src": ["group:admins"],
"dst": ["user1@"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot"]
}
]
@ -1229,26 +1259,12 @@ func TestSSHPolicyRules(t *testing.T) {
},
{
name: "unsupported-autogroup",
targetNode: nodeUser1,
peers: types.Nodes{&taggedClient},
policy: `{
"ssh": [
{
"action": "accept",
"src": ["tag:client"],
"dst": ["user1@"],
"users": ["autogroup:invalid"]
}
]
}`,
expectErr: true,
errorMessage: "autogroup \"autogroup:invalid\" is not supported",
},
{
name: "autogroup-nonroot-should-use-wildcard-with-root-excluded",
targetNode: nodeUser1,
targetNode: taggedClient,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:client": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
@ -1256,7 +1272,30 @@ func TestSSHPolicyRules(t *testing.T) {
{
"action": "accept",
"src": ["group:admins"],
"dst": ["user1@"],
"dst": ["tag:client"],
"users": ["autogroup:invalid"]
}
]
}`,
expectErr: true,
errorMessage: "autogroup \"autogroup:invalid\" is not supported",
},
{
name: "autogroup-nonroot-should-use-wildcard-with-root-excluded",
targetNode: nodeTaggedServer,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
"ssh": [
{
"action": "accept",
"src": ["group:admins"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot"]
}
]
@ -1282,9 +1321,12 @@ func TestSSHPolicyRules(t *testing.T) {
},
{
name: "autogroup-nonroot-plus-root-should-use-wildcard-with-root-mapped",
targetNode: nodeUser1,
targetNode: nodeTaggedServer,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
@ -1292,7 +1334,7 @@ func TestSSHPolicyRules(t *testing.T) {
{
"action": "accept",
"src": ["group:admins"],
"dst": ["user1@"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot", "root"]
}
]
@ -1318,9 +1360,12 @@ func TestSSHPolicyRules(t *testing.T) {
},
{
name: "specific-users-should-map-to-themselves-not-equals",
targetNode: nodeUser1,
targetNode: nodeTaggedServer,
peers: types.Nodes{&nodeUser2},
policy: `{
"tagOwners": {
"tag:server": ["user1@"]
},
"groups": {
"group:admins": ["user2@"]
},
@ -1328,7 +1373,7 @@ func TestSSHPolicyRules(t *testing.T) {
{
"action": "accept",
"src": ["group:admins"],
"dst": ["user1@"],
"dst": ["tag:server"],
"users": ["ubuntu", "root"]
}
]