Use Case

Multi-tenant SaaS analytics with policy control by default

Resolve auth context once, enforce tenant filtering automatically, and keep role checks in query definitions where teams can review and version them.

Tenancy mode

Scoped automatically

Policy location

Inside query code

Scale target

2 to 2000+ tenants

Map auth once

Convert API keys or sessions into typed auth context with tenant and role metadata.

Inject tenant filters

Configure extraction once and let query execution scope data automatically.

Enforce roles inline

Require admin or tenant-specific roles directly in sensitive query definitions.

Request lifecycle

1

Request arrives with API key/session.

2

Auth strategy resolves tenant and roles.

3

Tenant scope is injected into query execution.

4

Role gates are enforced in definitions.

5

Typed responses return safe tenant data.

Tenant auth without glue code

Use API key auth and map tenant and admin identities directly into typed auth context.

import { createApiKeyStrategy, createAuthSystem } from '@hypequery/serve';const { useAuth, TypedAuth } = createAuthSystem({  defaultAuth: { authenticated: false },});type AppAuth = typeof TypedAuth & { tenantId?: 'acme' | 'globex' };export const authStrategy = createApiKeyStrategy<AppAuth>({  validate: (key) => {    if (key === 'acme-key') return { authenticated: true, tenantId: 'acme', roles: ['admin'] };    if (key === 'globex-key') return { authenticated: true, tenantId: 'globex', roles: ['viewer'] };    return { authenticated: false };  },});

Automatic tenant scoping

Set tenant extraction once and let HypeQuery inject filters automatically.

const { define, query } = initServe({  tenant: {    extract: (ctx) => ctx.auth?.tenantId,    column: 'tenant_id',    required: false,  },  context: async () => ({ db }),});

Role-based access for sensitive queries

Apply access control directly in query definitions.

revenueByPlan: query  .describe('MRR by plan (admin only)')  .requireRole('admin')  .output(z.array(z.object({    plan: z.string(),    total_mrr: z.number(),  })))  .query(({ ctx }) =>    ctx.db      .table('analytics.subscription_mrr')      .innerJoin(        'analytics.users',        'analytics.users.user_id',        'analytics.subscription_mrr.user_id',      )      .sum('mrr', 'total_mrr')      .groupBy(['plan'])      .execute()  )

Governance outcome

Clear tenant boundaries with a single shared query layer

  • Clear admin versus tenant capabilities
  • Reusable auth and policy primitives
  • Faster onboarding for new product teams