Skip to main content

Tenant Lifecycle

This guide explains what happens when tenants are created, attached, or restored, and what steps you need to take in each scenario.

Creating a New Tenant

Creating a new tenant is the most common operation. It sets up a fresh, fully configured environment.

What Happens Automatically

  1. Asset Repository creates a new MongoDB database and registers the tenant
  2. A PosCreateTenant event is published to the distribution event hub
  3. All services receive the event and run their tenant setup:
    • Import their Construction Kit models
    • Run data migrations
    • Create MongoDB indexes
  4. Identity Service creates:
    • 10 default roles (TenantManagement, UserManagement, etc.)
    • TenantOwners group with all default roles
    • API scopes (octo_api, octo_api.read_only)
    • API resource (octoAPI) and identity resources
    • Default identity providers (Google, Microsoft — disabled; system tenant only). Child tenants receive an OctoTenant provider pointing to the parent tenant instead.

Steps

  1. Ensure you are in the system tenant context:

    octo-cli -c Config -tid "octosystem" -isu "https://localhost:5003/" -asu "https://localhost:5001/"
    octo-cli -c LogIn -i
  2. Create the tenant:

    octo-cli -c Create -tid "my-project" -db "my_project_db"
  3. Grant yourself access to the new tenant (from system tenant):

    octo-cli -c ProvisionCurrentUser -ttid "my-project"
  4. Switch to the new tenant context:

    octo-cli -c Config -tid "my-project" -isu "https://localhost:5003/"
    octo-cli -c LogIn -i
  5. Configure identity providers (optional):

    octo-cli -c AddAzureEntryIdIdentityProvider -n "Corporate Azure AD" -t "<azure-tenant-id>" -cid "<client-id>" -cs "<client-secret>" -e true
  6. Create groups and assign roles (optional):

    octo-cli -c CreateGroup -n "Operators" -rids "DashboardViewer,ReportingViewer"
  7. Import your Construction Kit model:

    octo-cli -c ImportCk -f "./my-model.yaml" -w
info

Step 3 (ProvisionCurrentUser) is critical. Without it, you cannot access the new tenant because you have no allowed_tenants claim for it.

Inspecting and Recovering Tenant Provisioning

Provisioning a tenant — during Create, and the automatic setup that runs on every service start — is a durable, self-healing process: its state is persisted in the system database, survives service restarts, and a background reconciler drives any incomplete setup to completion. Two operator commands let you inspect and, if ever needed, nudge that state.

Inspecting the lifecycle state

octo-cli -c GetTenantLifecycle -tid "my-project"

Returns the tenant's provisioning state as JSON:

  • StateCreating (setup in progress), Active (fully provisioned and usable), Deleting (deletion in progress), or Failed (setup gave up after the retry budget and needs an operator).
  • Phase, AttemptCount, LastError — how far setup progressed, how many attempts it has made, and the last error observed while the tenant was not yet Active.

A tenant with no lifecycle record (for example one created before this feature) reports "No lifecycle record found" — treat it as a normal, already-active tenant.

Recovering a stuck tenant

In the rare case a tenant is left in Creating or ends up Failed — for example if the identity service was briefly unavailable during a burst of tenant activity — re-open its setup so the reconciler completes it:

octo-cli -c ReRunTenantSetup -tid "my-project"

This resets the tenant to Creating, clears the attempt budget, and lets the background reconciler finish provisioning it. Watch it return to Active with GetTenantLifecycle.

tip

You normally never need this — setup completes on its own and self-heals after restarts. ReRunTenantSetup is a safety valve for the rare case a tenant is left half-provisioned.

Attaching an Existing Database

Attach registers an existing MongoDB database as a tenant. This is used when:

  • A database was previously detached
  • A database was created outside of OctoMesh
  • Moving a database from one OctoMesh instance to another

What Happens Automatically

  1. Asset Repository registers the existing database as a tenant
  2. Unlike create, attach does not trigger full initialization — the database is assumed to be already set up

Steps

  1. From the system tenant context:

    octo-cli -c Config -tid "octosystem" -isu "https://localhost:5003/"
    octo-cli -c LogIn -i
  2. Attach the database:

    octo-cli -c Attach -tid "restored-tenant" -db "existing_database_name"
  3. Clear the tenant cache (forces all services to re-initialize):

    octo-cli -c ClearCache -tid "restored-tenant"
  4. Grant yourself access (if not already present):

    octo-cli -c ProvisionCurrentUser -ttid "restored-tenant"
warning

If you attach a database from a different OctoMesh installation, you may need to update the system CK model:

octo-cli -c UpdateSystemCkModel -tid "restored-tenant"

Restoring from a Backup

Restoring recovers a tenant's data from a backup file. The backup includes all MongoDB data (CK models, runtime entities, identity data).

Important Considerations

  • The restore operation overwrites the target database
  • You must create or attach the tenant first
  • After restore, you need to clear the cache so services pick up the restored data
  • If the backup came from a different OctoMesh version, CK model migrations may run on first access
  • Identity data (users, roles, groups, providers) is included in the backup

Steps

  1. From the system tenant context:

    octo-cli -c Config -tid "octosystem" -isu "https://localhost:5003/"
    octo-cli -c LogIn -i
  2. Create the tenant first (sets up infrastructure):

    octo-cli -c Create -tid "restored-tenant" -db "restored_tenant_db"
  3. Grant yourself access before restore (identity data will be overwritten):

    octo-cli -c ProvisionCurrentUser -ttid "restored-tenant"
  4. Restore from backup (overwrites the database created in step 2):

    octo-cli -c Restore -tid "restored-tenant" -db "restored_tenant_db" -f "./backup.tar.gz" -w
  5. Clear tenant cache (critical — services must reload the restored data):

    octo-cli -c ClearCache -tid "restored-tenant"
  6. Re-provision yourself (restore may have overwritten your mapping):

    octo-cli -c ProvisionCurrentUser -ttid "restored-tenant"
caution

If the backup's original database name differs from the target, specify the old name:

octo-cli -c Restore -tid "restored-tenant" -db "new_database_name" -f "./backup.tar.gz" -oldDb "original_database_name" -w

Restore from a Different OctoMesh Instance

When restoring from a backup taken on a different OctoMesh installation:

# After the standard restore steps above:

# Update system CK model to current version
octo-cli -c UpdateSystemCkModel -tid "restored-tenant"

# Clear cache again
octo-cli -c ClearCache -tid "restored-tenant"

# Verify identity providers are correct (may need reconfiguration)
octo-cli -c Config -tid "restored-tenant" -isu "https://localhost:5003/"
octo-cli -c LogIn -i
octo-cli -c GetIdentityProviders

Creating a Backup

# From the system tenant context with Bot Services configured
octo-cli -c Config -tid "octosystem" -isu "https://localhost:5003/" -bsu "https://localhost:5009/"
octo-cli -c LogIn -i

# Dump the tenant
octo-cli -c Dump -tid "my-project" -f "./my-project-backup.tar.gz"

The backup is created as a background job. The CLI waits for completion and downloads the file.

Deleting a Tenant

danger

Deleting a tenant permanently removes the MongoDB database and all its data. This action cannot be undone.

octo-cli -c Delete -tid "my-project"
info

Delete followed immediately by a new Create of the same tenant id (for example when replacing a demo tenant) is safe: while the previous deletion is still completing its database drop, the Create returns a retryable "deletion still in progress, retry later" (HTTP 409) instead of a confusing error — simply retry and it succeeds once the drop finishes.

Cleaning a Tenant

Cleaning resets a tenant to factory defaults by removing all CK models (except system) and all runtime entities, while keeping the database:

octo-cli -c Clean -tid "my-project"

Summary of Operations

OperationCreates DBInitializes ConfigPreserves DataUse When
CreateYesYesN/ASetting up a fresh tenant
AttachNoNoYesRe-registering an existing database
RestoreNo (needs Create first)OverwrittenBackup dataRecovering from a backup
CleanNoPartial resetNoResetting to factory defaults
DeleteDrops DBN/ANoPermanently removing a tenant