fix(tailscale): align tool coverage and outputs with the Tailscale API#5366
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryHigh Risk Overview New operations and tools: API correctness fixes: UX/docs: Reviewed by Cursor Bugbot for commit 7f43c6e. Configure here. |
Greptile SummaryThis PR fixes API alignment bugs in the Tailscale integration (wrong
Confidence Score: 4/5Safe to merge with one behavior change in The new tools and bug fixes are well-implemented and consistent with the existing codebase patterns. The one concern is apps/sim/tools/tailscale/list_auth_keys.ts — the Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Tailscale Block Operation] --> B{Operation type}
B --> C[Device ops]
B --> D[User ops]
B --> E[ACL ops]
B --> F[DNS ops]
B --> G[Auth Key ops]
C --> C1[list_devices / get_device / delete_device / authorize_device]
C --> C2[get_device_routes / set_device_routes / update_device_key]
C --> C3[NEW: expire_device_key - POST /device/id/expire]
D --> D1[list_users - bug fix: profilePicUrl casing]
D --> D2[NEW: suspend_user - POST /users/id/suspend]
D --> D3[NEW: delete_user - POST /users/id/delete]
E --> E1[get_acl - GET /tailnet/t/acl - returns ETag]
E --> E2[NEW: set_acl - POST /tailnet/t/acl - If-Match quoted ETag]
F --> F1[list_dns_nameservers - magicDNS removed]
F --> F2[set_dns_nameservers / get_dns_preferences / set_dns_preferences]
G --> G1[list_auth_keys - CHANGED: all=true includes revoked keys]
G --> G2[create_auth_key / get_auth_key / delete_auth_key]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Tailscale Block Operation] --> B{Operation type}
B --> C[Device ops]
B --> D[User ops]
B --> E[ACL ops]
B --> F[DNS ops]
B --> G[Auth Key ops]
C --> C1[list_devices / get_device / delete_device / authorize_device]
C --> C2[get_device_routes / set_device_routes / update_device_key]
C --> C3[NEW: expire_device_key - POST /device/id/expire]
D --> D1[list_users - bug fix: profilePicUrl casing]
D --> D2[NEW: suspend_user - POST /users/id/suspend]
D --> D3[NEW: delete_user - POST /users/id/delete]
E --> E1[get_acl - GET /tailnet/t/acl - returns ETag]
E --> E2[NEW: set_acl - POST /tailnet/t/acl - If-Match quoted ETag]
F --> F1[list_dns_nameservers - magicDNS removed]
F --> F2[set_dns_nameservers / get_dns_preferences / set_dns_preferences]
G --> G1[list_auth_keys - CHANGED: all=true includes revoked keys]
G --> G2[create_auth_key / get_auth_key / delete_auth_key]
|
|
Fixed — |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fdf867f. Configure here.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6fd8469. Configure here.
- fix list_users profilePicUrl field name (API returns lowercase, was always null) - add nodeId, keyExpiryDisabled, expires to device outputs - quote the If-Match header value on ACL updates per API spec - add set_acl, expire_device_key, suspend_user, delete_user tools - add wandConfig to dnsServers/searchPaths block fields - expand BlockMeta skills/templates for ACL and key-expiry workflows
The GET /tailnet/{tailnet}/dns/nameservers response only returns
{dns: string[]} per the API spec — magicDNS is not part of this
endpoint's response and was always silently false.
Matches the pattern used by the other new tools in this PR (delete_user, suspend_user).
GET /tailnet/{tailnet}/keys silently scopes to the caller's own
keys unless all=true is passed, contradicting the tool's stated
purpose of listing all auth keys in the tailnet.
6fd8469 to
7f43c6e
Compare
|
@cursor review |
Summary
list_usersreadingprofilePicURLinstead of the API's actualprofilePicUrlfield — was always returning nullnodeId(API's preferred device identifier),keyExpiryDisabled, andexpiresto device outputsset_aclIf-Matchheader to be quoted per the Tailscale API specset_acl(write policy back, not just read),expire_device_key,suspend_user,delete_user(proper offboarding — the existing flow only deauthorized devices, never touched the user account)wandConfigto thednsServers/searchPathsblock fields per repo conventionTailscaleBlockMetaskills/templates for ACL management and key-expiry incident responseValidated every one of the 24 tools' endpoints, methods, required/optional params, and response field extraction against the live Tailscale OpenAPI spec and Go SDK source. Two independent passes confirmed full API alignment and that no backwards-incompatible field removals were made.
Type of Change
Testing
Tested manually. Verified against live Tailscale OpenAPI spec + Go client source.
bun run lintandbun run type-checkclean.Checklist