An open source, self-hosted implementation of the Tailscale control server
314 matches across 5 categories. Click a row to expand file-level details.
| Severity | File | Line | Snippet |
|---|---|---|---|
| LOW | config-example.yaml | 1 | --- |
| LOW | config-example.yaml | 21 | # Address to listen to /metrics and /debug, you may want |
| LOW | config-example.yaml | 41 | |
| LOW | config-example.yaml | 61 | # WARNING: These prefixes MUST be subsets of the standard Tailscale ranges: |
| LOW | config-example.yaml | 81 | # IP. A best-effort approach is used and Headscale might leave holes in the |
| LOW | config-example.yaml | 121 | # If you enable the DERP server and set this to false, it is required to add the DERP server to the DERP map using D |
| LOW | config-example.yaml | 141 | paths: [] |
| LOW | config-example.yaml | 161 | # |
| LOW | config-example.yaml | 181 | # |
| LOW | config-example.yaml | 221 | # Enable WAL mode for SQLite. This is recommended for production environments. |
| LOW | config-example.yaml | 241 | # max_idle_conns: 10 |
| LOW | config-example.yaml | 261 | # Domain name to request a TLS certificate for: |
| LOW | config-example.yaml | 301 | ## DNS |
| LOW | config-example.yaml | 341 | - 2606:4700:4700::1111 |
| LOW | config-example.yaml | 361 | # Extra DNS records |
| LOW | config-example.yaml | 381 | # OpenID Connect |
| LOW | config-example.yaml | 401 | # # Use the expiry from the token received from OpenID when the user logged |
| LOW | config-example.yaml | 421 | # extra_params: |
| LOW | config-example.yaml | 441 | # pkce: |
| LOW | config-example.yaml | 461 | # Taildrop configuration |
| LOW | config-example.yaml | 481 | # Only modify these if you have identified a specific performance issue. |
| LOW | cmd/vendorhash/main.go | 1 | // vendorhash maintains the Nix SRI hash for the Go module vendor tree |
| LOW | integration/auth_oidc_test.go | 121 | t.Fatalf("unexpected users: %s", diff) |
| LOW | integration/auth_oidc_test.go | 1081 | listNodes, err := headscale.ListNodes() |
| LOW | integration/auth_oidc_test.go | 1101 | // - The test verifies that the node ID is preserved (since it's the same user on the same device) |
| LOW | integration/auth_oidc_test.go | 1321 | } |
| LOW | integration/auth_oidc_test.go | 1461 | // policy applied until they restarted their client. This was a regression |
| LOW | integration/auth_oidc_test.go | 1741 | }, integrationutil.ScaledTimeout(10*time.Second), integrationutil.SlowPoll, "headscale should have correct users and no |
| LOW | integration/auth_key_test.go | 561 | |
| LOW | integration/acl_test.go | 621 | assert.EventuallyWithT(t, func(c *assert.CollectT) { |
| LOW | integration/acl_test.go | 641 | // "SrcIPs": ["*"] |
| LOW | integration/acl_test.go | 3141 | // |
| LOW | integration/acl_test.go | 3301 | // Additional verification: check filter rules are not empty |
| LOW | integration/acl_test.go | 3461 | // This test verifies that: |
| LOW | integration/auth_web_flow_test.go | 201 | // initially authenticate using the web-based authentication flow (where users visit a URL |
| LOW | integration/tags_test.go | 2781 | assertNodeHasTagsWithCollect(c, nodes[0], []string{"tag:valid-owned"}) |
| LOW | integration/tags_test.go | 3081 | t.Logf("Test 5.2 PASS: Registration correctly rejected with error: %v", err) |
| LOW | integration/route_test.go | 2161 | panic("node not found") |
| LOW | integration/route_test.go | 3841 | ip, err := subRouter2.IPv4() |
| LOW | integration/route_test.go | 4061 | // than a graceful tailscale down. The two differ in what the server sees: |
| LOW | integration/route_test.go | 4261 | assert.Contains(c, peer.PrimaryRoutes.AsSlice(), pref) |
| LOW | integration/route_test.go | 4281 | // resumes when r1 returns. |
| LOW | integration/scenario.go | 61 | // The list contains two special cases, "head" and "unstable" which |
| LOW | integration/scenario.go | 141 | // Networks, if set, is the separate Docker networks that should be |
| LOW | integration/scenario.go | 1741 | // endpoint. |
| LOW | integration/scenario.go | 1761 | // return errStatusCodeNotOK |
| LOW | integration/tsic/tsic.go | 1021 | // Netmap returns the current Netmap ([netmap.NetworkMap]) of the Tailscale instance. |
| LOW | hscontrol/grpcv1.go | 281 | // dependency here. |
| LOW | hscontrol/auth_test.go | 2301 | "error-test-method", |
| LOW | hscontrol/auth_test.go | 2941 | t.Logf("✓ New node created for user1 with machine key from %s (ID=%d)", node.hostname, newNode.ID().Uint64()) |
| LOW | hscontrol/auth_test.go | 3161 | |
| LOW | hscontrol/auth_test.go | 3441 | assert.Equal(t, initialNodeID, allNodes.At(0).ID(), "node ID should not change on re-registration") |
| LOW | hscontrol/auth_test.go | 3781 | |
| LOW | hscontrol/auth.go | 61 | } |
| LOW | hscontrol/auth.go | 381 | } |
| LOW | hscontrol/oidc.go | 861 | ) |
| LOW | hscontrol/app.go | 221 | for _, d := range magicDNSDomains { |
| LOW | hscontrol/noise.go | 181 | // /whoami is a debug endpoint to validate that the client can communicate over the connection, |
| LOW | hscontrol/auth_tags_test.go | 1261 | assert.True(t, node2.Expiry().Get().After(firstExpiry), |
| LOW | hscontrol/types/users.go | 61 | |
| 120 more matches not shown… | |||
| Severity | File | Line | Snippet |
|---|---|---|---|
| LOW | integration/auth_oidc_test.go | 1834 | // Step 1: Verify initial route is advertised, approved, and SERVING |
| LOW | integration/auth_oidc_test.go | 1863 | // Step 2: Logout |
| LOW | integration/auth_oidc_test.go | 1885 | // Step 3: Re-authenticate via OIDC as the same user |
| LOW | integration/auth_oidc_test.go | 1903 | // Step 4: THE CRITICAL TEST - Verify routes are STILL SERVING after re-authentication |
| LOW | integration/auth_key_test.go | 640 | // Step 1: Verify initial route is advertised, approved, and SERVING |
| LOW | integration/auth_key_test.go | 669 | // Step 2: Logout |
| LOW | integration/auth_key_test.go | 691 | // Step 3: Re-authenticate with the SAME user (using auth key) |
| LOW | integration/auth_key_test.go | 714 | // Step 4: THE CRITICAL TEST - Verify routes are STILL SERVING after re-authentication |
| LOW | integration/acl_test.go | 2576 | // Step 1: Verify initial access state |
| LOW | integration/acl_test.go | 2609 | // Step 2: Apply tag change |
| LOW | integration/acl_test.go | 2627 | // Step 3: Verify final NetMap visibility first (fast signal that |
| LOW | integration/acl_test.go | 2655 | // Step 4: Verify final access state (this is the key test for #2389). |
| LOW | integration/acl_test.go | 2812 | // Step 1: Verify initial state - HTTP on port 80 should work with tag:webserver |
| LOW | integration/acl_test.go | 2818 | // Step 2: Change tag from webserver to sshonly |
| LOW | integration/acl_test.go | 2839 | // Step 3: Verify peer is still visible in NetMap (partial access, not full removal) |
| LOW | integration/acl_test.go | 2858 | // Step 4: Verify HTTP on port 80 now fails (tag:sshonly only allows port 22). |
| LOW | integration/acl_test.go | 3054 | // Step 1: Verify initial connectivity - all users can reach each other |
| LOW | integration/acl_test.go | 3066 | // Step 2: Get user3's node and user, then delete them |
| LOW | integration/acl_test.go | 3091 | // Step 3: Verify that user1 and user2 can still communicate (before triggering policy refresh) |
| LOW | integration/acl_test.go | 3102 | // Step 4: Create a NEW user - this triggers [State.updatePolicyManagerUsers] which |
| LOW | integration/acl_test.go | 3114 | // Step 5: THIS IS THE CRITICAL TEST - verify connectivity STILL works after |
| LOW | integration/acl_test.go | 3231 | // Step 1: Verify initial connectivity - user1 and user3 can ping each other |
| LOW | integration/acl_test.go | 3245 | // Step 2: Delete user2's node and user (like reporter deleting "deleteable") |
| LOW | integration/acl_test.go | 3263 | // Step 3: Verify connectivity still works after user2 deletion |
| LOW | integration/acl_test.go | 3278 | // Step 4: Create a NEW user - this triggers [State.updatePolicyManagerUsers] |
| LOW | integration/acl_test.go | 3285 | // Step 5: THE CRITICAL TEST - verify connectivity STILL works |
| LOW | integration/acl_test.go | 3395 | // Step 1: Verify initial connectivity with VALID policy |
| LOW | integration/acl_test.go | 3409 | // Step 2: DYNAMICALLY update policy to add unknown user |
| LOW | integration/acl_test.go | 3439 | // Step 3: THE CRITICAL TEST - verify connectivity STILL works |
| LOW | integration/acl_test.go | 3543 | // Step 1: Verify initial connectivity WITH unknown user in policy |
| LOW | integration/acl_test.go | 3558 | // Step 2: Update policy to REMOVE the unknown user |
| LOW | integration/acl_test.go | 3587 | // Step 3: Verify connectivity after removing unknown user |
| LOW | integration/tags_test.go | 526 | // Step 2: Admin assigns different tags via headscale CLI |
| LOW | integration/tags_test.go | 548 | // Step 3: Force reauthentication |
| LOW | integration/tags_test.go | 650 | // Step 2: Admin assigns multiple tags via headscale CLI |
| LOW | integration/tags_test.go | 671 | // Step 3: Attempt to reduce tags via CLI |
| LOW | integration/tags_test.go | 1012 | // Step 2: Admin assigns tags |
| LOW | integration/tags_test.go | 1033 | // Step 3: Run tailscale up with --reset |
| LOW | integration/tags_test.go | 1131 | // Step 2: Admin assigns tags |
| LOW | integration/tags_test.go | 1152 | // Step 3: Run tailscale up with empty --advertise-tags |
| LOW | integration/tags_test.go | 1250 | // Step 2: Admin assigns multiple tags |
| LOW | integration/tags_test.go | 1271 | // Step 3: Attempt to reduce tags via CLI |
| LOW | integration/tags_test.go | 1549 | // Step 1: Create and register with one tag |
| LOW | integration/tags_test.go | 1579 | // Step 2: Try to add second tag via CLI |
| LOW | integration/tags_test.go | 1640 | // Step 1: Create and register with two tags |
| LOW | integration/tags_test.go | 1670 | // Step 2: Try to remove second tag via CLI |
| LOW | integration/tags_test.go | 1731 | // Step 1: Register with one tag |
| LOW | integration/tags_test.go | 1765 | // Step 2: Admin assigns different tag |
| LOW | integration/tags_test.go | 1785 | // Step 3: Try to change tags via CLI |
| LOW | integration/tags_test.go | 1848 | // Step 1: Register with one tag |
| LOW | integration/tags_test.go | 1881 | // Step 2: Admin assigns both tags |
| LOW | integration/tags_test.go | 1901 | // Step 3: Try to reduce tags via CLI |
| LOW | integration/tags_test.go | 2575 | // Step 2: Admin changes tag to tag:second (FIRST CALL - this is "tag:bar" in issue terms) |
| LOW | integration/tags_test.go | 2630 | // Step 3: Call SetNodeTags AGAIN with the SAME tag (SECOND CALL) |
| LOW | integration/tags_test.go | 2649 | // Step 4: Do another tag change to verify the pattern repeats |
| LOW | integration/tags_test.go | 2685 | // Step 5: Call SetNodeTags AGAIN with the SAME tag |
| LOW | integration/tags_test.go | 2835 | // Step 1: Create and register a node with tags |
| LOW | integration/tags_test.go | 2876 | // Step 2: Reauth with empty tags to remove all tags |
| LOW | integration/tags_test.go | 2921 | // Step 3: Verify tags are removed and ownership is returned to user |
| LOW | integration/tags_test.go | 3126 | // Step 1: Create a tags-only preauthkey WITHOUT a user. |
| 34 more matches not shown… | |||
| Severity | File | Line | Snippet |
|---|---|---|---|
| LOW | hscontrol/types/testcapture/testcapture_test.go | 424 | "full_policy": {"tagOwners": {"tag:ops": ["user@example.com"]}}, |
| LOW | hscontrol/types/testcapture/testcapture_test.go | 442 | want := `{"tagOwners":{"tag:ops":["user@example.com"]}}` |
| LOW | hscontrol/templates/auth_success.go | 25 | // e.g. "user@example.com". |
| LOW | hscontrol/policy/v2/policy_test.go | 828 | {Model: gorm.Model{ID: 1}, Name: "admin", Email: "admin@example.com"}, |
| LOW | hscontrol/policy/v2/policy_test.go | 867 | "group:admin": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/policy_test.go | 995 | {Model: gorm.Model{ID: 2}, Name: "admin", Email: "admin@example.com"}, |
| LOW | hscontrol/policy/v2/policy_test.go | 1077 | "group:admin": ["admin@example.com"], |
| LOW | hscontrol/policy/v2/policy_test.go | 1164 | {Model: gorm.Model{ID: 1}, Name: "admin", Email: "admin@example.com"}, |
| LOW | hscontrol/policy/v2/policy_test.go | 1194 | "group:admin": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/policy_test.go | 1232 | {Model: gorm.Model{ID: 1}, Name: "admin", Email: "admin@example.com"}, |
| LOW | hscontrol/policy/v2/policy_test.go | 1271 | "group:admin": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 42 | Group("group:example"): []Username{Username("user@example.com")}, |
| LOW | hscontrol/policy/v2/types_test.go | 48 | Tag("tag:test"): Owners{up("user@example.com")}, |
| LOW | hscontrol/policy/v2/types_test.go | 55 | new(Username("user@example.com")), |
| LOW | hscontrol/policy/v2/types_test.go | 74 | assert.Contains(t, jsonString, "user@example.com") |
| LOW | hscontrol/policy/v2/types_test.go | 661 | "group:admins": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 682 | Group("group:admins"): []Username{Username("admin@example.com")}, |
| LOW | hscontrol/policy/v2/types_test.go | 709 | "tag:web": ["admin@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 710 | "tag:server": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 733 | "group:admins": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 752 | Group("group:admins"): []Username{Username("admin@example.com")}, |
| LOW | hscontrol/policy/v2/types_test.go | 1031 | "group:test": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1032 | "INVALID_GROUP_FIELD": ["user@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 1043 | "group:test": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1055 | "group:test": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1079 | "tag:test": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1110 | "src": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1111 | "dst": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1143 | "10.0.0.0/8": ["user@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 1145 | "exitNode": ["user@example.com"], |
| LOW | hscontrol/policy/v2/types_test.go | 1198 | "user@example.com" |
| LOW | hscontrol/policy/v2/types_test.go | 1201 | "user@example.com" |
| LOW | hscontrol/policy/v2/types_test.go | 2175 | "tag:client": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 2197 | "tag:client": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 2217 | "tag:client": ["admin@example.com"] |
| LOW | hscontrol/policy/v2/types_test.go | 2237 | "tag:client": ["admin@example.com"] |
| Severity | File | Line | Snippet |
|---|---|---|---|
| MEDIUM | integration/route_test.go | 683 | // Get the expected router IP - use a more robust approach to handle temporary disconnections |
| MEDIUM | integration/dockertestutil/config.go | 70 | // This could be improved with more robust detection if needed |
| Severity | File | Line | Snippet |
|---|---|---|---|
| LOW | integration/run.sh | 59 | # Check if both arguments are provided |
| LOW | .github/workflows/needs-more-info-timer.yml | 81 | # Check if 3 days have passed |