For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Tailscale
Use Tailscale as a network boundary in front of agentgateway.
You can use Tailscale with agentgateway to place your MCP servers behind a private network boundary (your tailnet).
How it works
- You run agentgateway on a host that is connected to your tailnet.
- Clients connect to agentgateway over Tailscale (using the host’s tailnet IP or DNS name).
- Tailscale ACLs (and optionally agentgateway network authorization) restrict who can reach the gateway.
- agentgateway optionally applies application-layer policies (for example JWT validation) to authenticate/authorize requests.
Before you begin
- Install agentgateway.
- Install Tailscale on the agentgateway host and connect it to your tailnet.
- Have at least one other device on your tailnet to test from.
Step 1: Verify Tailscale connectivity
Check that Tailscale is connected. You should see your machine listed with a
100.x.x.xIP address.tailscale statusNote the host’s Tailscale IP address. You use this address to test access later.
tailscale ip -4
Step 2: Restrict access to your tailnet
Use Tailscale ACLs/tags to control which users/devices in your tailnet can reach the agentgateway host and port. This is the recommended place to enforce tailnet identity-based access, because it happens before traffic reaches agentgateway.
If you also want agentgateway to enforce a network allowlist, configure a network authorization policy to only accept connections from the Tailscale CGNAT range (100.64.0.0/10).
Create a config.yaml file:
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
frontendPolicies:
networkAuthorization:
rules:
- allow: 'cidr("100.64.0.0/10").containsIP(source.address)'
binds:
- port: 3000
listeners:
- name: default
protocol: HTTP
routes:
- name: mcp
backends:
- mcp:
targets:
- name: everything
stdio:
cmd: npx
args: ["@modelcontextprotocol/server-everything"]Step 3: Start agentgateway
agentgateway -f config.yamlExample output:
info proxy::gateway started bind bind="bind/3000"Step 4: Test connectivity
From a different device on your tailnet, send a request to the agentgateway host’s Tailscale IP:
curl -i http://<TAILSCALE_IP>:3000/mcpFrom a device that is not on your tailnet, verify that you cannot connect (either because of Tailscale ACLs or because the
networkAuthorizationpolicy rejects the connection).
Next steps: add application-layer auth (optional)
Tailscale protects network access, but it does not replace HTTP/MCP authentication and authorization. Depending on your use case, you might also want to configure:
- JWT authentication to validate OIDC access tokens.
- HTTP authorization for claim- and request-aware authorization rules.
- External authorization to delegate authz decisions to an external service (such as an IdP-aware proxy).
Troubleshooting
Can’t connect from a tailnet client: Confirm that your client is connected to the same tailnet and that you are connecting to the agentgateway host’s Tailscale IP/DNS name (not a LAN IP).
Connection is rejected after enabling networkAuthorization: Temporarily remove the frontendPolicies.networkAuthorization section to confirm whether the block is coming from Tailscale ACLs or from agentgateway. If you’re using subnet routers, proxies, or other routing, the downstream source.address might not fall into 100.64.0.0/10.