UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

72 lines (71 loc) 3.65 kB
/** * Principal resolution for connections. * * This module is the one place the runtime bridges session-layer * vocabulary (`"service" | "user" | "runtime" | "unknown"`) to the * connection-layer vocabulary (`"app" | "user"`) that connection * authors see. Every runtime call site that needs a * {@link ConnectionPrincipal} routes through * {@link resolveConnectionPrincipal}, and every cache lookup keyed * by principal routes through {@link principalKey}. */ import { type AlsContext } from "#context/container.js"; import { type SessionAuthContext } from "#context/keys.js"; import type { AuthorizationDefinition, ConnectionPrincipal } from "#shared/connection-types.js"; /** * Stable string key identifying one principal within a connection's * per-principal token cache. * * - `{ type: "app" }` → `"app"`. Shared across all sessions. * - `{ type: "user", issuer, id }` → `["user", issuer, id]` JSON. * - `{ type: "user", id }` → `["user", null, id]` JSON. This is the * native Vercel Connect user projection. * * JSON tuple encoding preserves the boundaries between issuer and id, so * user-provided separators and percent sequences cannot alias cache entries. */ export declare function principalKey(principal: ConnectionPrincipal): string; /** * Resolves the {@link ConnectionPrincipal} for one connection. * * Single entry point for principal resolution — every runtime * call site that needs a {@link ConnectionPrincipal} (wrapped tool * execution, `startAuthorization` step, `mcp-client` header * resolution) routes through here so the decision tree lives in * exactly one place. * * Resolution order: * * 1. For `authorization.principalType === "app"`, return * `{ type: "app" }` regardless of the session. App-scoped * connections share one credential across all callers and can * be resolved with or without an active context. * 2. For `authorization.principalType === "user"`, project the * current caller's {@link SessionAuthContext} (read directly from * the durable {@link AuthKey} seed) into a user principal. A * missing context, an unauthenticated caller, or a non-`"user"` * current principal all fail fast with * `reason: "principal_required"` — no amount of retrying will * recover a misconfigured route, so the runtime does not treat * it as retryable. * * {@link AuthKey} is used instead of the derived `SessionKey` * so resolution works in both `runStep` scopes (where * `sessionProvider` has populated `SessionKey`) and durable * `"use step"` boundaries where only the seed keys survive * context serialization. The two are equivalent inside a step * because `sessionProvider` projects `AuthKey` into * `session.auth.current`. * * `ctx` defaults to {@link contextStorage.getStore}. Pass it * explicitly when the caller already has a context handle (for * example inside a durable step that deserialized its own * {@link AlsContext}) to avoid a redundant ALS lookup. * * The caller is responsible for passing a matching * {@link AuthorizationDefinition}. This helper does not validate * the definition shape beyond reading `principalType`. */ export declare function resolveConnectionPrincipal(connectionName: string, authorization: AuthorizationDefinition, ctx?: AlsContext | undefined): ConnectionPrincipal; /** Resolves a connection principal from an explicitly bound session identity. */ export declare function resolveConnectionPrincipalFromAuth(connectionName: string, authorization: AuthorizationDefinition, current: SessionAuthContext | null | undefined, ctx?: AlsContext): ConnectionPrincipal;