Express middleware for Tailscale authentication
npm install express-tailscale-authExpress middleware for Tailscale authentication and authorization. Automatically authenticate users based on their Tailscale connection and optionally enforce fine-grained permissions using Tailscale Access control capabilities.
If you're already using Tailscale to secure your infrastructure, this middleware lets you leverage that same identity system for your web applications. No need for separate login systems, password management, or external authentication providers.
Perfect for:
- Internal tools and dashboards - Automatically authenticated for your team
- Services behind Tailscale Funnel/Serve - Secure public endpoints with zero-config auth
- Hybrid applications - Keep marketing pages public while protecting /admin or /api routes
Your users get seamless access to applications just by being connected to your Tailscale network, while you get enterprise-grade identity and access management without the complexity. No separate login or auth keys needed.
Or thats the idea anyway.
- 🔐 Zero-config authentication - Users are automatically authenticated if they're connected via Tailscale
- 🎯 Capability-based authorization - Fine-grained permissions using Tailscale Access control grants
- 🔍 User information - Access to Tailscale user profile in your route handlers
``bash`
npm install express-tailscale-auth
`typescript
import express from 'express'
import { createTailscaleAuthMw } from 'express-tailscale-auth'
const app = express()
app.set("trust proxy", ["loopback", "uniquelocal", "linklocal"]);
// Create the authentication middleware
const tailscaleAuth = createTailscaleAuthMw()
// Apply to all routes
app.use(tailscaleAuth)
// Or apply to specific routes
app.get('/protected', tailscaleAuth, (req, res) => {
// User information is available in req.tailscaleUser
res.json({
message: Hello ${req.tailscaleUser?.displayName}!,
user: req.tailscaleUser
})
})
app.listen(3000, () => {
console.log('Server running on port 3000')
})
`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| socketPath | string | undefined | Path to tailscaled unix socket. Auto-detected if not specified. |useSocketOnly
| | boolean | false | Whether to only use unix socket for communication. |debug
| | boolean | false | Enable debug logging to console. |capabilitiesNamespace
| | string | undefined | Namespace for capability-based authorization. |
If you need this middleware your app most likely runs behind a reverse proxy (e.g. tailscale funnel / serve).
You need to configure trust proxy settings:
`typescript`
// For most reverse proxy setups
app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal'])
see more https://expressjs.com/en/guide/behind-proxies.html
For fine-grained access control, you can use Tailscale Access control capabilities. First, configure your Tailscale Access control with grants:
Add grants to your Tailscale Access control policy:
`json`
{
"grants": [
{
"src": ["user@example.com"],
"dst": ["*"],
"app": {
"myapp.com/capabilities": [
{
"routes": [
{"route": "/api/admin/**", "methods": ["GET", "POST"]},
{"route": "/api/users", "methods": ["GET"]},
{"route": "/public/*", "methods": [""]}
]
}
]
}
}
]
}
Set the capabilities namespace in your middleware:
`typescript`
const tailscaleAuth = createTailscaleAuthMw({
capabilitiesNamespace: 'myapp.com/capabilities'
})
The middleware uses glob patterns for route matching:
- ** matches any number of path segments*
- matches a single path segment/api/users` match exactly
- Exact paths like