UNPKG

express-tailscale-auth

Version:

Express middleware for Tailscale authentication

129 lines (92 loc) 4.07 kB
# express-tailscale-auth Express 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. ## Why use this? 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. ## Features - 🔐 **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 ## Installation ```bash npm install express-tailscale-auth ``` ## Basic Usage ```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') }) ``` ### Configuration Options | 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. | ## Reverse Proxy Configuration 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 ## Capability-Based Authorization For fine-grained access control, you can use Tailscale Access control capabilities. First, configure your Tailscale Access control with grants: ### 1. Configure Tailscale Access control 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": ["*"]} ] } ] } } ] } ``` ### 2. Configure Middleware Set the capabilities namespace in your middleware: ```typescript const tailscaleAuth = createTailscaleAuthMw({ capabilitiesNamespace: 'myapp.com/capabilities' }) ``` ### 3. Route Matching The middleware uses glob patterns for route matching: - `**` matches any number of path segments - `*` matches a single path segment - Exact paths like `/api/users` match exactly