Cross-Tenant Worker
Run one worker daemon for all tenants with a cross-tenant API key
Cross-Tenant Worker
By default an API key belongs to exactly one tenant: the worker daemon polling /jobs/next with
that key only ever sees that tenant's configuration jobs. A cross-tenant worker key lifts that
restriction so a single daemon + Revit machine can serve the job queues of all active tenants.
How it works
- Cross-tenant API key: an API key created with
isCrossTenant: true. Only super admins can create one (POST /api-key). It still has a home tenant (the creator's organization), which applies whenever no tenant header is sent. - Queue scan across tenants: when a cross-tenant key polls
GET /jobs/next, the backend scans the house, block, and option-sales queues of all tenants and returns the highest-priority job. The job payload'stenantIdidentifies the tenant it belongs to. X-Tenant-Idheader: for every follow-up call (start/status/upload/finish/fail, project lookup,/tenants/me, blob downloads, …) the worker sends the job's tenant as anX-Tenant-Idheader. The backend validates the tenant (must exist and be active) and runs the request in that tenant's context, including tenant settings such as coordinate system, Revit template, and default Revit version.- Job dispatch: the daemon passes the job's
tenantIdto the Revit add-in over the named pipe (configure,configure-block,configure-option-sales). The add-in keeps it as the ambient job tenant and stamps all of its own API calls with the same header until the job ends.
Regular (single-tenant) keys are rejected with 403 if they send an X-Tenant-Id other than
their own tenant, and unknown or inactive tenants are rejected with 400. Every applied override
is audit-logged on the backend.
Setting it up
-
As a super admin, create a cross-tenant API key:
POST /api-key { "daysTillExpiration": 365, "name": "revit-worker-fleet", "isCrossTenant": true, "permissions": { "configuratorPermissions": ["READ_QUEUEJOBS"] } } -
Put the key in the worker machine's
~/Alpha/settings.jsonas usual (apiKey/productionApiKey/ …). No other daemon configuration is needed; thetenantIdsetting is now only a fallback for manual (non-job) runs. -
Restart the AlphaWorkerDaemon. The log line
Claimed <TYPE> job <id> (tenant=<tenantId>)confirms per-job tenant resolution is active.
Notes
- Manual runs in Revit (UI or CLI dispatch without a job) are unaffected: no job tenant is set, so calls run against the key's home tenant exactly as before.
- Revit versions per tenant still resolve per job:
project.revitVersion→ tenant default (/tenants/mewith the job's tenant) → daemon settings. - Heartbeat/registration still registers the agent under the tenant from local settings; the queue agent list shows which machine ran which job via worker events on the job itself.