SaaSを題材にしたオントロジーを作ってみようシリーズ #1 テナント

SaaSを題材にしたオントロジーを作ってみようシリーズ #1 テナント

0. このシリーズの目的

昨今、セマンティックレイヤー・オントロジーなどの記事がそこそこ盛り上がっている気がします。生成AIの時代になってきて、どちらも重要かつ実用的になってきたからかと思います。

しかし!いざ、オントロジーをやってみよう!と思っても、かなり内容が難しく、結局どうして良いのかわからない、これで正しいのかわからない、などハマりがちかと思います。少なくともぼくはハマりまくってます。

そこで!実際に自分たちが常に触れている、「B2B SaaS」を題材にしてオントロジーを作ってみて、使ってみて、理解を深めよう!というテーマで連載をしていきたいと思います。だいたい、10回くらいでまとめられればと思っておりますが、もっと多くなってしまうかもしれません。。。

そして、この連載が終わるころには、「SaaSっていったら、ベースとしてのオントロジーってこれだろ」っていうのがそこそこできているはずです。はずです。それを、「SaaSオントロジーv0」と呼ぼうと思います。そのうえで、v0を実際のみなさまのSaaSに当てはめて拡張して、おのおののSaaSのv1を作って活用していこう!というコンセプトです。

現在、ある程度まで書き進めているのですが、このSaaSオントロジー構築をやっていくと、とってもSaaSの理解が深まります。なので、オントロジーに興味が無くても、ディープなSaaSの世界をよりダイブして理解したい方々にはオススメ!と言える内容にしていきたいと思いますので、ぜひご一緒にオントロジー入門してみていただけますと幸いです。

※途中で、 RDF/Turtle を利用したオントロジーを表現したファイルが出てきます。ここで、うわ!ってなった方は、 こちらの記事で RDF/Turtle とは? というのを確認してみていただければと思います!

RDF・RDFS・OWL・Turtleの違いを整理して、ファイルで理解するオントロジー入門
「オントロジーを勉強し始めたけれど、RDF、RDFS、OWL、Turtleの違いが分からない」 これは、たぶんオントロジー初心者が最初につまずきやすいポイントです。少なくとも、ぼくはこれらが出てきたときに思考が止まりました。。。なので、これらだけをザックリ解説する記事になっております。 特に混乱しやすいのが、次のような疑問です。 * RDFとOWLは別のファイル形式なのか * .ttlファイルはRDFなのかOWLなのか * ex:とは何を意味するのか * URIはどのように決めればよいのか * RDF/XMLでは、なぜURIの書き方が場所によって違うのか この記事では、社…

1. このオントロジーの目的

B2B SaaSには、業種や機能が違っていても、かなり共通した構造があります。たとえば、会計SaaS、CRM、勤怠管理、セキュリティ管理、プロジェクト管理のいずれであっても、一般的に次のような概念が登場します。

  • SaaSを利用する単位
  • SaaSにログインする人
  • 人がどの利用単位に所属しているか
  • その人に何が許可されているか
  • どのプランを契約しているか
  • SaaS上で作成・管理されるデータ

これらを、特定のSaaSに依存しない形で表現するのが、このオントロジーの目的です。

最初のバージョンでは、次の8つだけを中心概念とします。

  1. Tenant
  2. User
  3. Membership
  4. Role
  5. Permission
  6. Subscription
  7. Plan
  8. Resource

2. 全体像

classDiagram
    class Tenant {
        tenantId
        name
        status
    }

    class User {
        userId
        displayName
        status
    }

    class Membership {
        membershipId
        status
        joinedAt
    }

    class Role {
        roleId
        name
    }

    class Permission {
        permissionId
        action
    }

    class Subscription {
        subscriptionId
        status
        startedAt
        endedAt
    }

    class Plan {
        planId
        name
    }

    class Resource {
        resourceId
        resourceType
        name
    }

    User "1" --> "0..*" Membership : hasMembership
    Tenant "1" --> "0..*" Membership : hasMember
    Membership "0..*" --> "0..*" Role : assignedRole
    Role "0..*" --> "0..*" Permission : grants
    Tenant "1" --> "0..*" Subscription : hasSubscription
    Subscription "0..*" --> "1" Plan : basedOn
    Tenant "1" --> "0..*" Resource : owns
    User "0..1" --> "0..*" Resource : created

このモデルの中心は、名前のとおり Tenant です。

Tenantを中心として、

  • 誰が参加しているか
  • 誰がどの権限を持つか
  • どのプランを契約しているか
  • どの業務データを所有しているか

を表現します。


3. 最重要概念:Tenant

3.1 Tenantとは何か

Tenantは、SaaSにおける論理的な利用境界です。

Tenant
= ユーザー、権限、契約、データを分離する単位

典型的には、次のようなものがTenantになります。

  • 企業
  • 部署
  • 支店
  • プロジェクト
  • 顧客専用環境
  • 学校
  • 医療法人
  • 自治体
  • 販売代理店
  • グループ会社

重要なのは、

Tenant = 会社

とは限らないことです。

3.2 会社とTenantを同一視しない

たとえば、株式会社ABCがSaaSを利用しているとしても、Tenantの作り方には複数の可能性があります。

パターンA:会社全体で1テナント

株式会社ABC
└── Tenant ABC

パターンB:部署ごとに別テナント

株式会社ABC
├── 営業部Tenant
├── 開発部Tenant
└── 管理部Tenant

パターンC:会社と子会社で別テナント

ABCグループ
├── 株式会社ABC Tenant
├── ABC販売 Tenant
└── ABCシステムズ Tenant

したがって、Tenantは「法人」ではなく、あくまでSaaS上の利用境界として定義します。

3.3 Tenantの基本属性

Tenant
├── tenantId
├── name
├── status
├── createdAt
└── updatedAt

statusには、たとえば次の値が入ります。

active
suspended
closed

4. UserとMembershipを分離する

このオントロジーで特に重要なのが、UserとMembershipを別の概念にすることです。

4.1 Userとは何か

Userは、SaaSを利用する人、またはログイン主体です。

User
= SaaS全体で識別される利用主体

Userは通常、次のような情報を持ちます。

User
├── userId
├── displayName
├── emailAddress
├── status
├── createdAt
└── updatedAt

ただし、Userが存在するだけでは、特定のTenantに所属しているとは限りません。

4.2 Membershipとは何か

Membershipは、UserとTenantの間に存在する「所属関係」です。

Membership
= あるUserが、あるTenantに参加しているという事実

関係としては、次の形になります。

User
  ↓
Membership
  ↓
Tenant

一見すると、単純に次のようにしてもよさそうに見えます。

User belongsTo Tenant

しかし、これでは複数テナントへの所属をうまく扱えません。

4.3 同じUserが複数Tenantに所属できる

たとえば山田太郎さんが、次の2つのTenantに参加しているとします。

User: 山田太郎
├── Tenant Aでは「管理者」
└── Tenant Bでは「閲覧者」

この場合、User自体は同じですが、所属状態や役割が異なります。

graph LR
    U[User
山田太郎] M1[Membership A] M2[Membership B] T1[Tenant A] T2[Tenant B] R1[管理者Role] R2[閲覧者Role] U --> M1 U --> M2 M1 --> T1 M2 --> T2 M1 --> R1 M2 --> R2

したがって、Roleは原則としてUserに直接付けるのではなく、Membershipに付けます。

推奨:

Membership assignedRole Role

単純化しすぎたモデルでは、次のようになりがちです。

非推奨:

User hasRole Role

Userに直接Roleを付けてしまうと、「どのTenantでのRoleなのか」が分からなくなります。

4.4 Membershipの基本属性

Membership
├── membershipId
├── status
├── joinedAt
├── leftAt
└── invitationStatus

statusの例は次のとおりです。

invited
active
suspended
removed

5. RoleとPermission

5.1 Roleとは何か

Roleは、権限をまとめたものです。

Role
= Permissionの集合

たとえば、次のようなRoleが考えられます。

Tenant Administrator
Manager
Editor
Viewer
Billing Administrator

日本語では、次のような名称になるでしょう。

テナント管理者
部門管理者
編集者
閲覧者
請求管理者

5.2 Permissionとは何か

Permissionは、何らかの操作を許可する最小単位です。

Permission
= 何に対して、何をしてよいか

最初は単純に、操作を文字列で表現できます。

tenant.read
tenant.update
member.read
member.invite
member.remove
resource.read
resource.create
resource.update
resource.delete
billing.read
billing.update

たとえば「管理者Role」は、次のPermissionを持ちます。

Role: Tenant Administrator
├── tenant.read
├── tenant.update
├── member.read
├── member.invite
├── member.remove
├── resource.read
├── resource.create
├── resource.update
└── resource.delete

「閲覧者Role」は、次のようになります。

Role: Viewer
├── tenant.read
├── member.read
└── resource.read

5.3 権限判定の流れ

あるUserが操作できるかどうかは、次の順番で判定できます。

User
→ Membership
→ Role
→ Permission

たとえば、山田太郎さんがTenant Aのデータを削除できるかを確認する場合は、次のように考えます。

1. 山田太郎のUserを特定する
2. Tenant Aに対するMembershipを取得する
3. Membershipに割り当てられたRoleを取得する
4. Roleが resource.delete を持っているか確認する

概念的には、次のような条件です。

UserがTenant内で操作可能
=
有効なMembershipが存在する
かつ
MembershipのRoleが必要なPermissionを持つ

5.4 Roleの種類

Roleには大きく2種類あります。

システム定義Role

SaaS提供者が最初から用意するRoleです。

Administrator
Editor
Viewer

テナント定義Role

Tenantの管理者が独自に作るRoleです。

東日本支店管理者
監査担当者
外部委託先
承認のみ可能な担当者

いまのところは、どちらも同じRoleとして扱い、必要になったら次の属性を追加します。

Role
├── roleType: system | tenant
└── definedByTenant

6. SubscriptionとPlan

6.1 Planとは何か

Planは、SaaS提供者が定義する商品・提供条件です。

Plan
= SaaSとして販売される標準的なサービス構成

例として、次のようなPlanがあります。

Free
Standard
Professional
Enterprise

Planには次のような情報が含まれます。

Plan
├── planId
├── name
├── description
├── status
└── billingCycle

ただし、Planは「契約そのもの」ではありません。

6.2 Subscriptionとは何か

Subscriptionは、TenantがPlanを利用しているという契約・購読関係です。

Subscription
= TenantによるPlanの利用契約

関係は次のようになります。

Tenant
→ Subscription
→ Plan

たとえば、

Tenant: 株式会社ABC
Subscription: 2026年度契約
Plan: Enterprise

という形です。

6.3 PlanとSubscriptionを分ける理由

Planに直接Tenantを接続すると契約固有の情報を表現できず、契約にはTenantごとに次の違いがあります。

  • 契約開始日
  • 契約終了日
  • 無料トライアル期間
  • 自動更新の有無
  • 個別割引
  • 契約ユーザー数
  • 契約ストレージ容量
  • 契約状態

これらはPlanではなくSubscriptionに属します。

Plan
= 標準商品

Subscription
= 個別契約

6.4 Subscriptionの基本属性

Subscription
├── subscriptionId
├── status
├── startedAt
├── endedAt
├── trialEndsAt
├── autoRenew
└── contractedQuantity

statusの例は次のとおりです。

trial
active
past_due
suspended
cancelled
expired

7. Resource

7.1 Resourceとは何か

Resourceは、そのSaaSで管理される業務データや機能上の対象です。

Resource
= TenantがSaaS上で所有・管理する対象

Resourceは抽象的な概念であり、SaaSの種類によって具体的なResourceは変わります。

SaaSの種類Resourceの例
CRM顧客、商談、活動履歴
会計SaaS仕訳、請求書、勘定科目
プロジェクト管理プロジェクト、タスク、コメント
勤怠管理勤務記録、申請、承認
セキュリティSaaSアラート、検出結果、ポリシー
ファイル共有ファイル、フォルダ
チャットチャンネル、メッセージ

共通オントロジーでは、それらをすべてResourceの一種として扱います。

Customer is-a Resource
Invoice is-a Resource
Project is-a Resource
Task is-a Resource
SecurityAlert is-a Resource

ここで注意していただきたいのは、CustomerTaskは共通オントロジーの語彙ではないということです。共通オントロジーが定義するのはResourceまでで、その下にどんなクラスを作るかは、各SaaSが自分で決めます。

# 共通オントロジー側(saas:)が定義するのはここまで
saas:Resource a owl:Class .

# 各SaaSが、自分のドメインに合わせて継承する
crm:Customer rdfs:subClassOf saas:Resource .
crm:Deal     rdfs:subClassOf saas:Resource .

つまりResourceは、各SaaSが拡張するための接続点です。第1回で決めた8つの中心概念のうち、Resourceだけが「中身が空っぽ」なのは、そこが各社の個性が入る場所だからです。

以降の説明では、9章と同じCRM SaaSを例にして、Customer(顧客)を使って進めます。

7.2 ResourceはTenantに所有される

最も重要な関係は次のものです。

Tenant ownsResource Resource

この関係は、逆向きから見ることもできます。

Resource belongsToTenant Tenant

この2つは同じ1本の関係を、どちら側から見ているかの違いでしかありません。オントロジーでは、これを逆関係として明示的に宣言しておきます。

saas:ownsResource a owl:ObjectProperty ;
    rdfs:domain saas:Tenant ;
    rdfs:range  saas:Resource .

saas:belongsToTenant a owl:ObjectProperty ;
    owl:inverseOf saas:ownsResource .

こう書いておくと、Tenant → Resourceのどちらか一方を記録するだけで、推論エンジンがもう一方を自動的に導いてくれます。「このTenantが持つResourceは?」と「このResourceの持ち主は?」の両方を、データを二重に持たずに引けるということです。

そして原則として、すべての業務データに所有Tenantが存在します。

Tenant AのUser
→ Tenant AのResourceにはアクセス可能

Tenant AのUser
→ Tenant BのResourceには原則アクセス不可

マルチテナントSaaSでは、このTenantとの関係がデータ分離の根拠になります。

なお、Resourceの中には特定のTenantに属さないもの(国コードや通貨コードなど、SaaS全体で共有されるマスターデータ)もあります。この例外の扱いは10.2で整理します。

Resourceが持つもの

Resourceの構成要素は、次の2種類に分けて考えます。

他の概念との関係として表現するもの

belongsToTenant  → どのTenantのものか
createdBy        → 誰が作ったか
クラス(型)      → 何のResourceか(Customer / Deal / Task …)

Resource自身が持つ値(リテラル)

resourceId
name
createdAt
updatedAt

「何のResourceか」を、resourceType: "Customer"のような文字列ではなくクラスで表すのがポイントです。文字列だと、それがCustomerであることをオントロジーは理解できません。クラスにしておけば、crm:Customerと書いた時点で「これはResourceでもある」と推論されますし、crm:Customerだけに成り立つルール(たとえば「顧客は必ずメールアドレスを持つ」)を後から追加できます。

この「関係にするか、値にするか」という切り分けが、次の7.3のテーマです。

7.3 tenant_idを「カラム」ではなく「関係」として表現する

データベース設計では、多くの場合、Resourceにtenant_idを持たせます。

customers
├── customer_id
├── tenant_id
├── name
└── status

tenant_idは、RDBの世界では「customersテーブルの1カラム」でしかありません。値としては"tenant-abc"という文字列やUUIDが入っているだけで、それがTenantを指していることは、アプリケーションのコードや開発者の頭の中にしか存在しません。

オントロジーでは、これをTenantという実体そのものへのリンクとして表現します。

Customer belongsToTenant Tenant

実際のデータで書くと、次のようになります。

ex:customer-xyz a crm:Customer ;
    saas:belongsToTenant ex:tenant-abc ;
    saas:createdBy ex:user-yamada ;
    saas:name "株式会社XYZ" .

saas:belongsToTenant ex:tenant-abcex:tenant-abcは、文字列ではなくex:tenant-abcというTenantの実体を指しています。だから、この1行を起点にして、そのTenantの契約情報にも、所属メンバーにも、他の所有データにも辿っていけます。

そして7.2で逆関係を宣言してあるので、Tenant側から見ることもできます。

ex:tenant-abc saas:ownsResource ex:customer-xyz
(上のトリプルから自動的に導出される)

この関係を明示すると何が嬉しいのか

tenant_idをカラムではなく関係として書くことで、次のようなことがたどれるようになります

  • 誰がデータを所有するのかex:customer-xyzex:tenant-abc → 株式会社ABCテナント
  • どの権限体系が適用されるのかex:tenant-abcのMembershipを持つUserの、そのRoleのPermissionが適用される
  • どの契約制限が適用されるのかex:tenant-abc → Subscription → Plan → そのPlanの上限値
  • どのデータ保持ポリシーが適用されるのかex:tenant-abcに紐づく保持期間ルール(第◯回で追加予定)

RDBでこれをやろうとすると、テーブルを何段もJOINするクエリを書くことになります。オントロジーでは、これらはすべて「リンクをたどる」という同じ操作になります。しかも、ex:customer-xyzcrm:Customerであり、crm:Customersaas:Resourceのサブクラスであることも宣言済みなので、「Tenant Aが所有するすべてのResource」を聞けば、CustomerDealも、あとから追加したActivityも、まとめて返ってきます。

これが、7.1でResourceを「中身が空っぽの接続点」にしておいた理由です。


8. 最小の関係一覧

このオントロジーの最小関係は、次のとおりです。

主語関係目的語意味
UserhasMembershipMembershipUserが所属関係を持つ
MembershipbelongsToUserUserMembershipの対象User
MembershipbelongsToTenantTenantMembershipの所属先
MembershipassignedRoleRole所属内でRoleを持つ
RolegrantsPermissionPermissionRoleが操作を許可する
TenanthasSubscriptionSubscriptionTenantが契約を持つ
SubscriptionbasedOnPlanPlan契約が利用するPlan
TenantownsResourceResourceTenantがデータを所有する
ResourcecreatedByUserResourceを作成したUser
ResourcebelongsToTenantTenantResourceの所属先Tenant

関係を図にすると、次のようになります。

graph TD
    Tenant[Tenant]

    Membership[Membership]
    User[User]
    Role[Role]
    Permission[Permission]

    Subscription[Subscription]
    Plan[Plan]

    Resource[Resource]

    User -->|hasMembership| Membership
    Membership -->|belongsToTenant| Tenant
    Membership -->|assignedRole| Role
    Role -->|grantsPermission| Permission

    Tenant -->|hasSubscription| Subscription
    Subscription -->|basedOnPlan| Plan

    Tenant -->|ownsResource| Resource
    Resource -->|createdBy| User


9. 具体例

9.1 登場するインスタンス

次のようなCRM SaaSを考えます。

Tenant
- 株式会社ABC

User
- 山田太郎
- 佐藤花子

Membership
- 山田太郎の株式会社ABCへの所属
- 佐藤花子の株式会社ABCへの所属

Role
- 管理者
- 営業担当者

Permission
- customer.read
- customer.create
- customer.update
- customer.delete
- member.invite

Plan
- Professional Plan

Subscription
- 株式会社ABCのProfessional契約

Resource
- 顧客「株式会社XYZ」
- 商談「基幹システム刷新案件」

関係は次のようになります。

山田太郎
→ 株式会社ABCへのMembershipを持つ
→ 管理者Roleを持つ

佐藤花子
→ 株式会社ABCへのMembershipを持つ
→ 営業担当者Roleを持つ

管理者Role
→ customer.read
→ customer.create
→ customer.update
→ customer.delete
→ member.invite

営業担当者Role
→ customer.read
→ customer.create
→ customer.update

株式会社ABC
→ Professional PlanのSubscriptionを持つ

株式会社ABC
→ 顧客「株式会社XYZ」を所有する
→ 商談「基幹システム刷新案件」を所有する

9.2 インスタンス図

graph TD
    T[株式会社ABC
Tenant] U1[山田太郎
User] U2[佐藤花子
User] M1[Membership 001] M2[Membership 002] R1[管理者
Role] R2[営業担当者
Role] S[Professional契約
Subscription] P[Professional
Plan] C[株式会社XYZ
Customer Resource] D[基幹システム刷新案件
Deal Resource] U1 --> M1 M1 --> T M1 --> R1 U2 --> M2 M2 --> T M2 --> R2 T --> S S --> P T --> C T --> D

10. 最低限のルール

オントロジーを単なる用語集で終わらせず、意味のあるモデルにするため、最低限の制約を定義します。

10.1 Membershipのルール

Membershipは、必ず1つのUserに属する。
Membershipは、必ず1つのTenantに属する。

さらに、基本的には次の組み合わせを一意にします。

User × Tenantごとに、有効なMembershipは最大1つ

同じUserが同じTenantに、重複して所属するのを防ぐためです。

10.2 Resourceのルール

Tenant固有Resourceは、必ず1つのTenantに属する。

つまり、通常の業務データについては、次を必須とします。

Resource belongsToTenant exactly 1 Tenant

ただし、SaaS全体で共有されるマスターデータは例外で、たとえば次のようなものが挙げられます。

  • 国コード
  • 通貨コード
  • SaaS提供者が定義したテンプレート
  • システム共通Role
  • システム共通Plan

などは、特定のTenantに属さないことがあります。

10.3 Subscriptionのルール

Subscriptionは、必ず1つのTenantに属する。
Subscriptionは、必ず1つのPlanを参照する。

ただし、1つのTenantが複数のSubscriptionを持つ場合もあります。

たとえば、

基本プランのSubscription
追加ストレージのSubscription
AI機能追加のSubscription
監査ログ追加のSubscription

などです。

10.4 RoleとPermissionのルール

Roleは、0個以上のPermissionを持つ。
Membershipは、0個以上のRoleを持つ。

最初は1 Membershipにつき1 Roleでも構いませんが、将来的には次のような複数Roleが必要になる可能性があります。

山田太郎
├── 営業担当者Role
├── 請求閲覧者Role
└── セキュリティ監査者Role

そのため、オントロジー上は多対多にしておく方が拡張しやすくなります。


11. RDF/Turtleによる最小表現

オントロジーとして実装する場合の、非常に単純化したTurtle表現です。

@prefix saas: <https://example.com/ontology/saas#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:  <http://www.w3.org/2002/07/owl#> .

saas:Tenant a owl:Class .
saas:User a owl:Class .
saas:Membership a owl:Class .
saas:Role a owl:Class .
saas:Permission a owl:Class .
saas:Subscription a owl:Class .
saas:Plan a owl:Class .
saas:Resource a owl:Class .

saas:belongsToUser a owl:ObjectProperty ;
    rdfs:domain saas:Membership ;
    rdfs:range saas:User .

saas:belongsToTenant a owl:ObjectProperty ;
    rdfs:domain saas:Membership ;
    rdfs:range saas:Tenant .

saas:assignedRole a owl:ObjectProperty ;
    rdfs:domain saas:Membership ;
    rdfs:range saas:Role .

saas:grantsPermission a owl:ObjectProperty ;
    rdfs:domain saas:Role ;
    rdfs:range saas:Permission .

saas:hasSubscription a owl:ObjectProperty ;
    rdfs:domain saas:Tenant ;
    rdfs:range saas:Subscription .

saas:basedOnPlan a owl:ObjectProperty ;
    rdfs:domain saas:Subscription ;
    rdfs:range saas:Plan .

saas:ownsResource a owl:ObjectProperty ;
    rdfs:domain saas:Tenant ;
    rdfs:range saas:Resource .

saas:createdBy a owl:ObjectProperty ;
    rdfs:domain saas:Resource ;
    rdfs:range saas:User .

12. 具体的なデータのTurtle表現

先ほどの株式会社ABCの例を表すと、次のようになります。

@prefix saas: <https://example.com/ontology/saas#> .
@prefix ex:   <https://example.com/data/> .

ex:tenant-abc a saas:Tenant ;
    saas:name "株式会社ABCテナント" ;
    saas:hasSubscription ex:subscription-abc-professional ;
    saas:ownsResource ex:customer-xyz .

ex:user-yamada a saas:User ;
    saas:displayName "山田太郎" .

ex:membership-yamada-abc a saas:Membership ;
    saas:belongsToUser ex:user-yamada ;
    saas:belongsToTenant ex:tenant-abc ;
    saas:assignedRole ex:role-admin .

ex:role-admin a saas:Role ;
    saas:name "テナント管理者" ;
    saas:grantsPermission
        ex:permission-customer-read,
        ex:permission-customer-create,
        ex:permission-customer-update,
        ex:permission-customer-delete .

ex:plan-professional a saas:Plan ;
    saas:name "Professional" .

ex:subscription-abc-professional a saas:Subscription ;
    saas:basedOnPlan ex:plan-professional ;
    saas:status "active" .

ex:customer-xyz a saas:Resource ;
    saas:name "株式会社XYZ" ;
    saas:resourceType "Customer" ;
    saas:createdBy ex:user-yamada .

13. このモデルで答えられる質問

オントロジーを作る目的は、単にデータを保存することではなく、意味をたどって質問に答えられるようにすることです。この最小モデルでも、次のような質問に答えられます。

Tenantに関する質問

このUserは、どのTenantに所属しているか。
このTenantには、何人のUserが参加しているか。
このTenantが所有しているResourceは何か。

権限に関する質問

このUserは、Tenant AでどのRoleを持っているか。
このUserは、顧客データを削除できるか。
member.inviteを持つMembershipはどれか。
管理者権限を持つUserは誰か。

契約に関する質問

このTenantは、どのPlanを利用しているか。
Professional Planを利用しているTenantはどれか。
契約が停止中のTenantはどれか。

Resourceに関する質問

このResourceは、どのTenantのものか。
このUserが作成したResourceは何か。
Tenant AのすべてのResourceは何か。

14. あえて含めていない概念

最初のバージョンをシンプルにするため、たとえば次の概念などはまだ入れていません。

Organization
OrganizationUnit
Workspace
Group
Team
CustomerAccount
Invoice
Payment
Entitlement
Feature
Usage
Quota
AuthenticationIdentity
APIClient
ServiceAccount
AuditEvent
Policy
DataRetentionRule
Partner
Reseller

これらは重要ですが、最初から入れるとTenant、会社、部署、Workspace、契約者などの違いが分かりにくくなるため、まずは次の骨格を固定するのがよいでしょう。

Tenant
├── Membership
│   ├── User
│   └── Role
│       └── Permission
│
├── Subscription
│   └── Plan
│
└── Resource

15. このオントロジーのポイント

このモデルで最も重要なのは、次の4点です。

15.1 Tenantは会社ではなく境界である

Tenant
= SaaS上でユーザー、権限、契約、データを分離する境界

15.2 Userと所属は別である

User
= 人またはログイン主体

Membership
= Userが特定Tenantに参加している関係

15.3 Planと契約は別である

Plan
= SaaS提供者が定義した商品

Subscription
= Tenantごとの個別契約

15.4 業務データはResourceとして抽象化する

Resource
= 各SaaS固有の業務オブジェクトの共通上位概念

16. 最終的な最小モデル

最も単純に表すと、このB2B SaaSオントロジーは次の文章に集約できます。

Tenantは、SaaSの論理的な利用境界である。

Userは、Membershipを通じてTenantに所属する。

MembershipにはRoleが割り当てられる。

RoleはPermissionを付与する。

TenantはSubscriptionを通じてPlanを利用する。

TenantはResourceを所有する。

図にすると、次の形です。

graph LR
    User --> Membership
    Membership --> Tenant
    Membership --> Role
    Role --> Permission

    Tenant --> Subscription
    Subscription --> Plan

    Tenant --> Resource

これを、B2B SaaS共通オントロジーの最初のベースとし、SaaSオントロジーv0にむけての最初のバージョン、SaaSオントロジーv.1とでも呼んでおきましょう。

第2回は、 Tenantは会社なのか? Organization/Workspace/Teamを追加して「会社・契約単位・作業空間・部署」の違いを整理する で行きたいと思います

アディオス!