policy/v2: align SSH check action with SaaS wire format

SSH check rules now emit CheckPeriod in seconds (matching
Tailscale SaaS) instead of nanoseconds. Adds golden compat tests covering
accept/check modes.

Updates #3157
This commit is contained in:
Kristoffer Dalby 2026-04-15 08:27:57 +00:00
parent ded51a4d30
commit affaa1a31d
2 changed files with 42 additions and 6 deletions

View file

@ -169,7 +169,7 @@ func (h *Headscale) NoiseUpgradeHandler(
r.Post("/map", ns.PollNetMapHandler)
// SSH Check mode endpoint, consulted to validate if a given SSH connection should be accepted or rejected.
r.Get("/ssh/action/from/{src_node_id}/to/{dst_node_id}", ns.SSHActionHandler)
r.Get("/ssh/action/{src_node_id}/to/{dst_node_id}", ns.SSHActionHandler)
// Not implemented yet
//
@ -414,7 +414,6 @@ func (ns *noiseServer) SSHActionHandler(
reqLog := log.With().
Uint64("src_node_id", srcNodeID.Uint64()).
Uint64("dst_node_id", dstNodeID.Uint64()).
Str("ssh_user", req.URL.Query().Get("ssh_user")).
Str("local_user", req.URL.Query().Get("local_user")).
Logger()
@ -515,8 +514,8 @@ func (ns *noiseServer) sshActionHoldAndDelegate(
) (*tailcfg.SSHAction, error) {
holdURL, err := url.Parse(
ns.headscale.cfg.ServerURL +
"/machine/ssh/action/from/$SRC_NODE_ID/to/$DST_NODE_ID" +
"?ssh_user=$SSH_USER&local_user=$LOCAL_USER",
"/machine/ssh/action/$SRC_NODE_ID/to/$DST_NODE_ID" +
"?local_user=$LOCAL_USER",
)
if err != nil {
return nil, NewHTTPError(