Multi-tenant SaaS
Introduction
Section titled “Introduction”You will turn a single server into a multi-tenant one: the tenant comes from your identity service, each tenant gets its own skills, and chosen roles may manage agents, schedule runs and read usage. Everything is one forRoot call and a handful of environment variables.
What you need
Section titled “What you need”- Identity resolved from your own login (Sign in with your existing session). Each identity carries a
tenant. - A folder on the server’s disk for skills.
1. Turn the features on
Section titled “1. Turn the features on”import { Module } from '@nestjs/common';import { PilotooModule } from '@pilotoo/server';
import { appIdentityResolver } from './identity';
@Module({ imports: [ PilotooModule.forRoot({ env: process.env, serviceName: 'assistant', identityResolver: appIdentityResolver, identityHeaders: ['x-tenant-id'], skillLayers: { globalDir: process.env.AGENT_GLOBAL_SKILLS_DIR, tenantDir: process.env.AGENT_TENANT_SKILLS_DIR, }, configTools: { profiles: false, skills: true }, scheduleTools: true, }), ],})export class AppModule {}identityHeaderscopies those request headers to the identity resolver. Use it when your identity service picks the tenant by header. Header names are matched lower-case.skillLayersadds two skill folders (see step 2). Both fields also default to the environment variables of the same names, so you can leaveskillLayersout.configToolsgives agents tools to read and save profiles and skills. Here only skills.scheduleToolsregistersschedule_create,schedule_list,schedule_updateandschedule_delete, opt-in.
2. Lay out the skill folders
Section titled “2. Lay out the skill folders”skills/ AGENT_SKILLS_DIR shipped with your app (system layer)global-skills/ AGENT_GLOBAL_SKILLS_DIR put by hand, for every tenant, read onlytenant-skills/ acme/ AGENT_TENANT_SKILLS_DIR one folder per tenant refund-policy/SKILL.md globex/ refund-policy/SKILL.mdOn a shared name, tenant wins over global, and global over system. A tenant’s callers list, run, read and write only their own tenant folder.
3. Decide who may do what
Section titled “3. Decide who may do what”Roles come from the identity. Each variable is a comma-separated list; unset means nobody.
# Who manages agents, and (with configTools) skillsAGENT_MANAGER_ROLES=permission:assistant.manage
# Who may schedule runs as themselves, and who may also manage the whole tenant's schedules over the REST routesSCHEDULE_ROLES=permission:assistant.scheduleSCHEDULE_ADMIN_ROLES=permission:assistant.manage
# Who reads the whole tenant's usageUSAGE_ADMIN_ROLES=permission:assistant.manage
# Where the server finds its files, pinned so they do not depend on where it is installedPILOTOO_CONFIG_DIR=/srv/assistant/.pilotooAGENT_SKILLS_DIR=/srv/assistant/skillsAGENT_WORKSPACE_DIR=/srv/assistant/.workspaceAGENT_GLOBAL_SKILLS_DIR=/srv/assistant/global-skillsAGENT_TENANT_SKILLS_DIR=/srv/assistant/tenant-skillsThe role names are whatever your identity resolver returns in roles. The example uses the permission:<code> convention from the sign-in recipe.
4. Let an agent use the schedule tools
Section titled “4. Let an agent use the schedule tools”Schedule tools are opt-in, so name them in the agent.
id: plannername: Plannerdescription: Sets up recurring reports.status: activeruntime: systemPrompt: You help the user schedule recurring tasks. profileId: default tools: [schedule_create, schedule_list, schedule_update, schedule_delete] builtinTools: [] skills: [] knowledge: []presentation: {}An agent with tools: null gets neither the schedule tools nor the config tools.
How it works
Section titled “How it works”- Isolation follows the
tenantof the identity: conversations, attachments, tenant skills and usage are all keyed by it. - The schedule tools act on the caller’s own schedules only, whatever their role. A caller without a schedule role gets a “Not done” answer from the tool, not a silent no-op.
configToolswithskills: truewrites only to the caller’s tenant folder when a tenant layer exists.
Next steps
Section titled “Next steps”- Authentication: identities and roles.
- Skills and Config tools.
- Schedules: what a schedule runs and where the results go.