Dev.Chan64's Blog

Go Home
Show Cover Slide Show Cover Slide

gpt-4-turbo has translated this article into English.


Data Isolation/Tenant Hierarchy/Role Inheritance/Authorization Model

This document is a design note intended to explain why we considered data isolation (multi-tenant separation), user permission model (RBAC/ABAC), and tenant and role inheritance structure in the IoT Control SaaS.

This is not a document to record the completed design, but a document that organizes how the design direction was derived and the remaining unresolved tasks.


1. Starting Point: Why Consider Such a Complex Structure?

The IoT Control SaaS operates equipment/users/data from multiple customers on a single platform simultaneously. This involves the following conflicting requirements:

  1. Data between customers must be completely separated.
  2. There is a parent-child organizational structure within the same customer.

Therefore, the concept of a single tenant alone could not meet the actual operational requirements.

This naturally led to the following concepts:

As a result, many ideas were borrowed from the directory structure of the PC filesystem + Windows ACL inheritance model.


2. Data is Designed Around the “Document”

IoT equipment/recipes/settings/diagnostics/logs all have tree structure characteristics. However, if a single document has an overly deep and complex tree, it:

To solve this, we established the following principles:

Document Principle

This approach prevents data mixing between tenants while enabling flexible expansion at the document level.


3. Tenant is Viewed as a “Tree” Structure

It is natural to manage tenants in a tree structure, similar to PC directories.

Example:

/root
/root/BrandA
/root/BrandA/Shop01
/root/BrandA/Shop02

This structure naturally provides the following functions:

Example of Tenant Structure

tenantId
parentTenantId
path             // materialized path
type             // organization type (e.g., HQ, branch, etc.)
attributes       // attributes for ABAC

This structure is scalable and intuitive in operations, reporting, and UI.


4. Roles are Designed Similarly to “Object Inheritance”

In the field, roles have more significance than just simple tags.

Example:

For this, we applied a parent-child inheritance structure to Role.

Role
- roleId
- parentRoleId
- permissions[]

This allows common permissions to be elevated to the parent role, with additional permissions only extended to the child.

A realistic inheritance depth is 1-2 levels, considering operational complexity.


5. Introducing the “Scope” Concept to UserRole

Like Windows directory permissions, the scope of the role is specified.

UserRole
- userId
- roleId
- scopeTenantId   // reference tenant
- scopeType       // EXACT | WITH_DESCENDANTS

Example:

This meets the requirements of hierarchical tenant + role inheritance + data isolation.


6. Authorization Handling: Do Not Traverse Graphs at Request Time

If the tenant tree and role inheritance relationship are traversed per request, performance would significantly degrade.

The core principle is as follows:

All calculations are completed at the time of login or tenant switch.

The procedure is as follows:

  1. Query all roles a user has in a specific tenant
  2. Unfold (flatten) the inheritance structure of these roles to form a complete set of permissions
  3. Integrate these permissions into a Set
  4. Store in cache or token

At request time, simply check the following:

effectivePermissions.contains(permissionKey)

This method provides consistent fast authorization performance even in complex RBAC structures.


7. Why Choose This Design?

This structure is not to showcase a complex architecture. Rather, it is the form naturally demanded by the domain-specific requirements of IoT Control SaaS.

Requirements ↔ Structure Correspondence Table

Requirement Solution via Structure
Complete data isolation between customers Document isolation based on tenantId
HQ–branch structure Tenant hierarchy (Tree)
Differential roles Role inheritance
Control of sub-organizations by superior organization UserRole scope = WITH_DESCENDANTS
Fast authorization judgment effectivePermissions caching
Document-based scalability Schema-based Document model

Ultimately, this design is derived from the intersection of domain demands/data model constraints/operational realities.


8. Remaining Challenges (Unresolved Issues)

8.1 Defining the Scope of Tenant Inheritance

8.2 Limiting the Depth of Role Inheritance

8.3 Scope of ABAC Application

8.4 Strategy for Invalidating effectivePermissions

8.5 Cross-tenant Reference Policy


9. Conclusion: Meaning of the Design Note

This document is not a completed architecture document, but a memo and directional document that records why such a structure was considered, how to simplify the essential problems of the domain, and what remaining challenges exist.

In IoT Control SaaS, a multi-tenant structure, hierarchical organization, permission model, and document-based data model are inevitably required. The current design is an initial form that meets these requirements, and it also lays the groundwork for future scalability.


Part 2. Designing Data Isolation and Authorization for an IoT SaaS

This section is not just a theoretical model. It is a record of a multi-tenancy and authorization structure that was exercised while building and operating an actual IoT monitoring SaaS.

The current version has the following characteristics:

So far, this model has been operated and validated in small multi-tenant environments with a limited number of devices.

The rest of this section explains, using that current operating version as a baseline,


1. Overview

This document explains how multi-tenancy and authorization can be designed and implemented in an IoT SaaS platform. The approach presented here is based on tested operational experience and reflects an attempt to unify tenant structure, a document-centered data model, a role/permission system, and IoT device mapping into one coherent structure.

It centers on three goals:

  1. Complete isolation by customer or organization
    Each tenant must own an independent data space, and data from different tenants must never mix or leak.

  2. A flexible document-centered model
    Device state, settings, profiles, recipes, and user logs should all be manageable as documents, while schemas provide structural stability and validation.

  3. A scalable authorization model
    Even as the number of tenants and users increases, authorization must remain cheap enough to evaluate, while still expressing complex SaaS operational scenarios through roles and permissions.

Together, that means the structure aims to go beyond simple RBAC and become an architecture for domain isolation and authorization that covers tenant hierarchy, document modeling, and IoT device routing in one system.

The following sections explain the flow of requirements → domain model → isolation strategy → authorization model → operating scenarios → scalability structure.


1.5 The Concept of a Tenant

In this document, the word tenant refers to a logical unit of data partitioning defined so that organizational data can be separated clearly.

At a basic level, a tenant exists for the following reasons:

Why view a tenant like a filesystem directory?

This design defines tenant structure in terms that resemble a filesystem directory tree for three reasons.

  1. Clarity of isolation
    • Just as files in different directories do not mix, each tenant remains separate from every other tenant.
  2. Scalability and intuition
    • When organizations have parent-child structure, expressing them with paths such as /root/organizationA/branch001 provides both structural consistency and intuitive understanding.
  3. Simple policy and inheritance modeling
    • A tree structure makes it easy to describe “an upper organization can monitor a lower organization” using a scope such as WITH_DESCENDANTS.

What information does a tenant contain?

A tenant includes properties such as:

Why tenants matter so much in this document

Most of the design starts from the following principles:

That makes the tenant both the basic unit of data isolation and one of the main axes of the authorization model.


2. Requirements

To design data isolation and authorization for an IoT monitoring SaaS, the required behavior must first be defined in both functional and non-functional terms.

2.1 Functional Requirements

1) Independent management by tenant

2) User–Tenant–Role structure

3) Document access control

4) Device-level access control

5) Support for upper/lower organization structure

2.2 Non-Functional Requirements

1) Authorization performance

2) Scalability

3) Stability under model change

4) Correct tenant routing for IoT data


3. Domain Model

The IoT SaaS isolation structure is built by combining multiple entities such as Document, Schema, Tenant, User, Role, and Permission. This section defines the core domain model and explains how each part contributes to isolation and authorization.


3.1 Document Model

Most data in this design is stored as a document. A document acts as the common unit for things like device state, recipes, profiles, logs, and settings.

Common properties of a document

Every document includes:

Design principles

  1. A document can only be created if a schema exists for it.
    Arbitrary untyped structures are not allowed.

  2. Document references are always expressed as (schemaName, refId).
    Path-based or implicit tree references are not allowed, and dependencies remain explicit.

  3. Tree structure should be composed by splitting documents when necessary.
    Deep trees should not be embedded into a single document if they can be expressed as a loose multi-document structure.

This keeps the model strongly structured while still remaining flexible.


3.2 Schema and DTO

A schema is the contract that defines the structure, data types, and semantic constraints of a document.

Components of a schema

Each schema includes:

Schema change and version management

Schemas evolve over time. The following principles apply:


3.3 Tenant and Hierarchical Structure

A tenant is the basic unit of organization-level data isolation, and it can expand into a hierarchical tree like a filesystem directory.

Core properties of a tenant

Principles of data isolation

  1. If tenantId differs, the data is always separated.
    This applies to documents, devices, configuration, and logs.

  2. Parent-child relationship does not automatically grant access.
    Access is always controlled by role + scope.

  3. Cross-tenant references are allowed only explicitly.
    For example, a parent organization might expose a common profile document to child organizations in read-only form.

This structure preserves a simple isolation model while allowing hierarchical monitoring to be added flexibly.


3.4 User, Role, and Permission

At the center of authorization sits the relationship among users, roles, and permissions.

User

Role

A role is a bundle of actions.

Examples:

Permission

A permission is defined through:

Examples:

Role–Permission relationship

User–Role assignment

When assigning a role to a user, the stored structure includes:

This lets one user hold different permissions depending on organization and scope.


4. Data Isolation Strategy

The most important goal in a multi-tenant IoT SaaS is ensuring that data from different organizations never mixes. This section defines isolation at the tenant level, the rules for references between documents, and the strategy for keeping device, log, and status data safely partitioned.


4.1 Tenant-Level Isolation

The core isolation rules are as follows.

1) Every piece of data must belong to exactly one tenant

That includes:

Every one of these entities must contain tenantId at creation time.

2) Device-to-tenant mapping follows a single rule

Each device belongs to one tenantId. All device data goes through the following sequence:

  1. Read the tenantId contained in the incoming packet
  2. Verify that the tenant is valid
  3. Store the data only in the storage area for that tenant

This prevents data from being routed into the wrong tenant in the first place.

3) Storage choices: logical isolation vs physical isolation

Tenant-based data isolation can expand into two scenarios:

This document assumes logical isolation by default while keeping the tenantId-based model consistent enough to later support physical separation.


4.2 Reference Rules Between Documents

When a document-centered data model is used, one document often needs to reference another. The following rules keep that from breaking tenant isolation.

1) Default rule: only same-tenant references are allowed

2) Exception: limited references in parent/child organization structures

In some operating scenarios, a parent organization must provide a common document, such as a shared recipe or shared device setting, to child organizations.

That can be allowed only if:

This keeps operational flexibility without abandoning isolation.

3) References must always use (schemaName, refId)

Path expressions, composite keys, and embedded tree references are not used.


5. Authorization Model

To complete tenant-based isolation, the system needs an authorization structure that decides whether access should be allowed at all. This section defines that model using User, Role, Permission, and Scope.

5.1 Basic Principles

Authorization is evaluated using three core elements:

  1. userId
    • The identity of the user making the request
  2. tenantId (contextTenantId)
    • The tenant context the user is trying to access, such as the tenant selected in the monitoring UI
  3. permissionKey
    • A key representing the requested action, for example:
      • DOCUMENT:READ:SCHEMA=BREW_PROFILE
      • DEVICE:COMMAND:SCOPE=OWNED_BY_TENANT

Tenant-based access principle

Core concept of scope

When assigning a role, scope defines in which tenant range the role can be exercised.

This allows simple support for:

5.2 Effective Permissions Calculation

To process authorization in close to O(1), the system precalculates a user’s role-derived permission set.

What are effective permissions?

They are the final set of permissions the user can actually exercise in a specific tenant context.

Example:
If user U has:

then the final authorization set in tenant T is the merged permission set from those roles and any inherited parent roles.

Calculation rules

Effective permissions are calculated by combining every applicable UserRole that satisfies:

  1. scopeType = EXACT
    • include when scopeTenantId === contextTenantId
  2. scopeType = WITH_DESCENDANTS
    • include when contextTenantId is a descendant of scopeTenantId
  3. collect every permission from each included role

  4. flatten parent-role inheritance if present

When is it calculated?

Actual request flow

  1. The client or server identifies userId and tenantId from headers or context.
  2. The authorization service reads the cached effectivePermissions(userId, tenantId).
  3. It checks whether the requested permissionKey is present.
  4. If present, Allow. Otherwise, Deny.

Performance benefit


6. Authorization Service Design

To operate the permission and isolation model safely in a real system, a dedicated authorization service is needed. It manages user-tenant-role relationships and provides fast authorization decisions to the rest of the platform.

6.1 Roles and Responsibilities

The authorization service handles the following work.

1) Reading user–tenant–role relationships

2) Managing Role and Permission definitions

3) Verifying scope on top of the tenant hierarchy

4) Calculating and caching effective permissions

5) Serving authorization checks for external services

Web apps, API servers, and IoT gateways can ask questions such as:

6.2 Major API Examples

The authorization service can expose APIs through REST, gRPC, or other RPC mechanisms.

POST /authz/evaluate

Evaluates whether a specific permission is allowed.

Input

{
  "userId": "user-123",
  "tenantId": "tenant-A1",
  "permissionKey": "DOCUMENT:READ:SCHEMA=BREW_PROFILE"
}

Output

{ "allow": true }

GET /authz/effective-permissions

Returns the full permission set the user can exercise in a given tenant context.

Example input

/authz/effective-permissions?userId=user-123&tenantId=tenant-A1

Output

{
  "permissions": [
    "DOCUMENT:READ:SCHEMA=BREW_PROFILE",
    "DOCUMENT:WRITE:SCHEMA=DEVICE_CONFIG",
    "DEVICE:COMMAND:SCOPE=OWNED_BY_TENANT"
  ]
}

POST /authz/roles

Creates a new role or updates an existing one.

Example input

{
  "roleId": "TenantOperator",
  "permissions": [
    "DOCUMENT:READ:SCHEMA=BREW_PROFILE",
    "DOCUMENT:WRITE:SCHEMA=BREW_PROFILE",
    "DEVICE:COMMAND:SCOPE=OWNED_BY_TENANT"
  ],
  "parentRoleId": "TenantViewer"
}

POST /authz/user-roles

Assigns a role to a user.

Example input

{
  "userId": "user-123",
  "roleId": "TenantOperator",
  "scopeTenantId": "tenant-A1",
  "scopeType": "WITH_DESCENDANTS"
}

This is one of the core APIs for enabling parent organizations to monitor descendants.

6.3 Cache Strategy

Authorization latency directly affects the response time and scalability of the entire service. For that reason, the strategy for caching effectivePermissions(userId, tenantId) must be explicit.

1) Cache storage location

One or both of the following can be used:

2) Cache key structure

Cache keys are based on user and tenant context:

effective:{userId}:{tenantId}

Example:

effective:user-123:tenant-A1

This cleanly separates the fact that the same user may have different effective permissions in different tenant contexts.

3) Cache invalidation

When permission, role, or tenant information changes, cached results become invalid and must be recalculated.

The following events require invalidation:

Possible invalidation scopes include:

4) Version-based cache validation

In larger environments, cache invalidation can also be supported through versioning.

Permission version strategy

Benefits:

5) TTL options

TTL may optionally be used.

This document recommends explicit invalidation plus version validation as the primary strategy.


7. Example IoT Monitoring Scenarios

The tenant structure, document model, and authorization model described so far need to be understandable in concrete operating terms. This section walks through three representative scenarios.

7.1 Device–Tenant Mapping

Every IoT device (deviceId) must belong to exactly one tenant. That is the core assumption behind safe data isolation.

1) Assign a tenant when the device is registered

A device is registered with information such as:

Whenever the device connects or sends data, the server validates the included tenantId and confirms that the device belongs to the expected tenant.

2) Validate tenant at data-ingestion time

The following data must all be validated and stored based on tenantId at receipt time:

The server determines storage destination based on tenantId and never writes the data into another tenant’s area.

3) Prevent invalid tenant data

By explicitly carrying tenantId at the protocol level, the system can defend against misrouting or bad device behavior that would otherwise contaminate another tenant’s data.

7.2 Flow in the monitoring UI

What a user sees in the web or mobile monitoring UI depends entirely on the tenant the user has selected.

Overall flow

  1. User logs in
    • The system retrieves the list of tenants the user may access.
  2. A specific tenant context is activated
    • For example, if user A can access tenant-X1 and tenant-X2, choosing tenant-X2 sets contextTenantId = tenant-X2.
  3. Effective permissions are calculated or loaded
    • At login or tenant selection time, effectivePermissions(userId, contextTenantId) is read from cache.
    • If absent or invalid, it is recalculated and cached.
  4. The UI is rendered based on authorization
    • Documents without read permission are hidden.
    • Configuration pages without write access are disabled.
    • Device-control buttons are shown only if the required permission is present.
  5. Data is queried
    • The system reads devices, profiles, recipes, and logs that belong to the selected tenant.
    • The server returns data based on contextTenantId, not only on userId.
  6. Request-level authorization is enforced
    • When the user opens or edits a document, the service immediately checks the relevant permissionKey.

7.3 Parent organizations monitoring child organizations

The model supports scenarios where an upper-level organization monitors all lower-level organizations together.

Example: a parent-organization user viewing all child organizations

  1. User U in the parent organization has:

    • roleId = TenantOperator
    • scopeTenantId = parent organization
    • scopeType = WITH_DESCENDANTS
  2. User U chooses a specific child tenant in the UI.

  3. The authorization service verifies:

    • the role has WITH_DESCENDANTS,
    • and the chosen child tenant is indeed a descendant of the scope tenant using lineage or the tenant tree.
  4. If the conditions hold, the user can read documents, devices, and logs belonging to that child tenant.

Directional access rules

Benefits


8. Versioning and Scalability

In a multi-tenant IoT SaaS, both the data model and the permission structure are likely to evolve over time. Schema, roles, and tenant structure must be able to change without destroying system consistency. This section covers long-term versioning strategy and scalability considerations.

8.1 Schema Versioning

Document schemas will continue to grow and change. To keep compatibility while allowing evolution, follow the principles below.

1) Manage schemas by schemaName + schemaVersion

2) Record the schema version used when the document was created

3) Establish a migration policy when the schema changes

This preserves system consistency even when schema change is frequent.

8.2 Role / Permission Versioning

Roles and permissions also change. Features can disappear or be added, which changes both permission definitions and role composition.

  1. Prefer adding a new role definition rather than mutating the old one in place
  2. Prefer adding a new permission key rather than mutating an existing one
  3. Reassign users gradually over time
  4. Mark old roles deprecated and remove them only after a safe transition period

This reduces role collision and permission confusion during live operation.

8.3 Expansion of the Tenant Hierarchy

Operationally, the tenant tree can change in many ways:

The following principles help absorb those changes safely.

1) Keep tenant lineage(path) up to date

Whenever tenants move or merge:

2) Reinterpret WITH_DESCENDANTS using lineage automatically

If the tenant tree changes, scope validity should shift automatically through the updated lineage relationships.

3) Invalidate cache

Any tenant move or merge must invalidate cached effective-permission results.

8.4 Scalability Considerations

As the number of tenants, users, and devices grows, authorization and data access still need to remain stable.

1) Large numbers of tenants

Even if tenant hierarchy becomes deep or scales to hundreds or thousands of nodes, ancestor/descendant checks can be performed through lineage prefix comparison alone.

2) Large numbers of users

Per request, the work is bounded:

3) Large numbers of IoT devices

4) Ability to expand into physical isolation

8.5 Summary of Long-Term Operating Principles


9. Operations and Monitoring

If data isolation and authorization are to stay reliable in a multi-tenant IoT SaaS, the system must be observed continuously during operation. This section summarizes the main signals, logs, and response concerns that should be monitored.

9.1 Managing authorization-failure logs

Authorization failures are important signals for identifying bad access attempts, configuration issues, bad role assignments, or tenant-boundary problems.

1) Information that must be logged on authorization failure

These logs make it possible to determine:

2) Automatic alerting

Persistent authorization failures may indicate either a security threat or an operational misconfiguration. Alerts can be triggered for:

9.2 Audit logs for tenant/role/permission changes

Permissions and tenant structure are security-sensitive. All of the following should be audited:

1) Events that must be recorded

2) Information included in the logs

These logs are critical when tracing permission issues or responding to security events.

9.3 Cache monitoring

The stability of the effective-permissions cache is directly tied to authorization performance.

1) Metrics that should be monitored

2) Monitoring for version-based validation

Abnormal growth in those numbers usually signals heavy churn in tenant structure or permission models.

9.4 Monitoring IoT data operations

The tenant-isolation model must also be monitored at the IoT device layer.

1) Detecting bad tenant data ingress

2) Monitoring missing data and excessive traffic

9.5 Operational metrics

Problems in authorization and organizational structure can delay real business operations, so the following metrics should be monitored continuously.

1) Authorization latency

2) Impact of organizational-structure changes

3) Impact on UI and workflow

9.6 Combined operating principles


Part 3. Additional Design Philosophy and Future Work

This section exists to record more explicitly

The current model feels viable, but documenting the basis, limits, and expansion conditions behind that intuition is useful for future architecture changes and operational planning.

1. Why view tenants as directories?

The overall design grew naturally from the following analogy:

That analogy works well for the following reasons.

1.1 It makes the isolation model simple and intuitive

The rules of directory structure map cleanly to the needs of an IoT SaaS:

That fits the SaaS requirement of hierarchical monitoring combined with strict isolation.

1.2 It lets ACL-style access control be reused naturally

1.3 It lets ABAC be added only where needed

As with Windows ACLs, allowing ABAC too broadly can explode the rule set and increase operational difficulty.

For that reason, this design keeps the following principles:


2. Additional Notes on Data-Structure Choices

2.1 Why design tenant structure like a directory?

The combination of tenantId, parentTenantId, and lineage(path) satisfies the following goals:

A lineage-prefix approach keeps tenant-relationship checks close to O(1) or O(depth).

2.2 Keep role inheritance shallow

If role inheritance grows deep:

In most practical environments, shallow inheritance such as TenantViewer → TenantOperator → TenantOwner is the most realistic form.

2.3 UserRole(scope) is the key that connects the full model

By placing scopeTenantId + scopeType inside UserRole, the model can naturally express:

This is effectively the formal data-model expression of whether a directory ACL should inherit downward.


3. Authorization Flow and Performance Design

3.1 Do not traverse the graph on every request

Computing tenant hierarchy and role inheritance on every request does not scale well.

The preferred approach is:

  1. calculate everything at login time
  2. or calculate everything at tenant-switch time

Then request-time work becomes:

That keeps authorization cost effectively O(1), even in large IoT environments.

3.2 Keep ABAC as a thin layer on top of RBAC

ABAC has high expressive power, but it can also cause:

For that reason, the structure should remain:

  1. RBAC grants first-level access
  2. ABAC policy evaluates conditions
  3. the final allow/deny decision is made

4. Why It Already Works Well in Small Environments

The current structure is intuitively sound and performs well in small environments for simple reasons:

As the scale grows, the expected pressure points are:

So the current structure is valid, but the future scaling concerns are already visible.


5. Open Problems

5.1 Defining the scope of tenant inheritance

5.2 Deciding the depth of role inheritance

5.3 Strategy for invalidating authorization cache

effectivePermissions cache invalidation is one of the hardest expansion problems.

All of these can trigger invalidation, and in larger environments the invalidation cost itself can become a bottleneck.

5.4 Whether ABAC should expand further

Possible additions include:

ABAC needs to grow gradually, if at all.

5.5 Cross-tenant document-sharing policy


6. Conclusion

The following conceptual frame maps very well to IoT SaaS data isolation and authorization:

The current design already works well in small environments and has the foundation needed to scale into larger ones.

Even so, the following areas still need further refinement:

In other words, the model is a valid first form, but one that will continue to need expansion and refinement as the service grows.


Go Home
Tags: Retrospective Design Philosophy