/**
 * The request-time gate: resolve who is calling, then decide whether the
 * {@link routePolicy} for their request permits it.
 *
 * Every dashboard request passes through here before reaching a handler, so
 * this file and {@link import('./dashboard-policy')} together are the complete
 * authorization story for the HTTP API.
 */
import type { AuthenticationStore, AuthSession } from '../auth';
import type { ControlPlaneStore } from '../control-plane';
import type { DashboardUser } from './dashboard-auth';
/**
 * A synthetic admin used only when auth is explicitly disabled for local
 * development. It is never persisted and never has a password.
 */
export declare const LOCAL_ADMIN: DashboardUser;
export interface GuardOptions {
    cwd: string;
    /** When false, every request is treated as {@link LOCAL_ADMIN}. */
    enabled: boolean;
    secret: string;
    authentication?: AuthenticationStore;
    authorization: {
        store: ControlPlaneStore;
        organizationId: string;
        projectId: string;
        defaultEnvironment: string;
    };
}
export interface GuardDecision {
    ok: boolean;
    status?: number;
    error?: string;
    /** True when the caller has no valid session at all (vs. lacking a grant). */
    unauthenticated?: boolean;
}
export interface DashboardGuard {
    enabled: boolean;
    /** The user for this request, or null when unauthenticated. */
    resolveUser: (req: Request) => DashboardUser | null;
    /** Durable v2 session metadata, when this request did not use a legacy cookie. */
    resolveSession: (req: Request) => AuthSession | null;
    /** Whether `user` may perform `req`. `site` is required for site-scoped routes. */
    check: (req: Request, pathname: string, user: DashboardUser | null, site?: string) => GuardDecision;
}
export declare function createDashboardGuard(options: GuardOptions): DashboardGuard;
export declare function dashboardMembershipVersions(store: ControlPlaneStore, organizationId: string, user: DashboardUser): Record<string, number>;
/**
 * Read the site name a site-scoped route acts on, without consuming the body
 * the handler will read (the request is cloned).
 */
export declare function siteFromRequest(req: Request, pathname: string): Promise<string | undefined>;
