Apps catalog
Register the portals and project-backed apps on your deployment, and control who is allowed to open each one
Overview
An app is a surface someone opens: one of the platform portals, or a custom app backed by one of your projects. Registering an app in the catalog is what makes it possible to control who may open it at all, as opposed to what they can do once inside.
You manage it in Superadmin → Access Control → Apps Catalog.
This is a separate question from roles and permissions. A role decides what someone can do inside a portal. An app entitlement decides whether the portal opens for them in the first place. See Access control for the former.
The three platform apps
Superadmin, Hub, and Studio are registered automatically the first time the platform starts. You do not run anything to create them, and they appear in the catalog on every deployment.
They are registered in a deliberately inert state:
- No entitlement is required. Registering them makes them visible and manageable; it does not start refusing anyone.
- No origin is set. Access control for an app only becomes active once it has an origin, so out of the box these three are registered and not enforced.
That combination is the point. You can see the catalog and plan before anything changes for a single user.
Custom apps from projects
A custom app is backed by a project, and access derives from project membership. Add someone to the project in the build portal and they can open the app; remove them and they cannot.
There is no separate list of app users to maintain, no sync job, and no second place for the two to drift apart. Registration is keyed on the project, so registering the same project twice is harmless.
Unlike the platform apps, a custom app does require an entitlement, and project membership is what supplies it. Someone who is an admin, builder, operator, or viewer on that project can open it. Anyone else is refused.
Turning enforcement on
Access control for an app is switched on by registering an origin for it in the catalog, not by changing configuration and redeploying.
Give the app its own origin
Set the origin the app is actually served from. An app with no origin is registered but not enforced.
Grant the entitlement
For a platform app, entitle the people who should be able to open it. For a custom app, project membership already answers this.
Because this is data rather than configuration, you can enable it for one app at a time, and you can undo it, without a deployment.
How the platform decides which app a request is for
Four signals, strongest first:
- The request's own
Origin, matched against the catalog - The token audience, minted and signed by the server
- The deployment host map (deprecated, see below)
- The
X-MagOne-Appheader, asserted by the client
Origin is checked first, and that ordering is load-bearing. A browser cannot forge Origin — page script is not permitted to set it — so it is at least as trustworthy as the token, and it describes this request rather than the session.
The token audience is a snapshot of wherever the session logged in. One cookie is shared across every portal on a domain, so deciding from the token binds the answer to the login rather than to the page being opened. In practice that broke both ways: someone who logged in at Hub could then open Studio and have it render in full, and someone who logged in at Studio first was refused from Hub even though they were entitled to it.
Never set MAGAUTH_APP_HOSTS. It is deprecated and setting it causes an outage. The map is host-to-app and ignores the path, so on a deployment serving Studio, Hub, Superadmin, and the API from one host, every request resolves as the single app named, and a denial on that app denies every portal at once.
The limitation worth understanding
An origin has no path, so it cannot tell /hub from /superadmin when both are served from the same host. Neither the catalog nor the old host map can separate portals that share an origin.
Enforcing app access across portals is therefore an ingress change first: give each portal its own hostname, then register each one with that hostname as its origin.
Until you have done that, leaving app access unenforced is the correct state, not a broken one. Every other permission still applies normally — roles, groups, and overrides all work exactly as documented. What you lose is only the outer "may you open this portal at all" check.