Settings scope — instance credentials vs the person's own account
Maintainer, 2026-10-18: "double check instance settings vs user settings … apple maps key and alike must go to instance settings. user should just set up his apple account. pls revisit all settings tabs."
The rule
| Home | Address | Holds |
|---|---|---|
| Instance settings | Administration app (/Admin/Settings/...), platform admins only |
developer and platform credentials and integration configuration: Apple MapKit / WeatherKit / MusicKit keys, Google Maps key, the Google OAuth client, sign-in provider clients, model-provider keys the instance pays for, storage bindings, payments, system mail |
| User settings | the person app (/{user}/Settings/...) |
what is the person's own: profile, language and time zone, notifications, launcher, their own account connections (an Apple ID, a Google or Microsoft consent, a Home Assistant they run), their personal preferences |
A person is never asked to paste a developer API key to use an app. A credential bound to a user token (a Google refresh token, an Apple Music User Token) stays valid only with the developer credential that minted it; so where a person already holds such a token with their own key, that setup keeps working (see "Migration" below).
Instance keys are written to Key Vault through a SetSecrets instance action (never to node
content) and reach the portal as configuration. 🚨 A value is read only when the deployment
record declares its config key; the Administration tab's Value column says what the portal reads.
Inventory — the person app (`/
Read from the running company instance (first paint of rbuergi/Settings) and from the sources.
| Tab id | Where it shows | Stores, and where | Who writes | Verdict |
|---|---|---|---|---|
| Profile | user | profile fields on the user node | the person | correct |
| Account | user | read-only: who the session is | n/a | correct |
| Preferences | user | language, time zone, theme on the user node | the person | correct |
| user | the person's Microsoft 365 mailbox consent / mail preferences | the person | correct (delegated consent; the app registration is instance configuration) | |
| Inbox copies | user | opt-in switch per live source; copies in the person's space | the person | correct |
| Notifications | user | per-app notification preferences | the person | correct |
| API tokens | user | the person's own tokens | the person | correct |
| Security | user | approval step-up methods | the person | correct |
| Connected instances | user | the person's links to other instances | the person | correct |
| Sharing | user | access control on the person's partition root | the person | correct |
| Extensions | user | which in-app extensions the plan covers | the person | correct |
| Connections › Accounts | user | one row per provider; state read from the person's own records | the person | correct (rows link to the package tabs below) |
| Connections › Messaging | user | which channels reach the person (Teams, WhatsApp, iMessage) | the person | correct (bot / Business API registration is instance configuration, ConfiguredByDeployment) |
| Connections › MCP clients | user | connecting an MCP client | the person | correct |
| Connections › Signing authority | user | the person's signing identity and the provider they connected ({user}/_Signature/*) |
the person | correct, see judgement call 1 |
| Connections › Apple Music | user, only where the package is held | the person's Music User Token (own Apple sign-in) | the person | split: developer key to Administration › Integrations (was a per-user paste form) |
| Connections › Apple Weather | user, only where the package is held | pinned places and language; was also the WeatherKit key | the person | split: WeatherKit key to Administration › Integrations; places stay |
| Connections › Google | user, only where the package is held | the person's consent (refresh token); was also the OAuth client id and secret | the person | split: OAuth client to Administration › Integrations; consent stays |
| Connections › iCloud | user, only where the package is held | Apple ID + app-specific password (the person's own CalDAV credential) | the person | correct: an app-specific password is the person's own and no developer programme is involved |
| Connections › Home Assistant | user, only where the package is held | base URL + long-lived token of the person's own home server | the person | correct |
| Storage | user (partition root) | storage binding for the person's own partition ({user}/_Storage) |
whoever holds Update on the root | correct; the instance default is the Administration › Storage tab |
| Threads › Settings › Models / Harnesses / Web search | the AI app | the person's own model-provider keys, harness logins, search default | the person | correct as an OPTIONAL bring-your-own key; the instance keys are Administration › AI providers (judgement call 2) |
Apple Maps (MyMaps) |
the package page | previously the person's MapKit key | n/a | moved already (Plugins#3321): instance key only; a stored legacy key is no longer read under Home:AppSource=Directory and says so |
Inventory — the Admin app (/Admin/Settings)
| Tab id | Group | Stores | Verdict |
|---|---|---|---|
| Overview | read-only build and plugin facts | correct | |
| Manage apps | the apps on the instance, audience on {app}/_Policy |
correct | |
| Maps | Google Maps API key, Apple MapKit JS token and Server API trio (Key Vault) | correct | |
| Integrations (new) | Apple WeatherKit key, Apple MusicKit key, Google OAuth client (Key Vault) | correct, added by this change | |
| AI providers | shared model-provider keys and tiers | correct | |
| Administrators, Sign-in providers, Invitations, Privacy, Published to the web, Service identities | People and sign-in | platform access and sign-in clients | correct |
| Updates, Operations packages, Instance registration, Fleet console, Build queue, Data sources, Governed activities, Partitions, Storage, Inbox | Operations | platform operations and bindings | correct |
| Coupons, Instance grants, Composition, AI usage and cost | Commercial | plans, grants, cost | correct |
Satellite repos (read only): MeshWeaver.SocialMedia LinkedIn publishing reads its OAuth client from
deployment configuration (Social:LinkedIn:ClientId / ClientSecret) and the person only connects
their own account, which is already the right split. X and YouTube import the person's own
archive and need no credential. Crm, Education, FundReporting, Manufacturing and Reinsurance carry no
settings tab of this kind.
What this change moved
| Credential | Was | Now | Config keys |
|---|---|---|---|
Apple WeatherKit (team, key, services id, .p8) |
per person ({user}/_Connections/weather) |
instance; the person keeps places and language | AppleWeather:TeamId, :KeyId, :ServiceId, :PrivateKey |
Apple MusicKit (team, key, .p8) |
per person (developer token minted from their key) | instance; the person keeps only their Music User Token | AppleMusic:TeamId, :KeyId, :PrivateKey |
| Google OAuth client (id, secret) | per person | instance; the person keeps only their consent | Google:OAuth:ClientId, :ClientSecret, :RedirectUri (the authorize page URL registered on the client) |
The three live as rows of Administration › Integrations (Store/AdminTabs/Integrations, area
AdminIntegrations, InstanceIntegrations in Store/Catalog/Source), write-only like the Maps tab.
Migration — an already-configured key keeps working
- Weather: instance key complete wins; else the person's stored record is used as a fallback and their page says so. Nothing is dropped.
- Music, Google: tokens are bound to the developer credential that minted them. A person who already holds a Music User Token or a Google refresh token together with their own key keeps using it (their page notes that an instance key now exists). Everyone else, including every new user, uses the instance credential.
- An instance that has not declared the new config keys behaves exactly as before.
Judgement calls for the maintainer
- Signature providers. Skribble, Swisscom AIS and Swisscom Sign already fall back to the mesh's
Skribble:*,Swisscom:Ais:*,Swisscom:Sign:*configuration when a person has no sign-in of their own, and DeepSign is per person only. A signature account can be the operator's contract or the person's own, so it was left a person-level connection with the instance fallback. If the operator's contract should be the norm, add the same kind of Integrations rows and drop the per-person form. - Bring-your-own model keys in Threads › Settings › Models stay user-level as an optional override of the instance keys; a plan that wants "instance keys only" removes that tab.
- Token-bound precedence above (own key kept for an existing token) deviates from "instance first" on purpose, so no configured setup breaks. Retiring it means asking those people to reconnect once.
- Vault declaration. Saving a key on the Integrations tab only reaches the portal once the
deployment record declares the ten keys: four
AppleWeather__*(TeamId, KeyId, ServiceId, PrivateKey), threeAppleMusic__*(TeamId, KeyId, PrivateKey) and threeGoogle__OAuth__*(ClientId, ClientSecret, RedirectUri); that is a deployment-record change, not made here.