Custom App Manifest
Schema id: custom-app-manifest@1
Machine-readable schema: custom-app-manifest.schema.json
The canonical description of a Custom React App (Section 6.3): the Module Federation remote the Platform Shell loads for a hand-written app in an environment. A manifest is validated identically whether it is registered through the Admin Control Center, submitted via a direct API call, generated by an AI assistant, or carried inside a Solution import — the one-validation-path rule (Section 6.7).
Shape
| Field | Type | Required | Notes |
|---|---|---|---|
logicalName | string | yes | Publisher-prefixed, lower snake-case (e.g. par_sales_dashboard). Used as the app's stable artifact id — the audience of its App Context Token. |
displayName | string | yes | Human-readable name shown on the Shell's home page. |
description | string | null | no | Short description shown on the app tile. |
entryFileName | string | no | The container entry file inside the package (e.g. remoteEntry.js), copied from the archive's own manifest. Empty in Hosted mode, which has no package. |
packageHash | string | null | no | Lower-case hex SHA-256 of the archive this app was registered from. Null in Hosted mode. On Solution import it is checked against the bytes that travelled in the package, so what is served is what was exported. |
remoteEntryUrl | string | yes | Either an absolute http(s) URL of the remote's remoteEntry.js (Hosted mode — its origin must be on the environment's Shell allow-list, Section 6.3), or a webresource:<logicalName> reference (Packaged mode, Section 6.15) — the bundle is stored as Web Resources and served by the platform, which the Shell resolves to a platform serving URL and treats as first-party. |
scope | string | yes | The Module Federation container's global scope name (unique per remote), matching the remote's federation({ name }). |
module | string | yes | The exposed module path the Shell loads (e.g. ./App). Must start with ./. |
requestedScopes | string[] | yes | Scopes the app declares it needs; requested when its App Context Token is minted and intersected with the user's own. May be empty. |
declaredEntities | string[] | yes | Entities the app declares it accesses, for review and dependency validation. May be empty. |
Where it is validated
- Registration — the Application Layer validates the manifest against
custom-app-manifest@1and enforces thatlogicalNamestarts with the owning publisher's prefix before recording the app in an environment. - Solution import — every embedded manifest in a Solution package is re-validated against the same schema before the app is registered in the target environment, so a hand-edited package cannot slip an invalid remote through.
Security notes
A Custom React App runs in the same JavaScript realm as the Shell (Module
Federation, not an iframe — Section 6.3), so the trust boundary is enforced
elsewhere: the remoteEntryUrl origin must be allow-listed for the environment
(CSP), the app is only loadable if a Solution deployed it into that environment,
and every data call it makes through the Runtime SDK is authorized server-side
against the scopes on its App Context Token. Declaring a scope in
requestedScopes never grants it — it is intersected with what the user already
holds.
Related
- Runtime SDK reference (how a Custom App consumes
useParswareRuntime()). - Solution Package — carries these manifests between
environments under its
customAppsarray.