Single-Tenant Apps
Most apps are not multi-tenant. If yours serves one organisation, you do not need to configure anything for tenancy — and you can skip the Multi-Tenancy guide entirely.
This page exists because the reassurance used to live inside that guide, which is the one page a single-tenant reader would never open.
What you have to do
Section titled “What you have to do”Nothing. Multi-tenancy is off by default:
iam: multi-tenancy: enabled: false # the default — you do not need to write thisOn first startup IAM seeds one tenant and one admin user, then registers the resources your
@RequiresPermission annotations name. That is the whole tenancy story for your app.
| Default | Property | |
|---|---|---|
| Tenant name | Default |
iam.default-tenant.name |
| Tenant slug | default |
derived from the name |
| Admin email | admin@localhost |
iam.default-tenant.admin-email |
| Admin password | (none — you set it) | iam.default-tenant.admin-password |
There is deliberately no built-in admin password. Set one from the environment, or run
iam.dev-mode: true locally and IAM generates an ephemeral one and logs it at startup. A
guessable literal would be a shipped backdoor.
iam: default-tenant: name: Acme # optional — cosmetic, and sets the slug admin-password: ${IAM_ADMIN_PASSWORD} # required outside dev-modeLogging in
Section titled “Logging in”tenantSlug is optional. Omit it and IAM uses the default tenant:
curl -X POST localhost:8080/api/iam/v1/auth/login \ -H 'Content-Type: application/json' \ -d '{"email":"admin@localhost","password":"..."}'What you can ignore
Section titled “What you can ignore”Everything the Multi-Tenancy guide describes is inert while enabled is false:
- Tenant resolution — no
X-Tenant-IDheader, no subdomain parsing, notidclaim to plumb. Every request lands in the default tenant. - Isolation modes —
row-level,schemaanddatabaseare choices about separating tenants from each other. With one tenant there is nothing to separate. - Tenant provisioning —
IamTenantProvisioningis for hosts that create tenants at runtime.
What you will still see
Section titled “What you will still see”tenantId does not disappear from the API. IamUserDetails.tenantId is populated, admin
endpoints are scoped to a tenant, and service methods take one. In a single-tenant app that value
is simply always the same — the seeded default.
This is deliberate. It is what lets an app that starts single-tenant become multi-tenant later by
flipping one flag, rather than by re-modelling its data. You can pass userDetails.tenantId
through without thinking about it.
If you later need multi-tenancy
Section titled “If you later need multi-tenancy”Set iam.multi-tenancy.enabled: true and choose how tenants are identified and separated. Your
existing data stays where it is: the tenant it was seeded into becomes the first of several. See
the Multi-Tenancy & Isolation guide.