System
The System section in the /org sidebar contains platform-level configuration. Two sub-pages today:
System Consumer Settings
Path: /org/system/settings-consumer
Controls how Consumers can register, whether OTP is required, and which Spaces new outside-registered Consumers automatically get.
The page has a Save button at the bottom — none of these settings take effect until you save.
Section 1 — Consumer Registration
| Field | Effect when Yes |
|---|---|
| Allow customer to be registered from the system. | Admins can invite Consumers from inside /org (the email-activation flow). |
| Allow customer to be registered outside the system. | The public sign-up form at /registration becomes reachable, and the "Sign up" link appears on /login. |
What actually gates in-app (admin-invite) registration. Creating a Consumer from
/orgis gated by org roles — an account needs the consumer Write permission (seeroles.md). There is no per-tenant "register from system" switch: the only per-tenant registration kill-switch is the outside (public) one. For partner-bound tenants this lives on the tenant's contract asoutsideRegistration(see Multi-tenant access below), and the public registration UI is reachable only when it is enabled.
Section 2 — Consumer Login
OTP toggles, per Consumer class:
| Field | Effect when Yes |
|---|---|
| Use OTP Login for system registered users | Consumers invited from /org are sent through the OTP page after entering credentials. |
| Use OTP Login for outside registered users | Consumers who signed up via /registration are sent through OTP. |
The two are independent — you can require OTP for one class and not the other.
Per-tenant override. For consumers bound to a partner tenant, the OTP decision comes from that tenant's contract (
otpInsideRegistration/otpOutsideRegistration), not from these global toggles. The global toggles are the fallback for first-party consumers. Partner tenants additionally carry block-login flags — a tenant can refuse logins from system-registered consumers, from outside-registered consumers, or both (see Multi-tenant access).
Section 3 — Consumer Spaces
"Set default spaces for every outside registered consumer."
A table of Spaces with columns:
| Title | Description | Id |
|---|---|---|
| Main Space | Default Main Space | cmncvl3u50000o77w4p2u0xpc |
When a Consumer activates their account via the /registration flow, they're auto-assigned every Space listed here. They see those Spaces on / from their first login.
This setting only affects outside-registered Consumers. System-registered (admin-invited) Consumers get Spaces assigned manually from their consumer-edit page in /org.
Per-tenant default spaces. For partner-bound tenants, default spaces are carried on the tenant's contract and exist for both registration kinds — a default-system set and a default-outside set — each a subset of the spaces the tenant is allowed to offer. On every login the issued token's spaces are also clamped to the set the tenant currently permits, so a space the tenant has since revoked cannot survive into a live session. See Multi-tenant access.
Documentation pending: the picker UI for choosing which Spaces appear in this table (multi-select against all Spaces, drag-and-drop, etc.) is not yet documented.
System Google Connect
Configures the platform's Google integration. The values you set here are exposed to the runtime as the google_settings resource — the same settings the public REST surface serves at resources/google_settings. Flow code does not reach Google through a dedicated "external token" library: outbound HTTP from a Script Node goes through the SSRF-guarded system/http resource, and the consumer's Google-Connect token (when present) is read from the request via the read-only system/cookies resource.
Note: the earlier "External API / encrypted external token retrieval" framing is obsolete — the
system/externallibrary it referred to is not part of the current resource set. Usesystem/httpfor outbound calls; see the Script Node reference.
Documentation pending: the exact form fields on this page and the Google Cloud / OAuth client setup an admin must complete before filling it in are not yet documented. Do not assume field names — confirm against the live
/orgUI.
What this connects to
| This setting | Surfaces here |
|---|---|
| Allow registration from system → Yes | /org admin can invite Consumers (also requires the consumer Write role) |
| Allow registration outside system → Yes | /registration becomes reachable + /login shows "Sign up" link |
| OTP for system users → Yes | System-invited Consumers go through OTP on login |
| OTP for outside users → Yes | Self-registered Consumers go through OTP on login |
| Consumer Spaces table | Spaces auto-assigned to new outside-registered Consumers |
| Google Connect | Populates the google_settings resource read by the runtime |
Multi-tenant access & partner integrations
When the platform is fronted by partner applications, each partner is bound to a tenant contract that governs how its consumers register and log in. This is an operator concern — the contract is configured on the admin side, not by flow developers. Below is what an operator needs to know; the cryptographic internals are out of scope for these docs.
Origin allow-list
Every public request (both the REST surface and the chat WebSocket) is checked against an org-wide Origin allow-list:
- A request whose browser
Originis not on the list is dropped at the connection level — there is no HTTP error body and no close code; to the caller it looks like the server is unreachable. - The match is exact, including scheme and port —
http://localhostdoes not matchhttp://localhost:5174. Add a separate entry per origin (no wildcards, no regex). - An empty list means any origin is accepted. This is only the fresh-install bootstrap state; tighten the list before exposing the sandbox to anything untrusted.
Application tokens (server-to-server)
Partner/integration apps that call the public REST surface use an application token — a long-lived Bearer credential minted by exchanging an api key together with a user's email and password. It is sent as a standard Authorization: Bearer … header (never in a cookie or URL). The token itself is signed by the shared api-keys certificate — not a per-tenant cert (the per-tenant certificate binds the consumer access_token, a different credential). The application token's tenant binding comes instead through the api key → client → contract chain plus its client_id. Deleting or rotating the api key, or unbinding its client, revokes outstanding tokens within seconds.
Per-tenant policy & the cross-tenant gate
Each tenant contract declares, for that tenant alone:
- the spaces it may offer, and the default spaces new consumers receive for each registration kind (system vs outside);
outsideRegistration— the only per-tenant registration kill-switch (in-app registration stays gated by org roles);- OTP per registration kind (
otpInsideRegistration/otpOutsideRegistration); - block-login flags per registration kind (refuse system-registered logins, outside-registered logins, or both).
Consumer login tokens are signed with the tenant's own signing certificate. A consumer registered for one tenant cannot log in through another tenant's surface — a mismatched login is rejected (HTTP 406). On every login the issued token's spaces are clamped to the set the tenant currently permits.
Related
- Consumers — what these settings affect.
- Chat → Login, Registration, OTP — the user-facing surfaces toggled here.