{"slug":"route-filtering-with-via","title":"Route filtering with Via","tags":["tailscale","access-control","routing"],"agent_summary":"Last validated: Jan 5, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Route filtering with Via\r\n\r\nLast validated: Jan 5, 2026\r\n\r\nVia introduces routing awareness to [grants](https://tailscale.com/docs/features/access-control/grants) by letting you include a `via` field to specify _how_ Tailscale can route the destination (`dst`) from the source (`src`).\r\n\r\nYou can use the [`via` syntax](https://tailscale.com/docs/features/access-control/grants/grants-via#syntax) to define the [exit nodes](https://tailscale.com/docs/features/exit-nodes), [subnet routers](https://tailscale.com/docs/features/subnet-routers), or [app connectors](https://tailscale.com/docs/features/app-connectors) a source can access when they use a specific destination. For example, you can create a grant that forces traffic through a specific exit node when it goes from the engineering team group to the GitHub app connector.\r\n\r\nUsing the `via` field in grants lets you do things like:\r\n\r\n- Route traffic to an enterprise application through a specific exit node.\r\n- Route traffic from devices through different exit nodes based on whether they meet device posture criteria.\r\n- Route traffic from specific users through a subnet router.\r\n\r\nYou can omit the `via` field (or set it to `[]` or `null`) when you create a grant to allow any group of devices to access a resource (through any exit node, subnet router, or app connector).\r\n\r\n## [Limitations](https://tailscale.com/docs/features/access-control/grants/grants-via\\#limitations)\r\n\r\n- You can only use [tags](https://tailscale.com/docs/features/tags) within the `via` field.\r\n- For [failover and regional routing reasons](https://tailscale.com/docs/how-to/set-up-high-availability), you can only use accessible routers as `via` candidates. The routers accessible to users depends on applicable [access policies](https://tailscale.com/docs/features/access-control/acls).\r\n\r\n## [Syntax](https://tailscale.com/docs/features/access-control/grants/grants-via\\#syntax)\r\n\r\nVia is an extension of the grant syntax. It adds a single field, `via`, that you can use to specify how the source routes to the destination. The following example shows how to use the `via` field.\r\n\r\n```json\r\n\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"<source>\"],\\\r\n    \"dst\": [\"<destination>\"],\\\r\n    \"via\": [\"tag:<tag-name>\"],\\\r\n    \"ip\": [\"*\"]\\\r\n  },\\\r\n]\r\n```\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\nThis example ensures traffic from `<source>` to `<destination>` goes through a device with the tag `<tag-name>`.\r\n\r\n## [Examples](https://tailscale.com/docs/features/access-control/grants/grants-via\\#examples)\r\n\r\nThe following examples illustrate using the `via` field in grants for common use cases.\r\n\r\n- [Route traffic based on device posture rules](https://tailscale.com/docs/features/access-control/grants/grants-via#route-traffic-based-on-device-posture-rules).\r\n- [Route users through exit nodes based on location](https://tailscale.com/docs/features/access-control/grants/grants-via#route-users-through-exit-nodes-based-on-location).\r\n- [Route users through app connectors](https://tailscale.com/docs/features/access-control/grants/grants-via#route-users-through-app-connectors).\r\n\r\n### [Route traffic based on device posture rules](https://tailscale.com/docs/features/access-control/grants/grants-via\\#route-traffic-based-on-device-posture-rules)\r\n\r\nYou can use the `via` field to segment access to resources through different [routers based on device posture](https://tailscale.com/docs/solutions/protect-postgresql-unencrypted-macbooks) management rules.\r\n\r\nThe following example demonstrates a scenario in which the engineering team group can access a `192.0.2.0/24` using any available router if they comply with the `latestMac` posture (which ensures they are running the latest stable version of the Tailscale client for macOS). Anyone else (`autogroup:member`) can access `192.0.2.0/24` using the designated office router (`tag:office-router`).\r\n\r\n```json\r\n\"postures\": {\r\n  \"posture:latestMac\": [\\\r\n    \"node:os == 'macos'\",\\\r\n    \"node:osVersion == '13.4.0'\",\\\r\n    \"node:tsReleaseTrack == 'stable'\",\\\r\n  ]\r\n},\r\n\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"group:eng\"],\\\r\n    \"srcPosture\": [\"posture:latestMac\"],\\\r\n    \"dst\": [\"192.0.2.0/24\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"autogroup:member\"],\\\r\n    \"dst\": [\"192.0.2.0/24\"],\\\r\n    \"via\": [\"tag:office-router\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n]\r\n```\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\n### [Route users through exit nodes based on location](https://tailscale.com/docs/features/access-control/grants/grants-via\\#route-users-through-exit-nodes-based-on-location)\r\n\r\nYou can use the `via` field to segment different [exit nodes](https://tailscale.com/docs/features/exit-nodes) to different users.\r\n\r\nThe following example demonstrates a scenario where users can access internet resources through an exit node based on the user's home office location.\r\n\r\nUsers in the Toronto (`group:tor`) and Seattle (`group:sea`) offices can access internet resources using exit nodes near their home offices (or directly from their device when exit nodes are not selected). Users on the engineering team (`group:eng`) can access internet resources using any exit node in the tailnet (or directly from their device when exit nodes are not selected).\r\n\r\n```json\r\n\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"group:tor\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"via\": [\"tag:exit-node-tor\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"group:sea\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"via\": [\"tag:exit-node-sea\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"group:eng\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n]\r\n```\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\n### [Route users through app connectors](https://tailscale.com/docs/features/access-control/grants/grants-via\\#route-users-through-app-connectors)\r\n\r\nYou can use the `via` field to segment different [app connectors](https://tailscale.com/docs/features/app-connectors) to different users.\r\n\r\nThe following example demonstrates a scenario in which users in the group `group:github-users` can access GitHub through an app connector tagged `tag:github-appconnector` while users in the group `group:salesforce-users` can access Salesforce through an app connector tagged `tag:salesforce-appconnector`.\r\n\r\n```json\r\n\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"group:github-users\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"ip\":  [\"*\"],\\\r\n    \"via\": [\"tag:github-appconnector\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"group:salesforce-users\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"ip\":  [\"*\"],\\\r\n    \"via\": [\"tag:salesforce-appconnector\"],\\\r\n  }\\\r\n]\r\n```\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\n![Project Logo](https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed)\r\n\r\nAsk AI\r\n\r\nreCAPTCHA\r\n\r\nRecaptcha requires verification.\r\n\r\nprotected by **reCAPTCHA**\r\n","html":"<h1>Route filtering with Via</h1>\n<p>Last validated: Jan 5, 2026</p>\n<p>Via introduces routing awareness to <a href=\"https://tailscale.com/docs/features/access-control/grants\">grants</a> by letting you include a <code>via</code> field to specify <em>how</em> Tailscale can route the destination (<code>dst</code>) from the source (<code>src</code>).</p>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#syntax\"><code>via</code> syntax</a> to define the <a href=\"https://tailscale.com/docs/features/exit-nodes\">exit nodes</a>, <a href=\"https://tailscale.com/docs/features/subnet-routers\">subnet routers</a>, or <a href=\"https://tailscale.com/docs/features/app-connectors\">app connectors</a> a source can access when they use a specific destination. For example, you can create a grant that forces traffic through a specific exit node when it goes from the engineering team group to the GitHub app connector.</p>\n<p>Using the <code>via</code> field in grants lets you do things like:</p>\n<ul>\n<li>Route traffic to an enterprise application through a specific exit node.</li>\n<li>Route traffic from devices through different exit nodes based on whether they meet device posture criteria.</li>\n<li>Route traffic from specific users through a subnet router.</li>\n</ul>\n<p>You can omit the <code>via</code> field (or set it to <code>[]</code> or <code>null</code>) when you create a grant to allow any group of devices to access a resource (through any exit node, subnet router, or app connector).</p>\n<h2><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#limitations\">Limitations</a></h2>\n<ul>\n<li>You can only use <a href=\"https://tailscale.com/docs/features/tags\">tags</a> within the <code>via</code> field.</li>\n<li>For <a href=\"https://tailscale.com/docs/how-to/set-up-high-availability\">failover and regional routing reasons</a>, you can only use accessible routers as <code>via</code> candidates. The routers accessible to users depends on applicable <a href=\"https://tailscale.com/docs/features/access-control/acls\">access policies</a>.</li>\n</ul>\n<h2><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#syntax\">Syntax</a></h2>\n<p>Via is an extension of the grant syntax. It adds a single field, <code>via</code>, that you can use to specify how the source routes to the destination. The following example shows how to use the <code>via</code> field.</p>\n<pre><code class=\"language-json\">\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"&#x3C;source>\"],\\\r\n    \"dst\": [\"&#x3C;destination>\"],\\\r\n    \"via\": [\"tag:&#x3C;tag-name>\"],\\\r\n    \"ip\": [\"*\"]\\\r\n  },\\\r\n]\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<p>This example ensures traffic from <code>&#x3C;source></code> to <code>&#x3C;destination></code> goes through a device with the tag <code>&#x3C;tag-name></code>.</p>\n<h2><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#examples\">Examples</a></h2>\n<p>The following examples illustrate using the <code>via</code> field in grants for common use cases.</p>\n<ul>\n<li><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#route-traffic-based-on-device-posture-rules\">Route traffic based on device posture rules</a>.</li>\n<li><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#route-users-through-exit-nodes-based-on-location\">Route users through exit nodes based on location</a>.</li>\n<li><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#route-users-through-app-connectors\">Route users through app connectors</a>.</li>\n</ul>\n<h3><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#route-traffic-based-on-device-posture-rules\">Route traffic based on device posture rules</a></h3>\n<p>You can use the <code>via</code> field to segment access to resources through different <a href=\"https://tailscale.com/docs/solutions/protect-postgresql-unencrypted-macbooks\">routers based on device posture</a> management rules.</p>\n<p>The following example demonstrates a scenario in which the engineering team group can access a <code>192.0.2.0/24</code> using any available router if they comply with the <code>latestMac</code> posture (which ensures they are running the latest stable version of the Tailscale client for macOS). Anyone else (<code>autogroup:member</code>) can access <code>192.0.2.0/24</code> using the designated office router (<code>tag:office-router</code>).</p>\n<pre><code class=\"language-json\">\"postures\": {\r\n  \"posture:latestMac\": [\\\r\n    \"node:os == 'macos'\",\\\r\n    \"node:osVersion == '13.4.0'\",\\\r\n    \"node:tsReleaseTrack == 'stable'\",\\\r\n  ]\r\n},\r\n\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"group:eng\"],\\\r\n    \"srcPosture\": [\"posture:latestMac\"],\\\r\n    \"dst\": [\"192.0.2.0/24\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"autogroup:member\"],\\\r\n    \"dst\": [\"192.0.2.0/24\"],\\\r\n    \"via\": [\"tag:office-router\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n]\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<h3><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#route-users-through-exit-nodes-based-on-location\">Route users through exit nodes based on location</a></h3>\n<p>You can use the <code>via</code> field to segment different <a href=\"https://tailscale.com/docs/features/exit-nodes\">exit nodes</a> to different users.</p>\n<p>The following example demonstrates a scenario where users can access internet resources through an exit node based on the user's home office location.</p>\n<p>Users in the Toronto (<code>group:tor</code>) and Seattle (<code>group:sea</code>) offices can access internet resources using exit nodes near their home offices (or directly from their device when exit nodes are not selected). Users on the engineering team (<code>group:eng</code>) can access internet resources using any exit node in the tailnet (or directly from their device when exit nodes are not selected).</p>\n<pre><code class=\"language-json\">\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"group:tor\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"via\": [\"tag:exit-node-tor\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"group:sea\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"via\": [\"tag:exit-node-sea\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"group:eng\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"ip\": [\"*\"],\\\r\n  },\\\r\n]\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<h3><a href=\"https://tailscale.com/docs/features/access-control/grants/grants-via#route-users-through-app-connectors\">Route users through app connectors</a></h3>\n<p>You can use the <code>via</code> field to segment different <a href=\"https://tailscale.com/docs/features/app-connectors\">app connectors</a> to different users.</p>\n<p>The following example demonstrates a scenario in which users in the group <code>group:github-users</code> can access GitHub through an app connector tagged <code>tag:github-appconnector</code> while users in the group <code>group:salesforce-users</code> can access Salesforce through an app connector tagged <code>tag:salesforce-appconnector</code>.</p>\n<pre><code class=\"language-json\">\"grants\": [\\\r\n  {\\\r\n    \"src\": [\"group:github-users\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"ip\":  [\"*\"],\\\r\n    \"via\": [\"tag:github-appconnector\"],\\\r\n  },\\\r\n  {\\\r\n    \"src\": [\"group:salesforce-users\"],\\\r\n    \"dst\": [\"autogroup:internet\"],\\\r\n    \"ip\":  [\"*\"],\\\r\n    \"via\": [\"tag:salesforce-appconnector\"],\\\r\n  }\\\r\n]\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<p><img src=\"https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed\" alt=\"Project Logo\"></p>\n<p>Ask AI</p>\n<p>reCAPTCHA</p>\n<p>Recaptcha requires verification.</p>\n<p>protected by <strong>reCAPTCHA</strong></p>\n"}