From 5ebf88d3b669193d885e8124b11a13d3218e318c Mon Sep 17 00:00:00 2001 From: tnsardesai <18272584+tnsardesai@users.noreply.github.com> Date: Mon, 14 Sep 2026 23:55:41 +0000 Subject: [PATCH] Add managed auth region controls --- README.md | 2 +- .../mcp/apps/generated/managed-auth-app.ts | 2 +- src/lib/mcp/apps/managed-auth-entry.tsx | 1 + src/lib/mcp/apps/managed-auth-types.ts | 1 + src/lib/mcp/tools/auth-connections.test.ts | 14 +++++++++-- src/lib/mcp/tools/auth-connections.ts | 12 +++++++++- src/lib/mcp/tools/auth-login-app.test.ts | 5 ++++ src/lib/mcp/tools/auth-login-app.ts | 7 ++++++ src/lib/mcp/tools/managed-auth-start.test.ts | 23 +++++++++++++++++++ src/lib/mcp/tools/managed-auth-state.ts | 14 +++++++++++ 10 files changed, 76 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4a578957..e15b2c6c 100644 --- a/README.md +++ b/README.md @@ -388,7 +388,7 @@ Returns: { success: true, result: "Example Domain" } Example: “Log me into my Hacker News account and update my profile to add a random emoji at the bottom.” The agent should discover `news.ycombinator.com`, open the App when needed, wait for authentication, then continue the profile edit without asking for credentials or a profile name in chat. -The secure App defaults `record_session` and `browser_telemetry.enabled` to `true`, recording replay video plus the operational telemetry categories (`control`, `connection`, `system`, and `captcha`) for managed-auth browser sessions. Callers can explicitly disable either setting. The programmatic `manage_auth_connections` create, update, and login actions pass browser telemetry through the API’s current nested `browser.telemetry` configuration while preserving defaults and inheritance when the MCP parameter is omitted. +The secure App defaults `record_session` and `browser_telemetry.enabled` to `true`, recording replay video plus the operational telemetry categories (`control`, `connection`, `system`, and `captcha`) for managed-auth browser sessions. Callers can explicitly disable either setting. Set `region` in `open_auth_login`, or `browser_region` in `manage_auth_connections`, to choose where a managed-auth browser runs. Create and update set the connection default; login and reauth overrides apply only to that flow. Omit the field on create to use `us-east`, or omit it on update and login to preserve or inherit the connection default. The programmatic `manage_auth_connections` create, update, and login actions pass browser telemetry through the API’s current nested `browser.telemetry` configuration while preserving defaults and inheritance when the MCP parameter is omitted. ### Set up browser profiles for authentication diff --git a/src/lib/mcp/apps/generated/managed-auth-app.ts b/src/lib/mcp/apps/generated/managed-auth-app.ts index 8bd18611..cccabe81 100644 --- a/src/lib/mcp/apps/generated/managed-auth-app.ts +++ b/src/lib/mcp/apps/generated/managed-auth-app.ts @@ -1,2 +1,2 @@ // Generated by scripts/build-managed-auth-app.mjs. Do not edit. -export const MANAGED_AUTH_APP_HTML = "\n\n\n\n\nKernel Managed Authentication\n\n\n
\n\n\n"; +export const MANAGED_AUTH_APP_HTML = "\n\n\n\n\nKernel Managed Authentication\n\n\n
\n\n\n"; diff --git a/src/lib/mcp/apps/managed-auth-entry.tsx b/src/lib/mcp/apps/managed-auth-entry.tsx index 414540df..49faa4b3 100644 --- a/src/lib/mcp/apps/managed-auth-entry.tsx +++ b/src/lib/mcp/apps/managed-auth-entry.tsx @@ -40,6 +40,7 @@ function sanitizeBeginArguments(input: JsonObject): JsonObject { "save_credentials", "record_session", "browser_telemetry", + "region", "proxy_id", "proxy_name", ]; diff --git a/src/lib/mcp/apps/managed-auth-types.ts b/src/lib/mcp/apps/managed-auth-types.ts index 47a10706..cb3f142f 100644 --- a/src/lib/mcp/apps/managed-auth-types.ts +++ b/src/lib/mcp/apps/managed-auth-types.ts @@ -14,6 +14,7 @@ export type SafeConnection = { | null; flow_type: "LOGIN" | "REAUTH" | null; flow_expires_at: string | null; + region?: "us-east" | "eu-west" | "ap-southeast"; error_code: string | null; }; diff --git a/src/lib/mcp/tools/auth-connections.test.ts b/src/lib/mcp/tools/auth-connections.test.ts index 58808d73..a1152c01 100644 --- a/src/lib/mcp/tools/auth-connections.test.ts +++ b/src/lib/mcp/tools/auth-connections.test.ts @@ -40,6 +40,8 @@ describe("manage_auth_connections programmatic surface", () => { expect(schema?.credential_auto.description).toContain("create, update"); expect(schema?.health_checks).toBeDefined(); expect(schema?.auto_reauth).toBeDefined(); + expect(schema?.browser_region.safeParse("eu-west").success).toBe(true); + expect(schema?.browser_region.safeParse("emea").success).toBe(false); expect(schema?.browser_stealth).toBeDefined(); expect(schema?.query).toBeDefined(); expect(schema?.timeline_type).toBeDefined(); @@ -131,7 +133,7 @@ describe("manage_auth_connections programmatic surface", () => { expect(selectedProject).toBeUndefined(); }); - test("forwards replay and browser telemetry settings on create and login", async () => { + test("forwards browser settings on create and login", async () => { const { handler } = captureHandler(); let createBody: unknown; let loginBody: unknown; @@ -176,6 +178,7 @@ describe("manage_auth_connections programmatic surface", () => { domain: "example.com", profile_name: "work", record_session: true, + browser_region: "eu-west", browser_telemetry: { enabled: true, browser: { network: { enabled: true } }, @@ -186,6 +189,7 @@ describe("manage_auth_connections programmatic surface", () => { expect(createBody).toMatchObject({ record_session: true, browser: { + region: "eu-west", telemetry: { enabled: true, browser: { network: { enabled: true } }, @@ -198,13 +202,17 @@ describe("manage_auth_connections programmatic surface", () => { action: "login", id: "conn_1", record_session: false, + browser_region: "ap-southeast", browser_telemetry: { enabled: false }, }, extra, ); expect(loginBody).toEqual({ record_session: false, - browser: { telemetry: { enabled: false } }, + browser: { + region: "ap-southeast", + telemetry: { enabled: false }, + }, }); } finally { kernelClientMock.factory = () => unusedKernelClient; @@ -238,6 +246,7 @@ describe("manage_auth_connections programmatic surface", () => { auto_reauth: false, save_credentials: false, record_session: true, + browser_region: "eu-west", browser_stealth: false, proxy_mode: "direct", browser_telemetry: { @@ -263,6 +272,7 @@ describe("manage_auth_connections programmatic surface", () => { save_credentials: false, record_session: true, browser: { + region: "eu-west", stealth: false, proxy: { mode: "direct" }, telemetry: { diff --git a/src/lib/mcp/tools/auth-connections.ts b/src/lib/mcp/tools/auth-connections.ts index 9230d7a6..543c4bab 100644 --- a/src/lib/mcp/tools/auth-connections.ts +++ b/src/lib/mcp/tools/auth-connections.ts @@ -143,6 +143,12 @@ export function registerAuthConnectionTools(server: McpServer) { "(create, update) Set the connection default for browser telemetry. (login) Override it for this login only. Use { enabled: true } for the default operational categories (control, connection, system, captcha); browser category settings can opt into console, network, page, interaction, screenshot, or platform capture, tune control CDP exclusions, and configure OTLP export. Omitted preserves the API default or inherited value.", ) .optional(), + browser_region: z + .enum(["us-east", "eu-west", "ap-southeast"]) + .describe( + "(create, update) Set the region for future managed-auth browser sessions. (login) Override the region for this login only. Defaults to us-east on create; omitted on update or login preserves or inherits the connection setting.", + ) + .optional(), browser_stealth: z .boolean() .describe( @@ -278,10 +284,14 @@ export function registerAuthConnectionTools(server: McpServer) { : undefined; const buildBrowser = () => { const proxy = buildProxy(); - return params.browser_stealth !== undefined || + return params.browser_region !== undefined || + params.browser_stealth !== undefined || params.browser_telemetry !== undefined || proxy ? { + ...(params.browser_region !== undefined && { + region: params.browser_region, + }), ...(params.browser_stealth !== undefined && { stealth: params.browser_stealth, }), diff --git a/src/lib/mcp/tools/auth-login-app.test.ts b/src/lib/mcp/tools/auth-login-app.test.ts index 51ce4acf..5cb72d76 100644 --- a/src/lib/mcp/tools/auth-login-app.test.ts +++ b/src/lib/mcp/tools/auth-login-app.test.ts @@ -152,6 +152,10 @@ describe("managed-auth MCP App registration", () => { expect(schema.safeParse({ ...base, proxy_id: "proxy_1" }).success).toBe( true, ); + expect(schema.safeParse({ ...base, region: "eu-west" }).success).toBe( + true, + ); + expect(schema.safeParse({ ...base, region: "emea" }).success).toBe(false); const defaults = schema.parse(base); expect(defaults.record_session).toBe(true); expect(defaults.browser_telemetry).toEqual({ enabled: true }); @@ -521,6 +525,7 @@ describe("managed-auth MCP App registration", () => { expect(MANAGED_AUTH_APP_HTML).toContain("profile_name"); expect(MANAGED_AUTH_APP_HTML).toContain("record_session"); expect(MANAGED_AUTH_APP_HTML).toContain("browser_telemetry"); + expect(MANAGED_AUTH_APP_HTML).toContain("region"); expect(MANAGED_AUTH_APP_HTML).toContain("manage_auth_connections"); expect(MANAGED_AUTH_APP_HTML).not.toContain("flow_wait_started_at"); expect(MANAGED_AUTH_APP_HTML).toContain( diff --git a/src/lib/mcp/tools/auth-login-app.ts b/src/lib/mcp/tools/auth-login-app.ts index 7d700ff1..7e50c8cf 100644 --- a/src/lib/mcp/tools/auth-login-app.ts +++ b/src/lib/mcp/tools/auth-login-app.ts @@ -71,6 +71,12 @@ const authLoginInputSchema = () => ({ "Browser telemetry for this managed-auth flow and the connection default for new connections. Defaults to { enabled: true }, which captures the operational categories (control, connection, system, captcha).", ) .default({ enabled: true }), + region: z + .enum(["us-east", "eu-west", "ap-southeast"]) + .describe( + "Region for the managed-auth browser session. Sets the connection default for a new login or overrides it for this reauth.", + ) + .optional(), proxy_id: z.string().min(1).optional(), proxy_name: z.string().min(1).optional(), }); @@ -104,6 +110,7 @@ function inputFromParams(params: AuthLoginParams): AuthLoginInput { }), record_session: params.record_session ?? true, browser_telemetry: params.browser_telemetry ?? { enabled: true }, + ...(params.region && { region: params.region }), ...(params.proxy_id && { proxy_id: params.proxy_id }), ...(params.proxy_name && { proxy_name: params.proxy_name }), }; diff --git a/src/lib/mcp/tools/managed-auth-start.test.ts b/src/lib/mcp/tools/managed-auth-start.test.ts index d7b59011..5ebe8b7d 100644 --- a/src/lib/mcp/tools/managed-auth-start.test.ts +++ b/src/lib/mcp/tools/managed-auth-start.test.ts @@ -1,5 +1,6 @@ import { describe, expect, test } from "bun:test"; import { beginAuthLogin } from "./managed-auth-state"; +import type { ManagedAuth } from "@onkernel/sdk/resources/auth/connections"; import { assertNoSecrets, connection, @@ -66,6 +67,28 @@ describe("managed-auth start/resume state machine", () => { }); }); + test("secure App login forwards the selected region", async () => { + const initial = connection({ + browser: { region: "eu-west" } as NonNullable & { + region: "eu-west"; + }, + }); + const { client, calls } = fakeClient({ initial }); + const result = await beginAuthLogin(client, { + mode: "new_login", + domain: "example.com", + profile_name: "work", + region: "eu-west", + }); + expect(calls.createParams).toMatchObject({ + browser: { region: "eu-west" }, + }); + expect(calls.loginParams).toMatchObject({ + browser: { region: "eu-west" }, + }); + expect(result.connection.region).toBe("eu-west"); + }); + test("secure App login preserves explicit recording opt-outs", async () => { const initial = connection(); const { client, calls } = fakeClient({ initial }); diff --git a/src/lib/mcp/tools/managed-auth-state.ts b/src/lib/mcp/tools/managed-auth-state.ts index 5ac500d4..33bce07c 100644 --- a/src/lib/mcp/tools/managed-auth-state.ts +++ b/src/lib/mcp/tools/managed-auth-state.ts @@ -10,6 +10,12 @@ import { } from "@/lib/mcp/tools/managed-auth-checkpoint"; import type { ManagedAuthBrowserTelemetry } from "@/lib/mcp/tools/managed-auth-telemetry"; +export type ManagedAuthRegion = "us-east" | "eu-west" | "ap-southeast"; + +type ManagedAuthBrowserWithRegion = NonNullable & { + region?: ManagedAuthRegion; +}; + export interface SafeAuthConnection { id: string; domain: string; @@ -33,6 +39,7 @@ export interface SafeAuthConnection { flow_expires_at: string | null; can_reauth: boolean | null; can_reauth_reason: string | null; + region: ManagedAuthRegion; error_code: string | null; error_message: string | null; } @@ -47,6 +54,7 @@ export interface AuthLoginInput { save_credentials?: boolean; record_session?: boolean; browser_telemetry?: ManagedAuthBrowserTelemetry; + region?: ManagedAuthRegion; proxy_id?: string; proxy_name?: string; } @@ -97,6 +105,9 @@ const TERMINAL_ERROR_MESSAGES: Partial< export function toSafeAuthConnection( connection: ManagedAuth, ): SafeAuthConnection { + const browser = connection.browser as + | ManagedAuthBrowserWithRegion + | undefined; return { id: connection.id, domain: connection.domain, @@ -108,6 +119,7 @@ export function toSafeAuthConnection( flow_expires_at: connection.flow_expires_at ?? null, can_reauth: connection.can_reauth ?? null, can_reauth_reason: connection.can_reauth_reason ?? null, + region: browser?.region ?? "us-east", error_code: connection.error_code ?? null, error_message: connection.flow_status ? (TERMINAL_ERROR_MESSAGES[connection.flow_status] ?? null) @@ -466,6 +478,7 @@ export async function beginAuthLogin( record_session: recordSession, browser: { telemetry: browserTelemetry, + ...(input.region && { region: input.region }), ...(proxy && { proxy }), }, }); @@ -516,6 +529,7 @@ export async function beginAuthLogin( record_session: recordSession, browser: { telemetry: browserTelemetry, + ...(input.region && { region: input.region }), ...(proxy && { proxy }), }, });