Skip to main content
The dashboard includes built-in authentication to protect your analytics data. It supports two authentication modes: basic authentication and Tinybird token-based authentication.

Authentication Modes

The dashboard provides two ways to authenticate:

Basic Authentication

Username and password authentication with session management

Token Authentication

Direct authentication using Tinybird workspace tokens

Basic Authentication

The default authentication method uses username/password credentials managed through environment variables.

Configuration

Set up basic authentication by configuring these environment variables:
# Dashboard Basic Auth (server-only, defaults to admin/admin if not set)
DASHBOARD_USERNAME=admin
DASHBOARD_PASSWORD=changeme

# Optional: Set to "true" to disable auth during development
DISABLE_AUTH=false
Security Alert: The default credentials are admin/admin. Always change these in production!
DASHBOARD_USERNAME
string
default:"admin"
The username for dashboard access. Users will enter this when signing in.
DASHBOARD_PASSWORD
string
default:"admin"
The password for dashboard access. Use a strong, unique password in production.
DISABLE_AUTH
boolean
default:"false"
Set to true to disable authentication during local development.
Never set DISABLE_AUTH=true in production environments!

How It Works

When a user visits the dashboard:
1

Authentication Check

The middleware checks for a valid session cookie. If missing, an authentication dialog appears.
2

User Sign In

The user enters their username and password in the sign-in form.
3

Session Creation

On successful authentication, a session cookie (dashboard_session) is created.
4

Protected Access

All subsequent requests include the session cookie, granting access to the dashboard and API routes.

Authentication Middleware

The dashboard uses Next.js middleware to protect routes:
import { NextRequest, NextResponse } from 'next/server'

const SESSION_COOKIE_NAME = 'dashboard_session'

export function middleware(request: NextRequest) {
  // Skip auth if disabled (for development)
  if (process.env.DISABLE_AUTH === 'true') {
    return NextResponse.next()
  }

  const { pathname } = request.nextUrl

  // Allow auth API routes
  if (pathname.startsWith('/api/auth')) {
    return NextResponse.next()
  }

  // Check for session cookie
  const sessionCookie = request.cookies.get(SESSION_COOKIE_NAME)

  if (!sessionCookie?.value) {
    // For API routes, return 401
    if (pathname.startsWith('/api')) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }
    // For pages, show auth dialog
    const response = NextResponse.next()
    response.headers.set('x-auth-status', 'unauthenticated')
    return response
  }

  return NextResponse.next()
}
The middleware protects all routes except static files, Next.js internals, and the authentication API itself.

Sign Out

Users can sign out using the workspace menu in the header:
  1. Click the workspace menu in the top-right corner
  2. Select “Sign Out”
  3. The session cookie is cleared and the user is redirected to the login screen

Token Authentication

For advanced use cases, users can authenticate directly with a Tinybird workspace token.

Using Token Authentication

1

Open Auth Dialog

Click the “Tinybird Token” tab in the authentication dialog.
2

Enter Token

Paste your Tinybird workspace admin token.
Get your token from Tinybird Console → Tokens
3

Select Host (if needed)

If the token doesn’t include host information, select your Tinybird region:
  • EU Shared: https://api.tinybird.co
  • US East: https://api.us-east.tinybird.co
  • AWS regions: https://api.{region}.aws.tinybird.co
  • Local development: http://localhost:7181
4

Enter Tenant ID (optional)

For multi-tenant deployments, specify the tenant ID to filter data.
5

View Dashboard

Click “View dashboard” to create a scoped JWT and access the dashboard.

Token Scoping

When using token authentication, the dashboard automatically creates a scoped JWT with read-only permissions:
export async function createJwt(
  token: string,
  tenant_id: string
): Promise<string> {
  const expiration_time = Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60
  const workspace_id = extractWorkspaceIdFromToken(token)
  
  const resources = [
    'domains',
    'top_sources',
    'top_devices',
    'kpis',
    'top_locations',
    'top_browsers',
    'top_pages',
    'trend',
    'domain',
    'current_visitors',
    'web_vitals_current',
    'web_vitals_routes',
    'web_vitals_distribution',
    'web_vitals_events',
    'web_vitals_timeseries',
    'analytics_hits',
    'actions',
  ]

  const payload = {
    workspace_id: workspace_id,
    name: 'frontend_jwt',
    exp: expiration_time,
    scopes: [
      ...resources.map(resource => ({
        type: 'PIPES:READ',
        resource,
        fixed_params: tenant_id ? { tenant_id } : {},
      })),
    ],
  }
  
  const key = new TextEncoder().encode(token)
  return await new SignJWT(payload)
    .setProtectedHeader({ alg: 'HS256' })
    .setExpirationTime(expiration_time)
    .sign(key)
}
The scoped JWT has read-only access to analytics pipes and expires after 30 days.

URL Parameters

When using token authentication, credentials are passed via URL parameters:
  • ?token=<scoped-jwt> - The generated JWT token
  • ?host=<tinybird-host> - The Tinybird API host
  • ?tenant_id=<tenant> (optional) - The tenant ID for filtering
  • ?workspace=<name> (optional) - The workspace name for display
URLs with tokens should be kept private and not shared publicly.

Public Mode

For embedded dashboards or public analytics, you can bypass authentication by passing tokens in HTTP headers:
curl https://your-dashboard.vercel.app/api/endpoints/kpis \
  -H "X-Tinybird-Token: your-token" \
  -H "X-Tinybird-Host: https://api.tinybird.co"
The middleware allows requests with these headers to bypass authentication:
// Check for token auth from headers (public mode)
const headerToken = request.headers.get('X-Tinybird-Token')
const headerHost = request.headers.get('X-Tinybird-Host')
if (headerToken && headerHost) {
  return NextResponse.next()
}

Multi-Tenant Authentication

For multi-tenant deployments where multiple customers share the same dashboard:
1

Configure Tenant ID

Set the TENANT_ID environment variable or pass it during token authentication.
2

Data Filtering

All queries automatically filter by tenant_id = 'your-tenant-id'.
3

Scoped Tokens

JWT tokens include fixed parameters to enforce tenant isolation:
fixed_params: tenant_id ? { tenant_id } : {}
Multi-tenant mode requires your Tinybird data project to include a tenant_id column in all analytics tables.

Development Mode

During local development, you can disable authentication to speed up iteration:
DISABLE_AUTH=true
1

Start Development Server

pnpm dev
2

Access Dashboard

Open http://localhost:3000 - no authentication required.
Remember to set DISABLE_AUTH=false before deploying to production!

Security Best Practices

Choose a strong, unique password for DASHBOARD_PASSWORD. Consider using a password manager to generate and store it.
Change your dashboard password and Tinybird tokens periodically, especially if team members leave.
Use tokens with the minimum required permissions. Read-only tokens are sufficient for the dashboard.
Always use HTTPS in production to encrypt authentication credentials in transit.
Review Vercel logs and Tinybird access logs to detect unauthorized access attempts.
Never commit .env files to version control. Use .env.example for templates only.

Troubleshooting

  1. Clear browser cookies and try again
  2. Verify DASHBOARD_USERNAME and DASHBOARD_PASSWORD are set correctly
  3. Check browser console for errors
  4. Ensure session cookies are not blocked
  1. Verify the token is valid in Tinybird Console
  2. Check the token has read permissions for all pipes
  3. Confirm the host URL matches your workspace region
  4. Try creating a new admin token
Session cookies expire after a period of inactivity. Simply sign in again to continue.

Next Steps

Deploy to Production

Learn how to deploy your dashboard with proper authentication

Customize the Dashboard

Adapt the UI to match your brand

Build docs developers (and LLMs) love