> ## Documentation Index
> Fetch the complete documentation index at: https://developers.resistant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# How to use Tenant Management in practice

> Recommended operating models for provisioning tenants and tenant applications: scripted automation vs an internal provisioning service.

Tenant Management is a **control-plane API** intended for provisioning and lifecycle management of tenants and tenant applications (OAuth2 M2M clients). Partners typically use it in one of two ways:

1. **On-demand automation (scripts / CI jobs)**
2. **An internal provisioning service integrated into your tooling**

This page explains both models and when to use each.

***

## What Tenant Management is (and isn’t)

Tenant Management API is used to:

* create/list/delete **tenants**
* create/list/delete **tenant applications** (region/cell-specific OAuth2 clients)

It is **not** used for document submission or result retrieval. Documents API calls must use credentials for a **tenant application** (data plane). You do not pass `tenant_id` to Documents API — the tenant is inferred from the tenant application credentials used to obtain the token.

***

## Model A — On-demand scripts (simple, common)

Use a script when provisioning is **infrequent** or handled by engineering/ops.

**Typical pattern**

* A CLI/script (or CI job) uses **organization-level credentials** to:
  1. create a tenant (one tenant per downstream customer)
  2. create one or more tenant applications (per required cell/region)
  3. store the returned credentials securely (or hand them off to your secrets manager)

**Best for**

* early pilots / PoCs
* low tenant churn
* teams that want the least operational surface area

**Watch-outs**

* avoid storing org-level credentials on laptops
* ensure provisioning is auditable (log who/why/when)
* avoid manual copy/paste of secrets where possible

***

## Model B — Internal provisioning service (recommended at scale)

Some partners build a small backend service that exposes “Create tenant” to internal users (e.g., Customer Success, Account Managers) via a UI or internal workflow tool.

**Typical pattern**

* Your internal tool calls your provisioning service (not Resistant AI directly).
* The provisioning service uses **org-level credentials** to create tenants and tenant applications.
* The service stores outcomes in your **system-of-record** (admin DB / CRM) and stores sensitive material in a secrets manager.

**Best for**

* high volume onboarding
* delegated operations (non-engineers initiate provisioning)
* standardized workflows and governance

**Recommended controls**

* **RBAC**: only approved internal roles can trigger tenant changes
* **Approval flow** (optional): for production tenants, require a second approver
* **Idempotency**: prevent double-creation (e.g., if a user clicks twice)
* **Audit logging**: record actor, timestamp, request parameters, response IDs (`tenant_id`, `application_id`, `client_id`)
* **Secrets handling**
  * if using client secrets, store them immediately and never log them
  * if using JWT client assertion (private key), keep the private key in a secrets manager and reuse across deployments

***

## Region/cell decisions: how many tenant applications?

Tenant applications are **cell/region-specific**. Create:

* **one tenant application per cell** you need to process documents in (most common), or
* multiple applications per cell if you need operational separation (e.g., key rotation, separate internal environments).

***

## Store tenant metadata (strongly recommended)

A common operational failure mode is creating tenants but not storing the identifiers and URLs anywhere internally. This makes it hard for support, operations, and analysts to know:

* which **tenant\_id** to reference,
* which **Web UI URL** to use for deep links,
* which **cells** are enabled for a given downstream customer.

### Minimum fields to persist (system-of-record)

Store these values immediately after provisioning:

* `tenant_id`
* tenant name (and your downstream customer identifier)
* enabled cells (e.g., `["eu-1", "us-1"]`)
* Web UI base URL(s) per stage/cell (or the hostname pattern + chosen cell)
* tenant applications per cell:
  * `application_id`, `client_id`, auth method (secret vs JWT)
  * created\_at, rotated\_at (if applicable)
* internal owner / audit fields:
  * created\_by, created\_at, status (active/deprecated/deleted)

<Tip>
  When filing tickets with Resistant AI, always include: **stage**, **cell**, and **tenant\_id**. This prevents “wrong environment” investigations and speeds up support.
</Tip>

***

## Lifecycle management (don’t ignore deletions)

Treat tenants as lifecycle-managed resources:

* create tenants only for real downstream customers
* delete tenants you no longer need to reduce sprawl and simplify access governance

<Note>
  To delete a tenant, you must delete all tenant applications inside it first.
</Note>

***

## Common recommendation

If you’re unsure where to start:

* Start with **Model A (scripts)** for your first 5–10 tenants.
* Move to **Model B (internal provisioning service)** once onboarding becomes frequent, delegated, or needs stronger audit/RBAC controls.
