Skip to main content
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

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).

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)
When filing tickets with Resistant AI, always include: stage, cell, and tenant_id. This prevents “wrong environment” investigations and speeds up support.

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
To delete a tenant, you must delete all tenant applications inside it first.

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.