Repository navigation
Conversation
|
Here's a visual recap of what changed: Open the full interactive recap |
…kie-only hook, and redact a credential split from its scheme - Carry #8071's AuthOptions.getBrowserSession hook in auth.ts byte for byte, so whichever PR merges second sees identical hunks. - On the review page, an app with a custom getSession and no hook gets a page that says it can't confirm the sign-in, instead of a login page that only sends the reader back; its JSON and POST answer 401 naming the missing hook. - Redact "Authorization: Bearer" or "Basic" with the credential on the next line; the bearer pass had nothing left to match once the scheme was gone. - A request with an origin that doesn't parse no longer gets a configured loopback link.
There was a problem hiding this comment.
Builder reviewed your changes — looks good ✅
Review Details
Incremental review summary
This commit separates embed-origin resolution from ordinary MCP request metadata, uses a validated origin for widget CSP and embed tickets, and adds coverage for malformed forwarded headers and proxy-origin cases. I reviewed the delta as a high-risk session/authorization change. The two prior findings are addressed: ordinary session lookup no longer parses embed origins when no embed credential is present, and widget CSP expansion now uses the same validated embed origin as ticket minting. The trailing-slash capability-cookie issue was resolved in the previous review. I found no additional confirmed, actionable issues in this incremental diff. The new malformed-origin paths fail closed rather than silently producing an unscoped session or widget.
🧪 Browser testing: Skipped — browser-test-planner is unavailable; these changes affect server-side session and origin validation, not visual presentation.
|
Thanks for the update. This PR changes the runtime human-approval boundary for A2A/action calls across core. Before approval, it needs an independent current-head approval from a verified BuilderIO member; the current review history shows only the integration bot. |

MCP Apps embed sessions now authorize the embedded target and its declared actions.
create_embed_sessionis advertised and accepted only when the effective inline-apps signal is enabled. UI capabilities and UI approval proof require the signed-in browser cookie identity and same-origin evidence.Ordinary inline cards reuse explicit
mcp.directoryProfile.widgetTargetsand read/write argument contracts. The signed session binds the app mount, target, resource IDs, and allowed actions/arguments; scoped renewal retains those limits. Cards without a contract return their ordinary full-app link. Embed target headers, referrers, and ambient browser cookies do not expand session authority. Approval-gated card calls returnapproval_requiredwith guidance to finish in the full app.An additive ticket-store migration records the issuing audience before redemption and renewal. Existing tickets without an audience require a fresh card call. Existing tables and columns remain intact.
Embed ticket minting, widget CSP and own-app resource metadata, start URLs, and audience checks use a configured, allowlisted forwarded public origin, otherwise the peer-validated request origin. Proxy deployments with internal request URLs need their public origin configured through
APP_URLor the workspace gateway URL unless the proxy connects over loopback. Ordinary MCP metadata and reconstructed SDK requests retain their existing origin behavior. Originless/stdio calls retain their ordinary app link, and scoped renewal uses the issuing origin, including on beta and mounted apps. Originless local Design visual-edit calls still save their design/screens and returnopenUrl, but omit the short-lived editor handoff; completing that workflow requires the full app or an origin-bearing request.Supported inline hosts still receive the one-time start URL and scoped-renewal metadata in
_meta, because the card needs them. The narrowed session and authenticated renewal are the authority boundary. The inline signal narrows exposure and is the same deployment flag/email allowlist, trusted first-party header, or directory-mode signal used to render cards; a declared MCP client capability does not enable it.Follow-up: align all MCP origin consumers,
getOrigin, andgetMcpOAuthAudienceson one allowlist-aware rule. This PR limits the origin change to embed sessions.Card compatibility
This reduces the Mail draft, Calendar draft and Content sharing cards to full-app links for full-catalog callers where main showed them inline; scoped draft and document contracts follow in stacked PRs.
This inventory covers all 51 template actions on main that render
embedAppcards, plus the three framework views. Inline rendering depends on the existing deployment flag/email allowlist, trusted first-party signal, or directory mode. Deployed production flag and allowlist values have not been verified. No per-card data contract is added here.create-document,create-content-databasecreate-design,create-design-from-template,generate-design,present-design-variantscreate-deck,add-slideget-analysis,compose-dashboard,ensure-demo-dashboards,ensure-risk-meeting-dashboard,ensure-native-v2-dashboards,get-sql-dashboard,open-traffic-dashboard,list-sql-dashboards,mutate-dashboard,save-analysis,reorder-dashboard-panels,update-dashboardopen-asset-picker,generate-assetmanage-event-draftget-recording-player-data,search-recordingsshare-local-file-document,submit-content-database-formadd-localhost-screens,generate-screens,export-coding-handoff,show-design-questions,get-design-snapshot,open-visual-editcreate-formmanage-draftvisual-answer,update-visual-plan,import-visual-plan-source,create-visual-recap,create-visual-questions,create-visual-plan,create-ui-plan,create-prototype-plan,create-plan-design,convert-visual-plan-to-prototypeclone-context-slide,get-deckview-screen,context-manifest-get,context-preview-getExisting directory action/resource contracts remain in use. Their allowed data actions still work, subject to approval. Collaboration, presence, upload-status, and legacy upload endpoints are outside the action-runtime grant and stay denied; this PR does not claim full parity for those features. Metadata-only
mcpAppdeclarations have no additional renderer to change.Related open cards need bounded contracts in their owning PRs: #8005 and #8018 (Mail draft exposure/compact draft); #8017 (
suggest-document-edit); and all seven action entries exposed by #8010 (Analytics traffic, Calendar draft, Content sharing, Design generation/handoff, Slides and Slides-2 clone). #8004 changes host documentation only. The owning thread has the declaration shape and fallback inventory. Either merge order is safe.Browser callers and approval follow-up
Require a browser session for A2A approvals.
Approval predicates receive
httpfor an unproven frontend label; bearer calls returnapproval_required, browser-cookie calls without a UI capability retain mint-and-retry, and execution caller labels remain unchanged.getBrowserCookieSessionand its private resolver started as a verbatim copy from #8016 atab91ab94; this PR adds an explicit cookie-only custom-auth hook. #8016 owns the helper, and its thread will carry the matching update. Whichever PR lands second should rebase and drop the duplicate. #8016 is still open, so adding its review link to cardapproval_requiredresponses remains a follow-up after it lands.The shared browser client sends cookies and normal fetch metadata. Same-origin browser GETs commonly omit
Origin, soSec-Fetch-Site: same-originremains valid origin evidence alongside the cookie identity; UI proof refuses when both headers are missing. Agent Native desktop loads app pages in Electron webviews using that browser client; no separate UI-capability caller was found. CSRF-only routes retain their existing missing-header and Tauri handling, so installed native apps, scripts, and server callers keep working without an Origin header. UI proof and capability minting require positive same-origin browser evidence alongside cookie identity, including in generated workers. An Origin header without a Host is also refused by the shared CSRF check. Ordinary server-side rendering skips capability minting. Dispatch's server-to-server calls use bearer/A2A credentials and do not mint UI capabilities. Clips desktop adds bearer authentication and omits cookies in development, so that path cannot mint a UI capability; gated operations require the full signed-in browser. Sandboxed card frames and directOrigin: nullcalls cannot mint or prove UI, and instead use their explicit scoped action grants. Over HTTPS the embed session cookie isPartitionedto the agent client's top-level site, so it isn't sent on a top-level visit to the app. In plain-HTTP local development the cookie isSameSite=Laxwithout partitioning. Expired or unrelated ambient embed cookies are ignored on normal app requests. Live scoped embed credentials and explicit embed markers still cannot mint a UI capability, and the cookie Max-Age is capped at the token's remaining lifetime. The capability handler checks live capability cookies directly, including trailing-slash and app-mounted routes. Ordinary session lookup validates embed origin only for signed embed credentials; empty or malformed forwarding does not interrupt normal browser-cookie sign-in. Invalid authority grants no embed session, while ticket minting, start and renewal retain explicit400errors and live scoped credentials still restrict UI proof. Static custom MCP App HTML remains available without an embed-session contract. Direct UI-mint test helpers now provide the matching Origin explicitly.Custom authentication must explicitly configure the cookie-only
AuthOptions.getBrowserSessionhook for UI capabilities and browser approvals. Without it, UI-capability minting returns a401naming the hook, and the server warns once. Design uses its signed Builder identity cookie; Docs reads its existing anonymous cookie without creating a session. The embedded host adapter accepts and normalizes an explicitly configured browser hook. The changeset and authentication docs in all supported locales describe this migration.Validation
pnpm install, workspace postinstall builds, and recursive workspace typecheck pass. The root typecheck wrapper has a Windowsspawn EINVAL; the equivalent recursive pnpm command completed successfully, with a final core typecheck after the resource-binding repair.open-visual-editsuite passes all 48 specs. Refusal regressions were also checked against the pre-change source; no live server was used.pnpm guards: all 93 checks pass with Git's GNUgrepavailable on the Windows PATH. The settings guard also passes on the exact rebase base,b07c13bf20c4636931d3cf4d97c0d4ad8acdb305, in that environment. Both i18n guards pass. Thecoercion-okannotation on the session matcher records the intentional invalid-origin non-match; ticket operations retain explicit errors.