Platform Operations and Tenant Trust Surface

This page separates the implemented Platform Admin control plane from the tenant-visible trust features that remain roadmap work. The filename is retained for stable links.

← Back to Deployment and Operations

Implementation status

Area Status
Reserved-host Platform Admin routes Implemented in the main web application
Platform-user password + TOTP, lockout, recovery, allowed status Implemented
Host-bound Platform Admin session Implemented
Tenant provisioning/lifecycle, jobs, schedules, backup/restore controls Implemented
Fleet health summaries Implemented
Separate Platform Admin Container App Not implemented
External identity header/allowed-email gate Not implemented
Tenant /admin/trust dashboard Not implemented
Public /status page Not implemented
Azure Blob application WORM sink Not implemented; external control required

Do not use roadmap controls as evidence for a current release.

Current security boundary

Platform Admin is a privileged, mutating prefix in the same Container App as tenant traffic. Requests are admitted only when:

  1. KMP_PLATFORM_ADMIN_PORTAL_ENABLED=true;
  2. the normalized request host is in KMP_PLATFORM_ADMIN_HOSTS;
  3. the operator authenticates with a platform_users email/password and TOTP;
  4. the account has an allowed status;
  5. lockout/recovery checks pass; and
  6. the session was established for the same admin host.

A configured admin host redirects non-admin paths to the portal. Tenant hosts must not be listed as admin hosts and cannot use an admin session issued for another host. The current app does not consume a trusted external identity header. Penetration and regression tests should test host confusion, forwarded host handling, session replay across hosts, password/TOTP lockout, recovery paths, CSRF, and action authorization.

The data console is separately gated by KMP_PLATFORM_DATA_CONSOLE_ENABLED and should remain disabled in production unless reviewed.

Current operator capabilities

The implemented console is not read-only. Depending on controller policy and step-up requirements, it can:

Views and audit metadata must not expose database passwords, plaintext secret values, reusable KEKs, wrapped DEKs, TOTP/recovery material, credential-bearing object URLs, or raw job errors.

Tenant onboarding and job ownership

Tenant creation is asynchronous. The HTTP request validates safe metadata, creates/updates the registry row in provisioning, stores only secret reference names and safe configuration, and queues a tenant_provision platform job. The worker—not the web request—creates or validates the role/database, writes the database password to the configured writable secret store, runs tenant migrations, creates backup-key material, and activates the tenant only after verification.

The current Azure background authority runs every three minutes:

bin/cake platform worker run \
  --schedule-limit 100 \
  --max-jobs 100 \
  --max-runtime 45 \
  --cycle-budget 240 \
  --platform-limit 1 \
  --json

It dispatches due schedules, drains default/active tenant queues, and claims a bounded platform job. The old Azure sched-hourly, sched-daily, sched-weekly, and sched-nightly jobs are parked compatibility shapes.

Job parameters may contain tenant identifiers, safe configuration, and secret reference names. They must never contain plaintext passwords, tokens, API keys, KEKs, or connection URLs.

Backup and restore controls

Current formats are:

Requests enqueue tenant_backup, platform_database_backup, or tenant_restore jobs. Download, portable recovery-key export, manual deletion, and restore require typed confirmation, reason, current TOTP, and a platform audit record. Tenant targets must be suspended before restore queueing and are checked again under the operation lock.

The web application does not restore the platform database. Operators decrypt an exported platform backup on a secured recovery host and use the external PostgreSQL recovery process.

Fleet health

Current Platform Admin health derives from platform data and telemetry:

Treat absent evidence as unknown, not healthy. A default/disabled WORM sink or an unexecuted restore drill is not proof of continuity or recovery.

Data isolation rules

Audit and WORM status

Platform audit rows include a hash chain. The local file sink appends redacted, hash-chained JSONL records but is not storage-enforced WORM. The azure_blob sink is not implemented, the default is disabled, fail-closed defaults to false, and deploy/azure/main.bicep does not create immutable audit storage.

A production trust packet can require WORM continuity, retention lock/legal hold, and monitoring, but those must be supplied and verified as external controls until the application integration exists.

Tenant-visible trust roadmap

The proposed tenant /admin/trust surface and public status page are not current routes. If implemented, tenant evidence should be read-only, scoped to the resolved tenant, and summarized around:

It must not expose another tenant’s name or metrics, raw audit/job rows, object URIs, database names/roles, secret reference names, wrapped keys, or operator identity beyond an approved display.

Recommended freshness semantics for a future surface should be derived from the actual backup policy and evidence timestamps rather than a fixed “24 hours” label. No trust card should claim WORM, restore success, or incident clearance from configuration alone.

Regression checklist

For each Platform Admin change, verify: