Skip to content

Platform admin

Sys-admin routes for tiers, global settings, pool health, provider catalog, access control, and telemetry.

Intended audience: Stakeholders, Business analysts, Solution architects, Developers, Testers

Learning outcomes by role

Stakeholders

  • Clarify platform admin powers versus org admin boundaries.

Business analysts

  • Document admin-only workflows for support and operations teams.

Solution architects

  • Restrict admin routes via network policy and privileged access tooling.

Developers

  • Use cadence:system:* permissions and admin routers safely.

Testers

  • Attempt privilege escalation and cross-tenant access negative tests.

Platform admin routes configure the entire deployment — quota tiers, runtime flags, the provider model catalog, RBAC roles, and OAuth2 clients. These are cadence:system:* operations: an org admin’s token will receive 403 on every route on this page. Admin endpoints are registered on the main API next to tenant routes; SettingsService coordinates the pool and optional message-bus notifications when changes should reach running instances without a full restart.

  • Blast radius — These routes change behavior for every tenant simultaneously. A misconfigured tier quota or a disabled provider model affects all orgs.
  • Separation of duties — Org admins govern their own orchestrators, plugins, and users. Platform admins govern the infrastructure those orgs run on. The two permission namespaces (cadence:org:* vs cadence:system:*) enforce this boundary.
  • Support workflows — Document which incident types require sys-admin access versus org-scoped admin, so support engineers know which level to escalate to.
  • Audit — Each cadence:system:* permission name is a distinct audit event type; pair them with change records in your ITSM.

All routes live under /api/admin/*. They mount with the rest of the public API. SettingsService bridges global_settings rows and optional broker notifications so pool nodes can react without full restarts when messaging is available.

Subscription tiers define the quota limits that constrain what each org can do — maximum orchestrators, hot instances, chat RPM, and similar capacity controls. Tiers are stored as JSON objects in the global_settings table under keys like tier.free, tier.pro.

| Method | Path | Permission | Action | | ------- | ------------------------------ | ---------------------------- | -------------------------------------------------- | | GET | /api/admin/tiers | cadence:system:tiers:read | List all tier definitions and their current quotas | | PATCH | /api/admin/tiers/{tier_name} | cadence:system:tiers:write | Update quota limits for a tier |

Valid tier names: free, plus, pro, premium, business, enterprise. Patching a tier takes effect on the next request that reads quota for an org on that tier — there is no restart required.

Global settings are runtime key/value pairs that control platform behavior without restarting the process. They are the “Tier 2” layer of the settings cascade — above the hard-coded defaults in AppSettings and below per-org configuration. Examples include token TTLs, pool limits, and OTel configuration.

| Method | Path | Permission | Action | | ------- | --------------------------- | ------------------------------- | ----------------------------- | | GET | /api/admin/settings | cadence:system:settings:read | List all global settings | | PATCH | /api/admin/settings/{key} | cadence:system:settings:write | Update a global setting value |

When a setting is updated and RabbitMQ is available, the handler publishes a global_settings_changed event so pool nodes can reload affected values without polling.

These endpoints let platform admins inspect the current state of every running orchestrator instance and the pool as a whole.

| Method | Path | Permission | Action | | ------ | ----------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | GET | /api/admin/health | cadence:system:health:read | Health check all loaded orchestrator instances — returns framework, mode, plugin count, and readiness per instance | | GET | /api/admin/pool/stats | cadence:system:telemetry:read | Pool statistics: total instances, hot tier and demand pool counts, shared model and bundle counts, memory estimate |

The unauthenticated GET /health endpoint remains the right choice for load balancer probes. Use /api/admin/health for diagnostics and incident investigation — it gives per-instance detail rather than a single boolean. See Monitoring for how to interpret pool stats during incidents.

The provider catalog is the platform-level list of LLM models available for orgs to use. Adding a model here makes it selectable in org LLM configuration; removing or disabling it prevents new selections but does not stop already-running orchestrators. The catalog row’s primary key is an auto-increment integer, not a UUID7 (the only such exception in the schema).

| Method | Path | Permission | Action | | ------- | --------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------- | | GET | /api/admin/providers/models | cadence:system:providers:read | List all provider models (with enabled=false included) | | POST | /api/admin/providers/{provider}/models | cadence:system:providers:write | Add a new model to the catalog | | PATCH | /api/admin/providers/{provider}/models/{model_id} | cadence:system:providers:write | Update model metadata (display name, pricing, aliases, enabled flag) |

When adding a model, provider is the framework-level provider identifier (e.g. openai, anthropic). The model_id must be unique per provider; a conflict returns 409.

Two additional endpoints under /api/ (no admin gate — authenticated only) help clients build their LLM config forms:

| Method | Path | Permission | Description | | ------ | ----------------------------------------------- | -------------- | -------------------------------------------- | | GET | /api/frameworks | Authenticated | List registered framework types | | GET | /api/frameworks/{framework_type}/supported-providers | Authenticated | Query provider and mode support for a framework |

When adding a model, provider is the framework-level provider identifier (e.g. openai, anthropic). The model_id must be unique per provider; a conflict returns 409.

Platform admins can create and manage custom RBAC roles and OAuth2 clients beyond the built-in roles.

| Method | Path | Permission | Action | | ------- | ------------------------------------------------------------- | ------------------------------------ | ---------------------------------------------------------- | | GET | /api/admin/roles | cadence:system:roles:read | List all custom roles | | POST | /api/admin/roles | cadence:system:roles:write | Create a custom role with a set of cadence:* permissions | | PATCH | /api/admin/roles/{role_id} | cadence:system:roles:write | Update an existing custom role | | POST | /api/admin/users/{user_id}/roles | cadence:system:roles:write | Assign roles to users | | DELETE| /api/admin/users/{user_id}/roles/{role_name} | cadence:system:roles:write | Unassign a role from a user | | GET | /api/admin/permissions | cadence:system:roles:read | List all known cadence:* permission strings | | GET | /api/admin/oauth2/clients | cadence:system:oauth_clients:read | List registered OAuth2 clients | | POST | /api/admin/oauth2/clients | cadence:system:oauth_clients:write | Register a new OAuth2 client |

The OAuth2 client path is /api/admin/oauth2/clients (with the 2), not /api/admin/oauth-clients.

Built-in role names (sys_admin, org_admin, org_member, etc.) cannot be modified. Custom roles can carry any permission from the PERMISSIONS set. See Role-based access control for the full permission table.

| Method | Path | Permission | Action | | ------ | ---------------- | ------------------------------------- | --------------------------- | | GET | /api/stats/... | cadence:org:stats:read (org-scoped) | Org-scoped usage statistics |

Stats routes are org-scoped, not platform-scoped — an org admin can query their own stats without sys-admin access.

  • Telemetry reload — Changing OTel settings via /api/admin/settings publishes a telemetry_changed event when RabbitMQ is available. Without messaging, the change is written to the database but pool nodes pick it up only at next startup or explicit reload.
  • Tier patching scopePATCH /api/admin/tiers/{tier_name} only accepts the six known tier names. Custom tier names are not supported.