Skip to content

Instance and account settings

Instance administration is not one writable settings object. The console separates activation, platform users, identity providers, account security/sessions and instance observations. Process configuration is owned by deployment environment, not by a fictional PUT /settings API. Project settings affect one project; platform roles affect instance administration.

SurfaceActual route / authorityPersistence/effect
ActivationGET /license, POST /license/activate; see activationValid official-image-compatible activation; not vendor issuance
Platform users/users, /users/invite, /users/{email}/role; see platform usersPlatform accounts/roles, not project end users
Platform OIDC/admin/oidc-providers; platform OwnerProvider registration, encrypted secret and login policy
Account security/auth/mfa, /auth/password; interactive session where requiredCurrent account password/factor; see MFA
Sessions and PATs/auth/sessions, /auth/tokensSeparate refresh sessions and persistent management tokens
InstancesGET /admin/instances; platform Owner/AdminRead-only live-node inventory, no restart/upgrade action
Worker observations/admin/pool/stats, /admin/pool/stats/cluster; platform administrationOperational views, not durable configuration replacement

Platform owner, admin, developer, operator are the actual role literals. A project’s Owner is not automatically an instance Owner. Platform Owner does not bypass explicit project membership. Even a project member cannot universally read endpoints/trees: those reads require editor membership. Management identities has the complete plane distinction.

Use the deployment’s environment/secret mechanism for DATABASE_URL, VIAT_PUBLIC_URL, token/encryption keys, registration/MFA policy, runtime limits, retention, storage and network trust. The console is not an environment-file editor. Changing process knobs may require controlled restart/redeployment; it does not rewrite previously stored secrets or delete historic payloads by implication. Keep original encryption material available during migrations/restores.

VIAT_PUBLIC_URL must be the stable externally understood URL, including an intentional deployment prefix, when enabling project IdP and registering callbacks. Do not use an arbitrary caller Host header as the identity issuer. A private network/CA needs actual trusted connectivity from every participating verifier/provider; accepting a string config does not test that trust. Do not disable TLS verification to make login “work”.

Use the existing configuration reference for exact environment defaults and restart behavior rather than guessing new settings routes. Activation, public registration, MFA and upstream identity are independent prerequisites; an activated instance is not necessarily open for self-registration.

These routes sign platform accounts into the console/CLI. They are not project oauth_oidc authorizers or delegated Chinese-platform apps. Owner-only GET/POST /admin/oidc-providers; GET/PATCH/DELETE .../{name}.

Create fields:

FieldDefault / validation
nameRequired; ^[a-z][a-z0-9_-]{0,62}$; stable route identifier
display_nameRequired string; human login-button name
issuerRequired URL; HTTPS except localhost/127.0.0.1 HTTP; creation eagerly fetches discovery
client_idRequired provider client identifier
client_secretOptional/null/empty = no client secret; nonempty encrypted at rest
scopesOptional/null space-separated string, default openid profile email; must include openid (case-insensitive validation)
audienceOptional/null provider audience
default_roleOptional/null = platform operator; one of actual four roles
trust_email_claimOptional/null = true; choose deliberately according to provider email assurance

Source-derived unexecuted Owner request (will perform discovery if a real operator runs it):

终端窗口
curl -sS "$BASE/admin/oidc-providers" \
-H "Authorization: Bearer $PLATFORM_ACCESS_TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"fixture-sso","display_name":"Fixture SSO","issuer":"https://identity.example.invalid","client_id":"fixture-console","client_secret":"REPLACE_WITH_PROVIDER_SECRET","scopes":"openid profile email","default_role":"operator","trust_email_claim":false}'

Public provider picker is GET /auth/oidc/providers; browser start/callback are GET /auth/oidc/{name}/start and /callback. Register the exact callback at the provider. POST /auth/oidc/exchange completes the one-time Viat handoff, and CLI uses its own POST /auth/oidc/{name}/cli-init / GET .../cli-poll path. Prefer CLI login rather than hand-building internal handoff codes. Provider secrets are never exposed in public picker/detail responses. trust_email_claim influences identity linking; never enable it for an untrusted issuer merely to merge matching email strings.

PATCH fields: optional display_name, issuer, client_id, scopes, default_role, trust_email_claim; omitted/null leaves unchanged. Updating issuer revalidates/discovers it. client_secret is written as a nested Option in the DTO: actual deserialization treats explicit JSON null like omission (no double-option deserializer), despite comments saying null clears. Use a nonempty string to replace and "" to clear. audience has the same null/omit limitation; an explicit null is not a reliable reset operation in this release. Do not copy project-settings null-reset rules to this endpoint. Provider name is fixed.

Changing/deleting a provider is not offboarding its already-created platform accounts, PATs or project memberships. Inventory and revoke those independently; verify an alternate Owner login before removing the only SSO path. No real provider registration, discovery/SSO, code exchange or identity linking was tested for this page.

Instance inventory and version verification

Section titled “Instance inventory and version verification”

GET /admin/instances returns an array of {id,hostname,version,started_at,last_heartbeat_at} for currently alive nodes, ordered by start time. version may be null for old/unreported versions; it is not proof a node upgraded. The console polls at 15-second intervals and flags mixed versions. This is a heartbeat window, not historical inventory or a readiness proof under load. A missing node may be stopped/stale/unreachable; investigate service and database health rather than deleting a row to repair it.

Source-derived unexecuted read:

终端窗口
curl -sS "$BASE/admin/instances" -H "Authorization: Bearer $PLATFORM_ACCESS_TOKEN"

Compare every intended serving node’s version with the deployed stable release and the separately versioned clients. The endpoint cannot roll out an image, edit configuration, restart a worker or prove TLS/device/provider interoperability.

  1. Establish a second Owner recovery method and backup configuration/encrypted-data keys before changing issuer, registration or MFA policy.
  2. Update one surface at a time. Check whoami, real membership, factor status and a newly established session; an existing cached console session can conceal broken future login.
  3. For compromise, revoke PATs separately from sessions; local CLI logout is local-only and leaves project token state. Project customer identities are separate again.
  4. Redact screenshots, logs and configuration exports. Resource secrets are platform-side; never send them to scripts as a workaround.
  5. Revert the intended deployment config/provider config if needed; do not assume endpoint rollback restores instance settings. Audit state-changing administration.

Expect 401 invalid credential, 403 incorrect platform role, 400 provider validation/discovery failure, and 404 missing provider. Operator access to instance topology should be denied even if project operations are allowed. A Developer PAT must not become an Owner by setting default_role on an inaccessible route.

No tests/builds/installations, environment changes, network calls, provider actions or cleanup were executed. Evidence: crates/viat-api/src/{dto.rs,handlers/admin_oidc_providers.rs,handlers/platform_oidc.rs,handlers/admin_instances.rs,middleware_auth.rs}, web/src/pages/settings/{InstancesPage.tsx,SecurityPage.tsx,SessionsPage.tsx}, web/src/pages/projects/ProjectSettingsPage.tsx. The OIDC null-reset mismatch is an implementation discrepancy, not an invented supported operation.