node package manager
Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »


Multi Tenancy Plugin for Mongoose

Subscribe to Release Notes Get Help on Gitter Build Status Coverage Status npm version GitHub license


There are 3 ways of implementing multi-tenancy in mongoDB:

  • on document level (cheap and easy to administer but only secured by app logic)
  • on collection level (not recommended, due to breaking mongoDB concepts)
  • on database level (very flexible and secure but expensive)


The mongo tenant is a highly configurable mongoose plugin solving multi-tenancy problems on document level (for now...). It creates a tenant-reference field and takes care of unique indexes. Also it provides access to tenant-bound model-classes, that prohibit the exploid of the given tenant scope. Last but not least the "MAGIC" can be disabled so that shipping of the same code in single- and multi-tenancy environment (on premis vs. cloud hosted) is a question of a single line of config.


Tested with mongoose from version >= 4.3.0.



$ npm install --save mongo-tenant


Register the plugin on the relevant mongoose schema.

  mongoose = require('mongoose'),
  mongoTenant = require('mongo-tenant');
let MySchema = new mongoose.Schema({});
let MyModel = mongoose.model('MyModel', MySchema);

Retrieve the model in tenant scope with static byTenant method. This will return a new model subclass that has special tenant-scope guards. It has the exactly same interface as any other mongoose model but prevents the access to other tenant scopes.

let MyTenantBoundModel = MyModel.byTenant('some-tenant-id');
(new MyTenantBoundModel()).getTenantId() === 'some-tenant-id'; // true
// silently ignore other tenant scope
(new MyTenantBoundModel({
  tenantId: 'some-other-tenant-id'
})).getTenantId() === 'some-tenant-id'; // true

You can check for tenant context of a model class or instance by checking the hasTenantContext property. If this is truthy you may want to retrieve the bound tenant scope with getTenantId() method.

// With enabled mongo-tenant on a schema, all tenant bound models
// and there instances provide the hasTenantContext flag
if (SomeModelClassOrInstance.hasTenantContext) {
  let tenantId = SomeModelClassOrInstance.getTenantId();


The mongo-tenant takes care of the tenant-reference field, so that you will be able to use your existing schema definitions and just plugin the mongo-tenant without changing a single line of schema definition.

But under the hood the mongo-tenant creates an indexed field (tenantId by default) and includes this in all defined unique indexes. So by default, all unique fields (and compound indexes) are unique for a single tenant id.

You may have use-cases where you want to archive global uniqueness. To skip the automatic unique key extension of mongo-tenant for a specific index you can set the preserveUniqueKey config option to true.

let MySchema = new mongoose.Schema({
  someField: {
    unique: true,
    preserveUniqueKey: true
  anotherField: String,
  yetAnotherField: String
  anotherField: 1,
  yetAnotherField: 1
}, {
  unique: true,
  preserveUniqueKey: true


The mongo tenant works out of the box, so all config options are optional. But you have the ability to adjust the behavior and api of the mongo tenant to your needs.

let config = {
   * Whether the mongo tenant plugin MAGIC is enabled. Default: true
  enabled: false,
   * The name of the tenant id field. Default: tenantId
  tenantIdKey: 'customerId',
   * The type of the tenant id field. Default: String
  tenantIdType: Number,
   * The name of the tenant id getter method. Default: getTenantId
  tenantIdGetter: 'getCustomerId',
   * The name of the tenant bound model getter method. Default: byTenant
  accessorMethod: 'byCustomer',
   * Enforce tenantId field to be set. Default: false
   * NOTE: this option will become enabled by default in mongo-tenant@2.0
  requireTenantId: true
SomeSchema.plugin(mongoTenant, config);

Running Tests

Some tests rely on a running mongoDB and by default the tests are performed against 'mongodb://localhost/mongo-tenant-test'. The tests can also be run against a custom mongoDB by passing the custom connection string to MONGO_URI environment variable.

# perform jshint on sources and tests 
$ npm run hint
# run the tests and gather coverage report 
$ npm run test-and-cover
# run tests with custom mongoDB uri 
$ MONGO_URI='mongodb://' npm run test-and-cover


The files in this archive are released under MIT license. You can find a copy of this license in LICENSE.