Proposal: CAIPE App Contract for native UI, iframe apps, and agent capabilities #2853
Replies: 8 comments 2 replies
|
Thanks for writing this up. I think the client-only package plus an app-owned service behind the gateway is the right split, and the build-time checks in #2852 (pinned integrity, reserved paths, overlap detection, peer dependencies, auth-mode agreement) are a solid base. Some thoughts on how I'd like the plugin architecture to work more broadly. 1. Keep the boundary at "UI in the host, backend in the app"
2. Identity: verify the subject, never trust forwarded privilege
3. Non-browser callers need a first-class story
4. Adding vs. replacing host surfaces
5. Data and authorization ownership
6. Smaller contract details
On the decisions requested
|
PoC status update: contract 1.1This remains a proposal. The host contract PR is still a draft, and the following describes what the current proof of concept validates, not a generally accepted platform contract. Implemented and exercised
Still open before broader adoption
These observations support the add-on UI plus app-owned backend boundary in the proposal while preserving the iframe mode for less-trusted apps. |
|
My concern is the developer and operator experience when multiple plugins live in separate repositories:
Example: Plugins A, B, and C are maintained in separate repos. A small UI fix in A requires rebuilding CAIPE with the published packages from all three plugins, then redeploying the host, even though Plugins B, C, and CAIPE’s source haven’t changed. So for a small fix, developers of plugins need to rely on operators to rebuild CAIPE with new plugin version, and deploy, leading to frustrations from both.
|
|
This is a well-structured proposal, and I fully agree that build-time composition is the only sustainable path for native UI integration in a complex host like CAIPE. The distinction between "trusted native" and "hosted iframe" is critical, and your architectural table clearly highlights why the former is necessary for seamless navigation and theming without sacrificing the security boundaries of the latter. One significant challenge with the "same React tree" approach is managing state isolation and dependency conflicts across multiple trusted packages. If different app teams use slightly different versions of shared UI libraries or state management tools, you risk subtle bugs or bundle bloat. I’d recommend the contract strictly enforce a single, host-managed set of peer dependencies for all native packages, similar to how you’re handling the CSS scoping. This prevents any single app from accidentally introducing a divergent runtime environment. Regarding point 6 about bundle hygiene, I’ve found that enforcing strict size budgets at the CI stage is non-negotiable. When we reviewed similar plugin systems, we saw performance degradation quickly once multiple large bundles were statically imported. A hard limit on the initial load payload, combined with mandatory code-splitting for route-based views, keeps the shell responsive. Also, explicitly stating whether |
Example: Workflows as a modular native CAIPE feature
Intended boundaryWorkflows could use
The package consumes documented workflow APIs rather than importing host-private server modules or accessing MongoDB directly. The backend need not move into a separate service just to modularize the UI. Solution-level architecture%%{init: {"htmlLabels": false, "flowchart": {"htmlLabels": false, "padding": 20}}}%%
flowchart TB
Manifest["AgenticAppManifest<br/>native profile"] --> Build["Reviewed package<br/>and CAIPE image build"]
Build --> Registry["Generated module<br/>registration"]
Registry --> Shell["CAIPE shell<br/>shared React tree"]
Shell --> UI["Workflow UI<br/>native component"]
UI --> API["Authenticated<br/>workflow APIs"]
API --> Authz["Workflow and agent<br/>authorization"]
Authz --> Engine["Workflow engine"]
Engine --> Data["Workflow persistence"]
Engine --> Agents["Authorized agent<br/>invocation"]
The diagram describes the proposed module boundary. It does not imply that registration grants workflow/agent permissions or that PR #2852 implements a new workflow engine. Build and runtime lifecycle
Native packaging avoids a second document and iframe router coordination. It can approach built-in performance, but does not guarantee it: emitted bundles, lazy loading, dependencies, and data latency still need measurement. A UI package update still requires a CAIPE image rebuild and rollout. Current implementation versus next workAt the reviewed
See the workflow client, workflow engine, and reserved path/API rules. Recommended proof of concept and core registration designImmediate PoC: extract a workflow client package and register it at a non-conflicting path such as Core-feature target: introduce a host-owned built-in module registration adapter using the same manifest model. Host-maintained registration may explicitly assign the existing Do not remove The manifest can be common, while admission and ownership rules differ:
This is modular architecture, not Android-style browser isolation. Workflow native code would carry the same host-browser trust assumptions as other native packages. Roadmap fit
Recommendation: use Workflows to prove that one application model can describe both platform-owned native modules and separately maintained extensions. Keep the backend boundary and trust rules explicit; do not require repository or service separation solely for modular UI packaging. |
App contract review: scope, complexity, and securityMy understanding is that this contract/API pertains to two types of integration:
Assumptions behind this review
The critique below evaluates each field against these assumptions: what it enables, who should own it, and whether its complexity provides an actual integration or security benefit. Main changes requested
Detailed field, security, and configuration reasoning1. Generic permission requests: high complexity, little current valueFields: The schema requires a For example, declaring “use this agent” does not prevent a component in a native-package-app from calling the agent API directly. That API must check the user's permission independently. An enforceable version needs all of the following:
Recommendation: Defer this from the mandatory core until one complete operation demonstrates enforcement. Keep the manifest extensible through optional, versioned sections with defined compatibility rules. Do not require empty permission declarations today. If retained as future metadata, make that status explicit. Worth solving? Unauthorized resource access is worth solving through existing API/resource authorization. A generic installation permission envelope is worth adding only if it provides a defined restriction beyond those checks. Browser confinement of native-package-apps cannot be delivered by this field. 2. Gateway policy: useful for hosted services, excessive as a universal requirementFields: Authentication has a concrete purpose when CAIPE proxies a request to another service: the receiving service must verify the caller. HTTP admission rules and operation scopes can also be useful there. However, a native-package-app using only CAIPE APIs still has to declare Current gateway scopes are selected from the manifest's HTTP policy; they are not calculated from per-user CAS resource grants. Maintaining a manifest rule for every backend endpoint risks duplicating authorization and letting the two copies drift. Recommendation: Make gateway/auth policy conditional on hosted-service integration. Define receiver-enforced operations and operator-approved policy. Reuse existing resource authorization for calls from native-package-apps to CAIPE APIs. Worth solving? Verified identity between services is necessary. Reusing CAIPE API resource checks avoids maintaining overlapping access rules for calls from native-package-apps.
Delegation recommendation: Define short-lived, narrowly accepted credentials for app-to-CAIPE operations that identify the user and acting service. Reuse the repository's token-exchange experience, but specify the audience, actor validation, supported API surface, and failure behavior. Do not silently fall back to the original broad token if narrowing fails. A dedicated API must enforce the user's resource permission and, if introduced, an operator-approved app operation envelope. This could give future permission requests an enforcement path; it is not implemented today. Such delegation limits a compromised service's authority. It does not contain native-package-apps or same-origin iframe-apps that can obtain the original user credential through the host browser context. 3. Rendering and service configuration: keep the distinction, simplify the schemaFields:
The concrete combinations are:
Only one Recommendation: Keep renderer-specific adapters, clearly name hosted-service configuration, derive canonical paths, and use aliases only where the canonical app prefix is insufficient. Publish the actual support matrix; a shared schema does not currently provide identical renderer capabilities. 4. Operator decisions should not be publisher requirementsFields: These depend on the deployment: which other apps exist, where operators want them, local role names, ingress limits, and installed agents. Keeping these settings in the publisher declaration, sometimes alongside operator overrides, complicates configuration ownership and precedence. Publishers can recommend placement, role mappings, limits, and resource setup in their READMEs. These recommendations help operators configure the app; they should not become mandatory publisher-manifest policy. The individual fields are inexpensive. Their combined cost is precedence rules, duplicated configuration, and deployment-specific packages. Recommendation: Developers declare entry points, supported contributions, and technical compatibility requirements. Publishers document recommended deployment settings in their READMEs. Operators own the final placement/order, role mappings, limits, and resource bindings. Publisher labels/icons can remain optional presentation metadata. Worth solving? Placement and access mapping are necessary. Making the publisher control deployment decisions is unnecessary complexity. 5. Contracts to prioritize in the next phasesFields: These references should remain optional until the corresponding registration, resolution, and invocation contracts are ready. Requiring empty declarations adds configuration without enabling an integration. The more immediate requirement is a supported app-pod-to-CAIPE API. The current app gateway carries CAIPE-to-app traffic; it does not define the reverse integration. The five recognized host capability names are not a complete HTTP API specification. Recommendation: Start with concrete versioned operations, accepted credentials, request/response/errors, and user/service identity rules. Make capability sections optional and add references as their resolution/invocation behavior ships. iframe-apps need a documented way to communicate with CAIPE's shell: request navigation, update breadcrumbs, receive theme changes, preserve deep links, and report loading/errors. That communication interface is the host bridge. Define it together with the APIs app backends use to call CAIPE. Decide the supported origin/trust model early, because it affects this communication; a broader less-trusted/opaque-origin profile can remain separate follow-on work. For workflow integration in native-package-apps, use typed code APIs for panels, editors, callbacks, and subscriptions. Keep provider references in declarations and live workflow objects behind authenticated APIs. The next phases should complete or extend these explicit contracts:
Worth solving? Stable external APIs and SDKs for native-package-apps directly satisfy the requirements. An abstract capability catalog ahead of those interfaces is lower priority. 6. Auth should target realistic threats, with concrete controlsThe relevant threats are unauthorized resource access, compromised dependencies, forged identity, and direct calls from reachable pods. Operator-approved deployment does not eliminate these threats.
These controls need particular attention:
Prioritize controls against these concrete threats over mandatory permission metadata with no enforcement path. 7. Refactor responsibilities; reuse CAS for authorizationThe useful refactor is to give each decision one owner.
Enforcement remains in the API/service. CAS answers whether a verified principal may perform an action on a resource; the serving component stops the operation when denied. CAS does not sandbox JavaScript from native-package-apps, perform proxy routing, or replace token verification. For app services calling CAS, define a supported authenticated adapter first. The existing Access API evaluates its authenticated caller. A service token plus a user ID in the body does not establish user delegation, and a gateway app-audience token is not automatically a valid CAS credential. Worth refactoring? Yes: consolidate resource authorization through existing CAS/domain authorization paths and give authentication, routing, deployment configuration, and UI integration clear owners. App launch permissions, generic permission envelopes, and remote delegation remain design work; they should not be represented as capabilities CAS already supplies for this app contract. 8. Configuration and debugging burdenThe concern is how many settings must agree and how much knowledge is needed to diagnose a failure. Focus diagnostics on effective configuration and the component responsible for a failed request.
Where the current contract adds avoidable work:
For example, “the app does not work” can mean very different things:
Use consistent failure-stage labels through the gateway, receiving service, and platform APIs so operators know which configuration or permission decision to inspect. Recommendation: Treat diagnostics as part of the integration contract:
Worth the burden? Verified identity, correct routing, and resource checks are necessary. Duplicate settings, unused mandatory sections, and declarations with no runtime effect are avoidable complexity. The proposal needs a small configuration surface and a clear failure path, not just schema validation. 9. Proposed minimum boundaryKeep: identity/version, compatibility, renderer selection, route/slot ownership, artifact validation, operator installation, and private service/resource bindings. Simplify or move: canonical paths, duplicate version/configuration entries, presentation, deployment role mappings, and operator limits. Conditional: hosted gateway/auth policy, API aliases, provider references, and health metadata with a defined purpose beyond Kubernetes probes. Defer: mandatory generic permission requests until an end-to-end enforcement design exists. Keep the manifest extensible so an optional permission section can be introduced through a versioned schema change with documented compatibility behavior. Prioritize the app-to-CAIPE API contract, signing-key separation, direct/resource authorization tests, browser trust/mutation decisions, and typed SDK APIs for the first deep feature in native-package-apps. Reuse CAS for resource decisions through approved adapters; retain transport enforcement in the gateway and domain APIs. Implementation references
|
App Contract delivery backlog — October 14, 2026The review in this comment is now tracked as implementation work under App Contract epic #2928. Implemented foundation versus remaining work
Work packages
Delivery order and dependencies
Ownership and acceptance rules
|
|
I agree with @artdroz and @jnapper7. Use iframe as the default and native for apps that show a need for it. From looking through the code I found that:
I'm in favor of having both. Iframe works for bigger apps that can grow into something standalone. Native works for small, mostly visual, read-only dashboards. |

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Proposal: CAIPE App Contract for native UI, iframe apps, and agent capabilities
TL;DR
Phase 1 implementation update
CAIPE App Contract is the umbrella term for the shared manifest and rendering-profile interfaces.
AgenticAppManifestremains the manifest type; native packages implement a native component interface. Public version fields and behavior are unchanged.The name remains
AgenticAppManifest. New publishers use API 2.0; existing hosted v1.0 and native v1.1 inputs have compatibility adapters. The complete native declaration is supplied by its pinned package, while enablement, UI selection, and private service/resource bindings stay deployment-owned. See PR #2852 and the implementation documentation.This completes the shared declaration/registration foundation described in Phase 1. The CAS and Agent Builder sections below continue to describe the intended next phases. Permission requests remain metadata rather than effective grants.
1. Problem and intended outcome
CAIPE needs a consistent way to integrate independently maintained applications while preserving user identity, access controls, navigation, and agent interoperability.
Rendering is only one part of that problem:
The proposed outcome is a small shared application model with rendering-specific adapters and platform service contracts. An app should be able to change its UI rendering profile without redefining its domain APIs, agent identity, or authorization semantics.
This proposal extends the External Apps architecture discussion. It preserves hosted apps and adds a trusted native option.
2. Architectural choices and trade-offs
Keeping an app's source directly in CAIPE remains reasonable for a core feature. A package provides source ownership and a versioned extension boundary, but introduces packaging, compatibility, and release coordination costs.
Performance expectation: a well-integrated native package can approach a built-in feature's performance. Packaging alone does not guarantee equal startup, rendering, data-fetch, or navigation behavior. Iframe performance must likewise be measured for the actual app and deployment.
3. One app contract, separate rendering profiles
%%{init: {"htmlLabels": false, "flowchart": {"htmlLabels": false, "padding": 20, "nodeSpacing": 40, "rankSpacing": 45}}}%% flowchart TD Manifest["Common application<br/>manifest"] --> Installation["Approved installation<br/>and deployment bindings"] Installation --> Native["Native UI adapter"] Installation --> Frame["Iframe UI adapter"] Native --> SDK["Common host SDK<br/>behavior"] Frame --> SDK SDK --> APIs["Platform and app<br/>service APIs"] Builder["Agent Builder"] --> APIs Headless["Workflows and<br/>headless clients"] --> APIs APIs --> Enforcement["Gateway and service<br/>enforcement"] Enforcement --> CAS["CAS decision<br/>boundary"] CAS --> FGA["OpenFGA adapter"] Enforcement --> Services["Agents, tools, workflows,<br/>and app services"]The diagram describes the target. CAS answers authorization questions; execution continues through the responsible handler/service after an allow decision.
Internal applications and optional surfaces
4. Manifest model: declarations, approvals, and runtime decisions
The Android-manifest analogy is useful for identifying components, required capabilities, compatibility, and permission requests. Its operating-system isolation does not transfer to native JavaScript inside a shared browser document.
Use three separate records:
A publisher cannot grant itself access by editing its manifest. An app update that expands requested authority must produce a reviewable permission diff. Existing approval must not silently expand to cover new requests.
Illustrative future manifest
PR #2852 now provides
AgenticAppManifestAPI 2.0. The following is the original illustrative design sketch, retained to explain the declaration/installation boundary; it is not the executable schema. Use the implemented Phase 1 reference for current field names and checker behavior. Registry references do not provision services automatically.The concrete agent/resource IDs and runtime origins are bound by the approved installation. Secrets, raw tokens, and connected credentials do not belong in a publisher manifest or browser context.
An illustrative installation records
appId,appVersion,manifestDigest,selectedUiProfile,installed,enabled,visible,bindings, and references to the approved permission requests. Actual permission grants target authenticated principals and must retain their own ownership, audit, and revocation semantics.Claims are different from permissions
Stable route references should let the host bind concrete paths without downstream apps hard-coding another app's URL. Reserved paths and collisions must be checked for every rendering profile.
5. Threat model: native packages and iframe apps
Summary: native packages are trusted host code. The current same-origin, unsandboxed iframe is also a trusted-code profile—not an untrusted-app sandbox. A separately hosted backend or a different URL path does not change that browser boundary. An isolated iframe is a distinct future trust profile with additional enforcement requirements.
5.1 Scope, assets, and attackers
This model assumes an authenticated browser, HTTPS in deployed environments, a CAIPE shell/BFF, operator-owned installation configuration, and separately deployed app services. It distinguishes browser compromise from service compromise and build/publisher compromise. The source snapshot is PR #2852 at
6bfd938; these are source-level observations, not a penetration-test certification of any deployment.Protect:
Consider attackers:
An app being first-party lowers the ownership uncertainty; it does not eliminate XSS, supply-chain, or compromised-deployment risk.
5.2 Browser trust profiles
For example,
https://example.com/andhttps://example.com/apps/example/have the same origin. Origin is scheme, host, and port—not repository, service container, or URL path. Independent React trees do not create access-control boundaries. MDN: same-origin policy.flowchart TB subgraph Shared["Current trusted browser origin"] Host["CAIPE shell and DOM"] Native["Native package in host React tree"] Frame["Same-origin iframe: separate document"] Session["Host session and JavaScript-visible state"] Native --> Host Frame -->|"same-origin DOM access"| Host Native --> Session Frame --> Session end subgraph Isolated["Proposed dedicated app origin"] Child["Restricted iframe app"] end Child <-->|"bounded validated messages"| Broker["Host bridge"] Broker --> Host Native --> PEP["BFF/API enforcement"] Frame --> PEP Broker --> PEP PEP --> Policy["Applicable authorization checks"] Policy --> Service["App service and resource authorization"]The isolated profile is not implemented by selecting
mode: iframein the present manifest. Backend enforcement still applies to every profile.5.3 Native package threats and controls
These conclusions follow from the reviewed native integration implementation and its build-time trust assumptions.
5.4 Same-origin iframe versus isolated iframe threats
The current shell embeds a same-origin gateway URL without a
sandboxattribute and requests clipboard permissions. Separate documents provide layout/style separation and independent releases, but a compromised child remains able to affect the host origin. An iframe from another service reverse-proxied onto the same browser origin is still same-origin.For a less-trusted profile:
allow-scriptsandallow-same-originfor host-origin content: that child can remove the sandbox. On a genuinely different origin,allow-same-originpreserves the child's own origin; it does not make it the host origin.frame-src, childframe-ancestors, script/network policies, redirect destinations, and direct-navigation behavior. Origin isolation does not guarantee CPU/process isolation or prevent phishing inside an approved frame.These sandbox and browser-feature distinctions are defined by MDN: iframe controls.
Current proxy limitation: the gateway filters upstream
Content-Security-Policy,X-Frame-Options, andSet-Cookie. Do not assume a hosted service's headers survive this proxy. An isolated-profile implementation needs deliberate host/child policy enforcement rather than merely adding manifest fields.5.5 Session, JWT, and user-context threats
Current behavior: both native code and same-origin framed code can use the CAIPE browser session. The gateway authenticates the session and derives the user; it does not need to copy the session cookie into component props or messages. The current session callback exposes
accessTokento first-party browser code. Thus neither current profile isolates that bearer token from a compromised app.Recommended transport and lifecycle controls:
HttpOnlysession cookies, appropriateSecure/SameSitesettings, and narrow host scope. Do not share parent-domain session cookies with a less-trusted app origin.HttpOnlyprevents reading the cookie value; it does not stop host-origin malicious code from making authenticated requests. Cookie paths are not an app security boundary.SameSitealone does not isolate sibling same-site origins or protect against same-origin XSS.Cookie and session safeguards are described in OWASP: session management; the bullets are requirements to validate, not a claim that PR #2852 adds all of them.
app-scoped-tokenforward-user-access-tokenA user ID is an identifier, not authentication proof. Receiving services must verify signatures with trusted keys, allowed algorithms, issuer, audience, expiry and applicable claims; distinguish access tokens from ID/session tokens. Never trust an unsigned
sub, role header, route context, or claimed app ID as authorization. Short expiry reduces exposure but does not guarantee immediate revocation. RFC 8725: JWT security practices.Important limitation: using an app-scoped token on the gateway-to-service hop cannot prevent current host-origin app code from calling a different host endpoint using the same user's session. It protects a service credential boundary, not an npm-package/browser boundary.
5.6 Bridge abuse and confused-deputy threats
A future common iframe SDK must treat every bridge operation as input—not as authority:
contentWindow/event.source; an allowed origin may contain multiple frames."null"; that string is not a trusted identity. Any opaque-origin bridge requires an explicitly designed channel-binding protocol.Origin/source and exact
targetOriginhandling are documented in MDN: postMessage.For current same-origin hostile code, message validation alone is insufficient: the child can bypass the intended bridge and use direct DOM/API access. Use actual isolation before claiming that the bridge is its only authority path.
Confused deputy: an app must not supply a user ID, agent ID, credential reference or service URL and cause the host to execute with broader authority. Bind destinations/resources to the approved installation, derive the verified caller server-side, and independently authorize the concrete operation. This is the intended Phase 2–4 enforcement design, not a complete capability broker in PR #2852.
5.7 Next.js build and rendering boundary
"use client"selects the client-component module boundary, not a security sandbox. Next.js prerenders Client Components for initial page loads and hydrates them in the browser. Therefore publisher code needs build/render as well as browser review. Next.js: server and client components.The checker rejects declared server exports and listed server-only import patterns. It does not prove that all transitive code is browser-only or harmless. SSR opt-out, when explicitly configured for a rendering adapter, changes when component rendering occurs; it does not neutralize installation tooling or unsafe package imports.
5.8 Backend authorization, credentials, and agent execution
For both renderers:
The shared CAS target is described in section 6. PR #2852 retains existing session/role/HTTP-policy enforcement; it does not implement the proposed application CAS grants or universal broker.
5.9 Current controls versus required follow-on evidence
These are threat-model test obligations, not all passing results today.
5.10 Recommendation and explicit residual risk
Separate repositories, Shadow DOM/scoped CSS, React trees, manifests, and integrity hashes do not individually create a malicious-code sandbox. OWASP: micro-frontend boundaries.
Residual risk accepted by current trusted profiles: an app compromise can affect host-visible data and exercise the user's otherwise authorized session. Backend authorization limits access beyond that user's authority; it cannot make hostile code safe inside the user's trusted browser context.
6. CAS: shared authorization for both rendering modes
Current foundation
CAS means CAIPE's Centralized Authorization Service in
ui/src/lib/authz. In the reviewed source snapshot it is a module inside the BFF; this proposal does not assume a separately deployed CAS service.Existing foundation APIs include:
POST /api/access/checkPOST /api/access/queryPOST /api/access/grantsDELETE /api/access/grantsBFF callers use CAS in process. Remote consumers need an approved authenticated adapter/API. Existing legacy authorization and gateway paths are not all migrated; adding the app contract must not imply that platform-wide CAS migration is complete.
Identity rules
subject, delegated identity, or caller-supplied trusted context.Proposed app authorization model
Phase 2 should add application resources and actions through the approved resource-model and CAS adapter boundary. The exact new resource name and action vocabulary require design review; examples such as
application/usebelow are proposed, not current supported Access API pairs.The model should distinguish:
For each protected operation, all applicable conditions must allow it:
This is the target enforcement rule, not a claim that every layer is already wired. The envelope can restrict brokered service operations; it does not isolate native JavaScript from all host browser APIs.
Example request lifecycle
sequenceDiagram actor User participant UI as Native or iframe UI participant PEP as Gateway / API handler participant CAS as CAS module or authenticated adapter participant FGA as OpenFGA participant Service as App / agent service User->>UI: Request protected operation UI->>PEP: Authenticated request PEP->>PEP: Verify caller, installation, binding, and input PEP->>CAS: Caller-bound action/resource check CAS->>FGA: Evaluate policy and relationships FGA-->>CAS: Decision CAS-->>PEP: ALLOW, DENY, or unavailable alt Authorized PEP->>Service: Approved operation with verified identity Service->>Service: Enforce domain and downstream resource access Service-->>UI: Result and correlation context else Denied or unavailable PEP-->>UI: Stop operation with appropriate error endThe service must enforce its checks when invoked directly, including by agents, MCP callers, webhooks, or schedules. A browser launch check is not a substitute for data-plane authorization.
Failure, cache, revocation, and audit rules
agent/usechecks currently have fresher execution semantics than some batch/list decisions. Do not enforce invocation from a stale picker result.no-storeand short token lifetimes do not by themselves provide immediate revocation.Credentials and domain authorization
Connected credentials stay behind the credential-management boundary. Services request authorized use of a credential; browser components do not receive raw secrets.
A steward, owner, or service credential must not widen a requesting user's access implicitly. The service must validate the operation's execution identity and policy, credential-use permission, and target-resource access. App-owned domain resources should use approved authorization adapters and scoped relationship ownership; apps must not mutate unrelated platform/team/admin relations directly.
7. Authentication continuity without unrestricted token sharing
Both UI profiles should preserve one CAIPE sign-in and a stable user subject. Authentication mode and service audience are deployment-reviewed contract choices.
forward-user-access-token.One user login should feel continuous across apps while each service's accepted authority remains explicit.
8. Agent Builder, agents, tools, and workflow contracts
Agent Builder is a core CAIPE experience for discovering, configuring, and composing agent capabilities. The underlying contracts belong to the platform APIs and runtime, so their use does not depend on the builder UI being loaded.
Providers advertise; consumers compose and invoke
flowchart LR AppServices["App services"] -->|MCP tools| Registry["Existing registries + capability adapters"] RemoteAgents["Remote agents"] -->|A2A cards and skills| Registry Workflows["Workflow services"] -->|Workflow references and schemas| Registry Registry -->|Authorized discovery| Builder["Agent Builder"] Registry -->|Authorized discovery| Apps["Native and iframe apps"] Builder -->|Persist configuration references| Runtime["Agent/runtime service APIs"] Apps -->|Invoke or subscribe| Runtime Headless["Schedules and headless clients"] -->|Invoke| Runtime Runtime --> Authz["CAS and downstream enforcement"]Reuse existing protocol foundations
An app manifest should reference the source of capability truth rather than copy every live tool schema or agent description into a UI package.
Bidirectional integration examples
Prefer meaningful domain operations with explicit inputs, outputs, and effects over exposing every UI button as a tool. Distinguish read operations from writes, approval-required actions, and long-running jobs. Runtime checks must re-evaluate the actual resource/action and approved execution identity.
Example: Workflows as a modular native feature
Workflows could publish a native UI package and
AgenticAppManifestwhile retaining its existing backend. The UI would share CAIPE's React tree, session, theme, routing, and breadcrumbs; modular packaging does not require a separate repository.Detailed Workflows example, architecture diagram, build lifecycle, and proposed built-in registration adapter.
Current boundary: external packages cannot claim reserved
/workflowsor replace workflow APIs. A PoC can use/workflow-studio; preserving the core route requires a separately designed, host-owned registration adapter. This is a proposal, not functionality delivered by PR #2852.9. Host SDK and UI lifecycle
Phase 3 should define common behavioral operations, with transport-specific adapters.
Common methods should have defined result/error semantics. React components and functions are not serialized across an iframe; each adapter implements local SDK methods over its transport. The current optional native
Linkprop remains a native-specific convenience.Iframe messages must validate origin/source or the expected opaque-origin sandbox channel, schema, bounded payloads, and handshake/session identity. Requests need correlation, timeouts, and ordering to prevent stale route events from overwriting current navigation. Native integration needs cleanup, suspense/loading states, and error boundaries.
The canonical public route belongs to CAIPE. Internal host rewrite paths must not leak into app links. Route transitions should preserve app state when intended and invalidate resource-specific data when the route changes.
The MCP Apps host bridge and lifecycle offer patterns to reuse for tool-associated iframe views. Full routed applications still need route, session, and lifecycle requirements beyond a tool-result view.
10. Build, publish, install, and rollback
Native profile
Use CI artifact caching and automated image assembly to reduce coordinated-release friction. Host-version compatibility and reproducible rollbacks remain operator responsibilities.
Iframe profile
Shared release record
Record the app version and manifest digest, source commit, selected UI profile, host version, SDK/checker version, service versions, relevant authorization model/policy revision, and approved permission changes. Do not store credentials or raw JWTs in that record.
11. Milestone phases and completion gates
The five-milestone sequence remains the delivery roadmap. PR #2852 now contains the Phase 0 native foundation and Phase 1 shared manifest/installation implementation. Phases 2–5 are follow-on proposals.
AgenticAppManifest2.0, installation, capability references, permission requests, rendering profilesSecurity, compatibility, and performance tests should begin in each phase. Phase 5 consolidates release evidence; it is not the first time authorization is tested.
Phases 0–1 — What PR #2852 implements
The implementation snapshot is
6aabb9a9cf4c3171fcf1d39a0bbf05bb1f299f02. The code and documents in the PR are the implementation reference; this roadmap does not expand its scope retroactively.AgenticAppManifest2.0, native component interface 2.0, App SDK/checker 2.0.0-rc.1, common manifest CLInavigate, optional hostLink, breadcrumbs, shared shellPR #2852 has a 64 KiB entry-module and 2 MiB compiled package JavaScript checker budget. Those are uncompressed artifact checks; they are not measured network latency or proof of the total initial payload.
The generator currently uses eager static package imports and global stylesheet inclusion. A small entry can import expensive dependencies. The future loading gate must inspect emitted bundles and test whether unopened apps affect shell loading.
PR #2852 implements Phases 0–1. Phase 1 retains the name
AgenticAppManifestand introduces API version 2.0. The native component interface is now 2.0; explicit legacy native component contract 1.1 remains supported without relabeling legacy modules. The implementation includes:Phase 1 limits: provided/consumed capabilities and permission requests are declarations. They do not create grants, provision agents/tools, or change token scopes. Unsupported required capabilities fail validation. The current iframe profile still launches under
/apps/<id>; profile selection does not implement the future cross-document route/lifecycle SDK.Still outside this PR:
Validation: full UI evidence is from behavior snapshot
6bfd938. The terminology-only update6aabb9areran 26 contract/package tests, 16 native UI tests, lint, and the production build successfully. Prior full-suite evidence: 26 contract/generator/packed-SDK tests; 719 UI Jest suites and 8,454 tests passed (12 tests and one suite skipped); lint and optimized UI build passed. The SDK package dry run includes the common types/validator and both checker CLIs. An existing asynchronous audit-log warning remains. These checks do not certify authenticated deployment behavior or production performance.The implementation reference is the shared manifest documentation. The native foundation retains its existing interfaces and limitations.
Phase 1 — Shared application manifest
Deliverables
Exit criteria
Suggested ownership: platform contract and UI integration maintainers, with authorization review.
Phase 2 — CAS app authorization
Deliverables
Exit criteria
Suggested ownership: authorization and gateway maintainers, with app-service owners.
Phase 3 — Shared host SDK
Deliverables
Exit criteria
Suggested ownership: UI host/SDK maintainers and app publishers.
Phase 4 — Agent capability integration
Deliverables
Exit criteria
Suggested ownership: Agent Builder/runtime, MCP/A2A, workflow, and authorization maintainers.
Phase 5 — Validation, compatibility, and release
Deliverables
Exit criteria
Suggested ownership: platform release, UI performance, authorization, runtime, and app publisher maintainers.
12. Milestone and issue organization
The phases above are proposed GitHub milestone definitions in this discussion. This update does not create milestone or issue objects.
Suggested milestone names:
App Contract 0 — Native UI Foundation— PR feat(ui): add shared AgenticAppManifest and native UI contract #2852.App Contract 1 — Shared Manifest and Installation— included in PR feat(ui): add shared AgenticAppManifest and native UI contract #2852.App Contract 2 — CAS Authorization.App Contract 3 — Host SDK and Rendering Adapters.App Contract 4 — Agent Capability Integration.App Contract 5 — Conformance and Release.For each implementation issue, record:
Keep changes reviewable: schema/migration, authorization model/adapter, host SDK/adapters, protocol integration, and release evidence should be separate work items/PRs where feasible. UI, runtime, and auth work can progress in parallel only when their prerequisite contracts are agreed.
PR #2852 should be reviewed as the native foundation plus shared
AgenticAppManifestPhase 1 migration. CAS grants, generalized capability execution/composition, and a shared iframe lifecycle SDK should not be represented as already delivered.13. Decisions requested
References
CAIPE implementation and authorization
Established architecture and protocol foundations
All reactions