Skip to main content

Tenant Admin Onboarding Hardening

OP-071 makes the super-admin tenant bootstrap flow safe enough for AWS dev demos and pilot onboarding. A tenant-facing user is now created only after Keycloak creation and verification succeed.

What Changed

  • Tenant-facing roles (tenant_admin, operator, auditor) require Keycloak bootstrap.
  • POST /api/v1/admin/tenants/{tenant_id}/users no longer accepts a "create without Keycloak" option.
  • Email and initial password are required.
  • Server-side password policy rejects weak temporary passwords before Keycloak is called.
  • Keycloak is verified before OneProtect commits the SQL role assignment.
  • Verification evidence is returned to the UI and stored in the audit payload.
  • A system-admin verify endpoint reports drift between OneProtect and Keycloak.
  • Worker reconciliation emits platform.tenant_user.drift_detected when tenant user assignments and Keycloak drift.
  • Logout uses Keycloak end-session when possible, and login supports switch-user prompting.
  • Empty tenant console states preserve the authenticated /api/v1/session role and tenant context, so a newly bootstrapped tenant admin can still see tenant-admin actions such as enrollment token creation before any demo workflow data exists.
  • Interactive Settings mutations update shell-level console state, so created enrollment token metadata, SCIM connections, and platform tenant rows remain visible when an operator/admin switches console tabs and comes back.
  • Tenant-admin security notices now use guardrail labels rather than "Read-only mode" when mutation controls are available.

State Model

API Validation

Create tenant user:

POST /api/v1/admin/tenants/{tenant_id}/users

Required fields:

  • user_id
  • display_name
  • role
  • email
  • initial_password

Verify tenant user:

POST /api/v1/admin/tenants/{tenant_id}/users/{user_id}/verify

Common 422 response:

{
"error": "identity_provider_failure",
"code": "keycloak_not_configured",
"detail": "Tenant admin bootstrap requires Keycloak.",
"remediation": "Verify Helm values and the Keycloak admin secret."
}

Operator Runbook

  1. Log in as system_admin.
  2. Create the tenant in Settings.
  3. Bootstrap the first tenant user as tenant_admin.
  4. Use the user's real email address.
  5. Use a temporary password with 12+ characters, uppercase, lowercase, digit, and symbol.
  6. Confirm the UI shows Keycloak verification success.
  7. Share the username and temporary password out of band.
  8. Ask the tenant admin to log in and change the temporary password.

To test as the new user, use the switch-user link on the login page or an incognito/private browser window. This avoids reusing the existing super-admin SSO session.

Troubleshooting

SymptomCauseFix
422 keycloak_not_configuredAPI pod lacks Keycloak bootstrap configuration.Check Helm values, API env, and the Keycloak admin Secret.
422 keycloak_admin_credentials_missingAdmin URL or Secret values are missing.Recreate the Kubernetes Secret and redeploy API/worker.
Verification table has red rowsKeycloak user attributes or credentials did not match.Fix realm mappers/admin config, then retry user creation.
Password rejectedTemporary password violates server policy.Use a stronger password that does not include tenant terms.
Login reuses super-adminKeycloak SSO session is still active.Use Logout, then Switch user, or a private browser profile.
New tenant shows Auditor view or hides tenant-admin actionsThe frontend is using a stale bundle or an empty-state session fallback.Redeploy the frontend image with the empty-tenant session-role fix and verify /api/v1/session returns role=tenant_admin.
Created enrollment token disappears after switching tabsPage-local Settings state was remounted from the original server snapshot.Redeploy the shell-state fix so Settings mutations update console-level demo state; after full refresh, verify GET /api/v1/agent-enrollment/tokens returns the token metadata.

Validation

  • tests/test_platform_admin_runtime.py
  • frontend/src/test/console-auth.test.ts
  • frontend/src/test/oneprotect-ui.test.tsx
  • make validate-contracts
  • make aws-dev-helm-render

Non-Scope

  • No SCIM rewrite.
  • No production IdP migration.
  • No new role model.
  • No tenant self-service signup.
  • No deployment from the feature branch.

Future Identity Modes

ADR-0021 proposes a later multi-mode tenant identity provider architecture for keycloak_local, brokered enterprise IdP federation, and SCIM-managed tenants. That work is intentionally parked until OP-071 is validated in AWS dev and a separate migration/contracts/UI branch is approved.