Tenants API
The tenants branch (/tenants) manages tenant lifecycle and the version-control sources a tenant's model is loaded from. Unlike the other branches it is not tenant-scoped — it operates across tenants.
Known endpoints (from TenantsController):
| Method | Path | Purpose |
|---|---|---|
GET | /tenants | List tenants. |
GET | /tenants/{id} | Get a tenant. |
POST | /tenants | Create a tenant. |
PUT | /tenants/{id} | Update a tenant. |
GET | /tenants/defaultSourceDataObject | Default source configuration. |
GET | /tenants/vcsSources | Available version-control sources. |
GET | /tenants/vcsSources/{gitSource}/repositories | Repositories for a source. |
GET | /tenants/vcsSources/{gitSource}/repositories/{repository}/branches | Branches for a repository. |
Tenant object
{
"tenantCode": "acme",
"name": "Acme Corp",
"description": "Acme's production tenant",
"logo": "https://cdn.example.com/acme-logo.png",
"generalSearchClasses": ["persons", "companies"],
"accessControlEnabled": true
}
| Field | Description |
|---|---|
tenantCode | The tenant's identifier — the {tenant} path segment every other branch is scoped by. |
name | Display name. |
description | Free text. |
logo | URI of the tenant's logo. |
generalSearchClasses | Plural REST names of the classes included in the tenant's general search. |
accessControlEnabled | Whether the tenant's model declares any access control at all. Present only on GET /tenants/{id} — see below. |
accessControlEnabled is a hint, not a permission
Read from the model's access-control index at request time rather than stored on the tenant, so it can never drift from the model it describes. It exists to let a client stop asking: with no access control configured, every capability check trivially answers yes, and a dashboard that fires one per view binding on every render can skip all of them once it knows this is false.
It is a hint about what's worth asking, never itself a permission — the server still decides every mutation regardless of what this field last said. A stale false costs a client a refused POST it could have avoided asking about, never unauthorized access.
GET /tenants/{id} — the single-tenant read a client makes once a tenant is selected — is the only place this is answered. The listing (GET /tenants) omits the field entirely rather than guessing false, because answering it there would mean loading the model of every tenant the account can reach, most of which are never opened. Treat an absent field as "keep asking," not as false — the two are different claims.
This page is a stub. Still to document: how a tenant is bound to a git repository and branch, and the VCS-source discovery flow (vcsSources, repositories, branches).