| name | multitenancy |
| description | Use when implementing multitenancy in SAP CAP: @sap/cds-mtxs, MTX sidecar, tenant provisioning, tenant subscription, tenant upgrade, HDI per tenant, service-manager, extensibility, tenant lifecycle hooks, SaaS, shared tenant mode.
|
| metadata | {"category":"cap","version":"1.0.0","keywords":["@sap/cds-mtxs","MTX","tenant","SaaS","subscription","provisioning","HDI per tenant","service-manager","extensibility","tenant upgrade"],"related":{"btp-deployment":"SaaS deployment configuration","security-auth":"tenant-aware authorization","btp-service-bindings":"service-manager binding"}} |
Multitenancy — CAP Best Practices
Primary reference: https://cap.cloud.sap/docs/guides/multitenancy/
MTX Services: https://cap.cloud.sap/docs/guides/multitenancy/mtxs
Setup with @sap/cds-mtxs (built-in MTX, recommended)
npm install @sap/cds-mtxs
CDS 10: @sap/cds-mtxs is now v4.x. The old @sap/cds-mtx package and the cds migrate migration command have been removed — if you haven't migrated yet, use an older @sap/cds-mtxs v3.x to perform the migration first, then upgrade to v4.
npm install @sap/cds-mtxs
package.json:
{
"cds": {
"profile": "with-mtx-sidecar",
"requires": {
"multitenancy": true,
"extensibility": true,
"toggles": true,
"db": {
"kind": "hana-mt"
},
"auth": {
"kind": "xsuaa"
}
}
}
}
xs-security.json for multitenancy
{
"xsappname": "my-cap-app",
"tenant-mode": "shared",
"scopes": [
{ "name": "$XSAPPNAME.mtcallback", "grant-as-authority-to-apps": ["$XSAPPNAME!t*"] },
{ "name": "$XSAPPNAME.mtdeployment", "description": "Scope to deploy to tenants" }
],
"authorities": ["$ACCEPT_GRANTED_AUTHORITIES"]
}
MTX Sidecar (for larger applications)
Add a separate sidecar module in mta.yaml:
- name: my-cap-app-mtx
type: nodejs
path: mtx/sidecar
build-parameters:
builder: npm
build-result: .
parameters:
memory: 512M
requires:
- name: my-cap-app-uaa
- name: my-cap-app-registry
- name: my-cap-app-db
mtx/sidecar/package.json:
{
"name": "my-cap-app-mtx",
"dependencies": { "@sap/cds": "*", "@sap/cds-mtxs": "*" },
"cds": {
"profile": "mtx-sidecar"
}
}
Tenant lifecycle hooks
const cds = require('@sap/cds')
cds.on('mtx.tenant.provisioned', async ({ tenant }) => {
console.log(`Tenant ${tenant} has been onboarded`)
})
cds.on('mtx.tenant.deprovisioned', async ({ tenant }) => {
console.log(`Tenant ${tenant} has been offboarded`)
})
cds.on('mtx.tenant.upgraded', async ({ tenant }) => {
console.log(`Tenant ${tenant} schema upgraded`)
})
Tenant-specific configuration
async onReadConfig(req) {
const { tenant } = req
const config = await SELECT.one(TenantConfig).where({ tenant_ID: tenant })
return config
}
Never use a single global config — always filter by req.tenant.
Extensibility: tenant-specific CDS extensions
Tenants can extend the base model (if extensibility: true):
// Tenant extension (uploaded via MTX API)
extend entity Products with {
tenantField : String(100);
}
Deploy tenant extension:
cds push --to https://my-app-mtx.cfapps.eu10.hana.ondemand.com \
--user alice@tenant.example.com
Service Manager (replaces HDI containers per tenant)
- name: my-cap-app-db
type: org.cloudfoundry.managed-service
parameters:
service: service-manager
service-plan: container
CAP's hana-mt database kind auto-provisions one HDI container per tenant via Service Manager.
Local multitenancy testing
{
"cds": {
"requires": {
"multitenancy": true,
"db": { "kind": "sqlite" },
"auth": {
"kind": "mocked",
"users": {
"alice": { "tenant": "tenant-A", "roles": ["admin"] },
"bob": { "tenant": "tenant-B", "roles": ["viewer"] }
}
}
CAP creates separate in-memory SQLite DBs per tenant automatically.
Common mistakes to avoid
- ❌ Using
hdi-container instead of service-manager — hdi-container is single-tenant only
- ❌ Storing shared (cross-tenant) data in a tenant HDI container
- ❌ Hardcoding
tenant-mode: dedicated in xs-security.json for a shared SaaS app
- ❌ Forgetting
$ACCEPT_GRANTED_AUTHORITIES in xs-security.json — breaks MTX callback
- ❌ Not seeding initial data in the
mtx.tenant.provisioned hook
- ❌ Running schema upgrades manually — always use the MTX upgrade API