/** * Auth Hono middleware and handlers for @agentuity/auth. * * Provides session and API key authentication middleware for Hono applications. * * @module agentuity/server */ import type { Context, MiddlewareHandler } from 'hono'; import type { AuthBase } from './config.ts'; import type { AuthUser, AuthSession, AuthOrgContext, AuthInterface } from './types.ts'; /** * Configuration for OpenTelemetry span attributes. * All attributes are included by default. Set to `false` to opt-out of specific PII. */ export interface OtelSpansConfig { /** * Include user email in spans (`auth.user.email`). * @default true */ email?: boolean; /** * Include organization name in spans (`auth.org.name`). * @default true */ orgName?: boolean; } export interface AuthMiddlewareOptions { /** * If true, don't return 401 on missing auth - just continue without auth context. * Useful for routes that work for both authenticated and anonymous users. */ optional?: boolean; /** * Configure which attributes are included in OpenTelemetry spans. * All PII attributes are included by default. Use this to opt-out of specific fields. * * @example Disable email in spans * ```typescript * createSessionMiddleware(auth, { otelSpans: { email: false } }) * ``` */ otelSpans?: OtelSpansConfig; /** * Require that the authenticated user has one of the given org roles. * If the user is authenticated but lacks the required role, a 403 is returned. * Only applies when authentication succeeds (ignored for optional + anonymous). * * @example Require admin or owner role * ```typescript * createSessionMiddleware(auth, { hasOrgRole: ['admin', 'owner'] }) * ``` */ hasOrgRole?: string | string[]; } export interface ApiKeyMiddlewareOptions { /** * If true, don't return 401 on missing/invalid API key - just continue without auth context. */ optional?: boolean; /** * Configure which attributes are included in OpenTelemetry spans. * All PII attributes are included by default. Use this to opt-out of specific fields. * * @example Disable email in spans * ```typescript * createApiKeyMiddleware(auth, { otelSpans: { email: false } }) * ``` */ otelSpans?: OtelSpansConfig; /** * Require that the API key has specific permissions. * If the API key lacks any required permission, a 403 is returned. * * @example Require project write permission * ```typescript * createApiKeyMiddleware(auth, { hasPermission: { project: 'write' } }) * ``` * * @example Require multiple permissions * ```typescript * createApiKeyMiddleware(auth, { * hasPermission: { project: ['read', 'write'], admin: '*' } * }) * ``` */ hasPermission?: Record; } /** * Hono context variables set by the middleware. */ export type AuthEnv = { Variables: { auth: AuthInterface; user: AuthUser | null; authSession: AuthSession | null; org: AuthOrgContext | null; }; }; /** * Create Hono middleware that validates sessions. * * Sets context variables (`user`, `session`, `org`, `auth`) for authenticated requests. * * OpenTelemetry spans are automatically enriched with auth attributes: * - `auth.user.id` - User ID (always included) * - `auth.user.email` - User email (included by default, opt-out via `otelSpans.email: false`) * - `auth.method` - 'session' or 'bearer' (always included) * - `auth.provider` - 'Auth' (always included) * - `auth.org.id` - Active organization ID (always included if set) * - `auth.org.name` - Organization name (included by default, opt-out via `otelSpans.orgName: false`) * * @example Basic usage * ```typescript * import { createSessionMiddleware } from '@agentuity/auth'; * import { auth } from './auth'; * * const app = new Hono(); * app.use('/api/*', createSessionMiddleware(auth)); * * app.get('/api/me', (c) => { * const user = c.var.user; * if (!user) return c.json({ error: 'Unauthorized' }, 401); * return c.json({ id: user.id }); * }); * ``` * * @example Using auth wrapper with org role check * ```typescript * app.get('/api/admin', createSessionMiddleware(auth, { hasOrgRole: ['admin', 'owner'] }), async (c) => { * const user = await c.var.auth.getUser(); * return c.json({ id: user.id, message: 'Welcome admin!' }); * }); * ``` */ export declare function createSessionMiddleware(auth: AuthBase, options?: AuthMiddlewareOptions): MiddlewareHandler; /** * Create Hono middleware that validates API keys. * * This middleware ONLY accepts API key authentication via: * - `x-agentuity-auth-api-key` header (preferred) * - `Authorization: ApiKey ` header * * It does NOT use sessions. For routes that accept both session and API key, * compose with createSessionMiddleware using `{ optional: true }`. * * @example API key only route with permission check * ```typescript * import { createApiKeyMiddleware } from '@agentuity/auth'; * * app.post('/webhooks/*', createApiKeyMiddleware(auth, { * hasPermission: { webhook: 'write' } * })); * * app.post('/webhooks/github', async (c) => { * // Permission already verified by middleware * return c.json({ success: true }); * }); * ``` * * @example Either session OR API key (compose with optional) * ```typescript * app.use('/api/*', createSessionMiddleware(auth, { optional: true })); * app.use('/api/*', createApiKeyMiddleware(auth, { optional: true })); * * app.get('/api/data', async (c) => { * // Works with session OR API key * if (!c.var.user) return c.json({ error: 'Unauthorized' }, 401); * return c.json({ data: '...' }); * }); * ``` */ export declare function createApiKeyMiddleware(auth: AuthBase, options?: ApiKeyMiddlewareOptions): MiddlewareHandler; /** * Configuration options for mounting auth routes. */ export interface MountAuthRoutesOptions { /** * Headers to forward from auth responses to the client. * Only headers in this list will be forwarded (case-insensitive). * `set-cookie` is always forwarded with append behavior regardless of this setting. * * @default ['set-cookie', 'content-type', 'location', 'cache-control', 'pragma', 'expires', 'vary', 'etag', 'last-modified'] */ allowList?: string[]; } /** * Mount auth routes with proper cookie handling and header filtering. * * This wrapper handles cookie merging between auth responses and other middleware. * It ensures both session cookies AND other cookies (like thread cookies) * are preserved while preventing unintended headers from leaking through. * * @example Basic usage * ```typescript * import { mountAuthRoutes } from '@agentuity/auth'; * import { auth } from './auth'; * * const api = createRouter(); * * // Mount all auth routes (sign-in, sign-up, sign-out, session, etc.) * api.on(['GET', 'POST'], '/api/auth/*', mountAuthRoutes(auth)); * ``` * * @example With custom header allowlist * ```typescript * api.on(['GET', 'POST'], '/api/auth/*', mountAuthRoutes(auth, { * allowList: ['set-cookie', 'content-type', 'location', 'x-custom-header'] * })); * ``` */ export declare function mountAuthRoutes(auth: AuthBase, options?: MountAuthRoutesOptions): (c: Context) => Promise; declare module 'hono' { interface ContextVariableMap { auth: AuthInterface; user: AuthUser | null; authSession: AuthSession | null; org: AuthOrgContext | null; } } //# sourceMappingURL=server.d.ts.map