Publishing apps
Anyone can register an app. The gate is rollout, not creation — how a self-registered app goes from private to visible, and who approves it.
Atrium is a directory anyone in the org can add to. Registering an app is not an admin action — the gate sits one step later, at rollout.
The two-step model
The distinction that makes open registration safe:
| Who | What happens | |
|---|---|---|
| Register | Members of the Atrium app creators group (official Delphi testers, partners, leaders) and admins | The app exists, but is SECRET — it appears in your launcher and nobody else's. You become its owner. No Zitadel SSO project is created. |
| Publish | An app publisher or admin | Visibility flips to DISCOVERABLE. Now it is in the directory for everyone it is scoped to. |
Nothing about a freshly-registered app touches the wider org: it is invisible,
it holds no identity project, and it grants nobody anything. Even so, creation is
limited to the Atrium app creators group: official Delphi testers, all partners and
all leaders, plus anyone an admin adds. Everyone else asks first (below).
Registering
Three doors, same service and same rules:
- UI —
/admin→ Register app - API —
POST /api/apps/registerwith{ id, name, description } - MCP / agent — the
register_apptool, so a coding agent can do it mid-flow
You get back the app, its owner row (you), a dev group, and — when the
DNS connector is connected — an auto-claimed subdomain
<slug>.atrium.<zone>.
The safe envelope is forced server-side, not left to the client: visibility
is pinned to SECRET and syncZitadel to false regardless of what the caller
sends. A client cannot register a discoverable app by passing extra fields.
If you may not register yet
The register door answers 403 app-creation-restricted for anyone outside the
group, and the answer names the next step. Everyone else asks per app: in
the launcher, Create an app turns into Request an app; over the API it
is POST /api/apps/request-creation with the same id, name and
description register takes, plus an optional message; an agent calls
request_app_creation with the same fields.
The request lands in Admin → Apps & Groups → Requests next to access
requests, and the super-admins get an email linking to it. Approve
registers exactly that app, private and owned by the requester, as
register_app would have. It does not make them an app creator: their next app
is another request, and owning an app never lets anyone create a new one.
Deny takes an optional reason. The person gets an email either way.
The answer to every ask names the super-admins who decide, so the person (or
their agent) knows who to chase. GET /api/apps/request-creation, or the
get_my_app_creation_request tool, reads where their requests stand, and the
register_app refusal carries the same status.
The limit is armed by the environment variable ATRIUM_APP_CREATORS_GROUP_ID
(the id of the Atrium app creators group). Unset it and redeploy to open the
door again. Existing apps and their owners are not touched.
Getting it published
Ask an app publisher. The role exists precisely so approvals are not stuck behind the handful of instance admins.
atrium:app_publisher is a real Zitadel role key, which means it can be granted
via a group rather than person by person. Atrium is itself a registered app,
so granting a group the atrium app with that role key gives the role to every
member — and because groups can mirror the directory, approver rights track the
org chart automatically.
The intended mapping at OMMAX is the existing dynamic directory group
omx_leaders_all ("ALL Employees with Level 5-7"), so every leader is a
publisher without anyone maintaining a list. See Groups for how a
directory group is mirrored, and Members and RBAC for the
full role table.
What a publisher can and cannot do
Deliberately a role, not a tier:
- Can — see the admin area, register apps, and flip
visibilityon any app - Cannot — change an app's
categoryorisPublicAccess, delete apps, remap Zitadel, or touch groups, secrets, scripts, members or API keys
Approving an app is not the same as changing what it is, and it is not the same
as handing it to the whole org without a grant — isPublicAccess stays
admin-only for that reason.
A publisher also does not inherit owner rights on the app they approve. They pass the permission gate on publishing rights alone, so they cannot rewrite someone else's app description while approving it.
Note: the role must exist on the Zitadel Atrium project before it can be granted. Creating it is a one-time admin step; after that, assignment is group-based.