This document details organization provisioning and user onboarding structures within multi-tenant SaaS environments. Zero IDS allows isolation of customer domains, teams, and administrative roles natively.
When a customer purchases a subscription in your B2B application, call the Zero IDS administrative endpoints from your backend to set up their tenant space:
Create a separate organization bound to the customer's domain name:
curl -X POST http://localhost:3000/api/organizations \
-H "Content-Type: application/json" \
-H "X-User-ID: your-super-admin-uuid" \
-d '{
"name": "Acme Corporation",
"domain": "acme.com"
}'
Response: Returns the organization record, including the auto-generated id (UUID) representing the Tenant.
Create the customer's initial administrator, binding their profile to the newly created organization ID:
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-H "X-User-ID: your-super-admin-uuid" \
-d '{
"email": "admin@acme.com",
"password": "secureTemporaryPassword123!",
"firstName": "Alice",
"lastName": "Admin",
"organizationId": "acme-organization-uuid",
"roleNames": ["ORG_ADMIN"]
}'
The ORG_ADMIN role permits Alice to invite members, manage teams, configure 2FA enforcement, and review audit logs within the Acme Corp tenant space.
Select either a Zero-managed or client-managed invitation flow based on your SaaS requirements:
Your application calls the user creation endpoint on behalf of the organization administrator. Zero IDS automatically sends an onboarding confirmation email to the invited user:
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-H "X-User-ID: alice-org-admin-uuid" \
-d '{
"email": "bob@acme.com",
"password": "temporaryPassword123!",
"firstName": "Bob",
"lastName": "Developer",
"organizationId": "acme-organization-uuid",
"roleNames": ["MEMBER"]
}'
Your application backend generates custom onboarding links (containing invitation tokens) and sends emails via its own delivery system.
When a user clicks the invitation link, your application validates the token and redirects the user to the OIDC authorization endpoint, passing a login_hint to populate the login form:
app.get('/accept-invite', (req, res) => {
const { org_id, email, token } = req.query;
// Validate the invitation token internally
if (!isValidInviteToken(token, email)) {
return res.status(400).send("Invalid or expired invitation token.");
}
// Persist organization context in cookie storage
res.cookie('pending_invite_org', org_id, { httpOnly: true, secure: true });
// Redirect to OIDC authorization endpoint with login_hint
const zeroIdsAuthUrl = 'http://localhost:3000/oidc/auth' +
'?client_id=your_saas_client_id' +
'&redirect_uri=https://your-app.com/auth/callback' +
'&response_type=code' +
'&scope=openid profile email' +
'&login_hint=' + encodeURIComponent(email);
res.redirect(zeroIdsAuthUrl);
});