Developer Guide
Identity and Access Management (IAM) in CrowdVision is handled exclusively by the Auth Service. Because of our Database-per-Service architecture, it is critical that user identity and organizational permissions are perfectly structured so that other services can securely authorize actions without relying on cross-database queries.
The Account is the central identity record in the system.
export interface IAccount extends Document {
name: string;
email: string;
password: string;
memberships: IDomainMembership[];
totpSecret?: string;
}Notice that an account’s organizational permissions (memberships) are embedded directly as an array of subdocuments within the Account document itself.
CrowdVision utilizes a Hierarchical Weight System to evaluate roles. Instead of explicitly defining what every single role can do, roles are assigned a numeric weight.
If a route requires a business_staff role, the system checks if the user’s role weight is greater than or equal to the required weight.
| Role Name | Internal Weight | Privileges |
|---|---|---|
| Admin | 100 | Full system control, can manage other domains. |
| Business Admin | 80 | Organization owner, can manage buildings, sensors, and generate invite codes. |
| Business Staff | 60 | |
| Standard Customer | 10 | General users/viewers. By default, all new accounts are assigned this role. |
To protect routes, developers use the requireAuthorization(requiredLevel) middleware. Because JWTs are stateless, this middleware operates entirely in memory without ever touching the MongoDB database.
flowchart TD
A[Incoming Request<br/>e.g., DELETE /twin/buildings/:domainName] --> B{Has Bearer Token?}
B -- No --> C[401 Unauthorized]
B -- Yes --> D{Verify JWT Signature}
D -- Invalid/Expired --> C
D -- Valid --> E[Extract StandardTokenPayload]
E --> F{Is domainName<br/>in params?}
F -- Yes --> G[Filter memberships to<br/>only match requested domain]
F -- No --> H[Evaluate all memberships<br/>for Global Admin]
G --> I{Does ANY candidate membership<br/>have Weight >= Required Weight?}
H --> I
I -- No --> J[403 Forbidden]
I -- Yes --> K[Allow Access]domainName)If the Express route includes domainName as a parameter (e.g., /:domainName/rooms), the middleware will filter the user’s embedded memberships and ensure their weight is sufficient only for that specific domain context.
The middleware is exceptionally smart. A user might be a business_admin in the “Main Campus” domain, but only a standard_customer in the “Engineering Lab” domain.
When a user signs up, they default to standard_customer. How do they securely get elevated to business_staff without an Admin manually intervening? CrowdVision handles this via Domain TOTP Secrets (Time-Based One-Time Passwords).