Resolve Customer Account question; add commercial subscription research

Record B2B SaaS subscriber tenancy and Stripe billing source notes. Resolve
the Customer Account open question: reject it as canonical, add Commercial
Record and Commercial Relationship to the Record and relationship layers, and
document Subscriber as a convenience term only.
This commit is contained in:
2026-06-21 20:35:36 +02:00
parent 1c1b5c9bc6
commit 3ccf841095
11 changed files with 345 additions and 26 deletions

View File

@@ -15,9 +15,14 @@ later explicit package is extracted.
- Separate Natural Person, Account, Profile, Credential, and Principal in
user-management schemas. Corpus confirms SCIM/LDAP use "user" for records,
Keycloak/ZITADEL for accounts.
- Model Tenant as Scope; relate explicitly to Organization, Customer, Vendor,
and Realm. ZITADEL org-as-tenant and Keycloak realm-as-namespace are common
mapping patterns.
- Model Tenant as Scope; relate explicitly to Organization, Customer role, Vendor
role, Commercial Relationship, and Realm. ZITADEL org-as-tenant and Keycloak
realm-as-namespace are common mapping patterns.
- Store Stripe Customer / CRM Account as Commercial Record; link to Tenant and
Organization via Identifier binding. Do not create a `customer_account` table
that merges billing and login semantics.
- Map Auth0/Stytch "subscriber" to Organization + Customer role + Tenant; treat
Subscriber as convenience label only.
- Store Synonymity Assertions with relation type, strength, scope, evidence,
source system, lifecycle state, and privacy classification. Never default to
destructive merge for duplicate detection.
@@ -86,6 +91,8 @@ later explicit package is extracted.
- Do not use MDM golden-record merge as default linking behavior.
- Do not collapse Realm, Tenant, and Organization into one table without
relationship modeling.
- Do not introduce `CustomerAccount` as a canonical type; use Commercial Record
for billing and Organization + Customer role for subscribing parties.
## Suggested Adapter Inventory
@@ -98,4 +105,6 @@ later explicit package is extracted.
| Cedar / Cerbos | Principal, Resource, Action, Context | Role, derived ownership |
| ActivityPub / FOAF | Actor, Profile, Following | — |
| DID / VC | Identifier, Credential, Claim | Trust relationship |
| Entity resolution | Synonymity Assertion | — |
| Entity resolution | Synonymity Assertion | — |
| Stripe / CRM billing | Commercial Record, Commercial Relationship | Subscription state |
| Auth0 / Stytch B2B | Organization, Customer role, Tenant, Membership | Account, Subscriber label |

View File

@@ -20,15 +20,35 @@ explicit Organization + Tenant + Realm mapping in downstream adapters.
### Customer Account as canonical concept
**Status:** Open — leaning toward Organization + Customer role.
**Status:** Resolved — do not add Customer Account; add Commercial Record instead.
ZITADEL and Keycloak model customer-like boundaries as Organization with tenant
semantics, not a separate account type. No corpus source defines Customer
Account as distinct from Organization actor + Customer relationship role +
Tenant scope.
**Decision:** Customer Account is not a canonical concept. The term overloads
login Account, billing customer (Stripe), CRM account (Salesforce), and B2B
subscriber organization (Auth0/Stytch).
**Decision needed:** Whether billing/commercial account records warrant a
downstream-only model or a canonical Customer Account specialization.
**Canonical pattern:**
| Source label | Canonical mapping |
| --- | --- |
| B2B subscriber / customer org (Auth0, Stytch, ZITADEL) | Organization actor + Customer Relationship role + Tenant Scope |
| Login user / member | Account + Membership Relationship |
| Stripe Customer / CRM Account | Commercial Record (Record layer) |
| Individual subscriber (no company) | Natural Person + Tenant Scope + Commercial Record |
**New concepts added (not participation roots):**
- **Commercial Record** — Record layer entity for billing/commerce system records.
- **Commercial Relationship** — typed relationship linking vendor and customer
actors, optionally referencing a Commercial Record.
**Convenience term only:** Subscriber (map like User — resolve before use).
**Citations:**
- `research/commercial-subscription/b2b-saas-subscriber-tenancy.md`
- `research/commercial-subscription/stripe-customer-billing.md`
- `research/identity-provisioning/keycloak-organizations.md`
- `research/identity-provisioning/zitadel-organizations-projects.md`
### Team modeling

View File

@@ -146,15 +146,39 @@ An organization or other actor recognized by a legal system.
## Customer
An actor in a commercial or service-consumption relationship.
A commercial role played by an actor (usually an Organization, sometimes a
Natural Person for individual subscriptions) that consumes services from a
vendor.
Customer is a relationship role, not automatically a tenant or organization.
Customer is a relationship role, not a record type and not interchangeable with
Tenant, Organization, Account, or Commercial Record.
## Vendor
An actor in a service-provider relationship.
A commercial role played by an actor (usually an Organization) that provides
services to customer actors.
Vendor is a relationship role, not automatically a tenant or organization.
Vendor is a relationship role, not a tenant, realm, or organization synonym.
## Commercial Relationship
A typed relationship connecting a vendor actor to a customer actor for a
commercial or subscription purpose within a stated scope.
May reference a Commercial Record for billing state. Does not imply membership,
authorization, or identity equivalence.
## Commercial Record
A record in a billing, CRM, or commerce system that tracks payment methods,
subscriptions, invoices, contracts, or commercial contact details for an actor
or tenant.
Examples: Stripe Customer, Salesforce Account, subscription billing profile.
Commercial Record is in the Record layer. It is not an Account (login), not an
Organization actor, and not a Customer Account. Link it to Actor, Tenant, or
Scope via Identifier binding or Commercial Relationship.
## Community
@@ -292,3 +316,19 @@ pseudonymization with separately stored re-identification keys.
`User` may be used in prose when quoting or mapping external systems, but it
should not be a canonical root concept. Resolve it to a specific canonical
concept before using it in model definitions.
## Non-Canonical Convenience Term: Subscriber
`Subscriber` (common in Auth0 B2B SaaS documentation) usually means the
organization or party holding a subscription and tenant. Resolve to Organization
+ Customer Relationship role + Tenant Scope, or to Natural Person + Tenant for
individual subscriptions. Do not model as Customer Account or Account.
## Non-Canonical Convenience Term: Customer Account
Do not use `Customer Account` as a canonical term. Resolve by layer:
- login/access → Account;
- subscribing company → Organization + Customer Relationship role;
- billing/CRM record → Commercial Record;
- isolation boundary → Tenant.

View File

@@ -78,6 +78,13 @@ dimensions (NIST IAL, AAL, FAL). Do not collapse them into a single "trust
level" on an account. Record assurance metadata on bindings, credentials, and
federation relationships where sources provide it.
## P14. Separate Commercial Records From Accounts
Billing customers (Stripe), CRM accounts (Salesforce), and login accounts are
different layers. Model billing and commerce artifacts as Commercial Records
linked to actors and tenants through Commercial Relationships — not as Customer
Accounts and not by overloading Account.
## P13. Prefer Non-Destructive Linking
Entity resolution, federation account linking, and semantic web equivalence

View File

@@ -27,6 +27,8 @@ collapsing into `user`, `group`, or `tenant`.
- Account: operational access record in a scope.
- Service Account: software-oriented account.
- Identity Record: source-specific record about an actor or account.
- Commercial Record: billing, CRM, or commerce-system record linked to an actor
or tenant (e.g., Stripe Customer).
- Profile: presentation or attribute surface.
- Persona: contextual presentation of an actor.
@@ -72,6 +74,8 @@ Core relationship classes:
- Administration: actor manages records, relationships, or configuration in a
scope.
- Trust: actor, issuer, verifier, or system relies on another for a purpose.
- Commercial: vendor actor provides services to customer actor; may reference a
Commercial Record for billing or subscription state.
- Synonymity: records or identifiers are asserted to refer to the same target
under stated evidence and scope.
@@ -127,9 +131,10 @@ to org units → `Legal Entity` as specialization or relationship when evidenced
### S04 — Vendor Tenant Serving Customer Tenants
`Organization`(vendor) + `Organization`(customer) → `Vendor`/`Customer`
relationship roles → separate `Tenant` scopes → `Trust Relationship` for
federation → `Administration Relationship` for delegated support.
`Organization`(vendor) + `Organization`(customer) → `Commercial Relationship`
(vendor/customer roles) → separate `Tenant` scopes → optional `Commercial Record`
per customer tenant (billing) → `Trust Relationship` for federation →
`Administration Relationship` for delegated support.
### S05 — Customer Organization With Delegated Administrators
@@ -203,7 +208,8 @@ cannot satisfy. Remaining ambiguities are documented in `OpenQuestions.md`:
- mandatory Synonymity Assertion field set;
- Realm vs. Tenant promotion for Keycloak-heavy mappings;
- Customer Account as separate concept vs. Organization + Customer role.
- Customer Account resolved: use Commercial Record + Commercial Relationship;
see `OpenQuestions.md`.
## Invariants

View File

@@ -49,6 +49,11 @@ The repository is focused on research and terminology. The corpus should collect
- `synonymity-assertions.md`
- `gdpr-pseudonymization.md`
### commercial-subscription
- `b2b-saas-subscriber-tenancy.md`
- `stripe-customer-billing.md`
## Source Note Template
Each source note should capture:

View File

@@ -0,0 +1,102 @@
# B2B SaaS Subscriber and Organization Tenancy
## Source Type
Product documentation and industry practice synthesis. Auth0 Organizations and
B2B SaaS multi-tenancy guidance; Stytch B2B Auth School org-tenancy model.
## Domain
B2B SaaS identity, organization tenancy, subscriber administration, and
vendor/customer delineation in IAM products.
## Why This Source Matters
IAM vendors explicitly separate the subscribing party (customer/subscriber) from
login accounts and from billing records. This source clarifies why "customer
account" overloads identity, commercial, and access semantics.
## Key Concepts
- **Subscriber**: Auth0-preferred term for the immediate B2B customer — the
party that holds a provisioned tenant and subscription.
- **Vendor**: provider of the B2B SaaS application (platform operator).
- **Organization tenancy**: architecture where organizations are first-class
entities; members are scoped to their organization.
- **Member**: end user with membership in an organization (Stytch); distinct
from platform-wide user identity.
- **Tenant / tenancy holder**: operational partition occupied by a subscriber.
- **Org discovery**: determining which organization a user authenticates into.
- **Membership control**: granting/revoking which users may access a subscriber's
tenant.
- **Identity isolation**: per-subscriber credential and IdP configuration vs.
platform-wide user population.
- **B2B2C / B2B2B variants**: additional "customer" and "consumer" layers below
the subscribing organization.
## Relevant Terminology
| Term | Source meaning |
| --- | --- |
| Subscriber | B2B customer occupying a tenant; Auth0 avoids "customer" label. |
| Vendor | SaaS platform provider. |
| Organization | First-class customer entity; "the organization is the customer" (Stytch). |
| Member | Employee or invited user within an organization. |
| Tenant | Isolation boundary for subscriber data, branding, and config. |
| Customer (informal) | Often used interchangeably with subscriber or organization. |
| User | Login identity; may belong to multiple organizations. |
| Consumer | End user in B2B2C scenarios below the subscriber org. |
## Modeling Assumptions
- **The subscribing company is modeled as an organization**, not as a user
account or billing record.
- **One human can be a member of multiple subscriber organizations** (contractors,
agencies).
- **Platform stores users globally**; membership scopes them to subscriber orgs.
- **Billing is subscription-based** but handled outside core IAM in most products.
- **Vendor administration** may cross tenant boundaries with subscriber consent;
subscriber administration does not.
- **No IAM product defines "Customer Account"** as a separate entity type.
## Identity-Canon Implications
- **Subscriber** maps to **Organization** actor in **Customer Relationship**
with vendor + **Tenant** Scope — not a canonical noun.
- **Member** maps to **Account** + **Membership Relationship** to Organization.
- **Vendor** maps to **Vendor Relationship** role on vendor Organization actor.
- Supports S04, S05 without Customer Account concept.
- Individual (B2C-style) subscriber maps to **Natural Person** + **Tenant**
Scope, still without Customer Account.
## Terminology Conflicts
- **Customer vs. Subscriber vs. Organization**: three labels for overlapping B2B
party; IAM prefers organization or subscriber.
- **Customer vs. Consumer**: B2B2C uses both; subscriber org vs. end consumer.
- **Tenant vs. Organization**: Stytch equates customer to organization; tenant
is the isolation fabric they occupy.
- **Account**: must not be used for subscriber org or billing party.
## Candidate Canonical Mappings
| B2B SaaS IAM concept | Candidate canonical concept |
| --- | --- |
| Subscriber | Organization + Customer Relationship role |
| Organization (tenant holder) | Organization + Tenant Scope |
| Member | Account + Membership Relationship |
| Vendor (platform) | Organization + Vendor Relationship role |
| Tenant | Tenant (Scope) |
| User (login) | Account |
| Consumer (B2B2C) | Natural Person or Account (context-dependent) |
## Open Questions
- None blocking Customer Account resolution. Commercial billing layer documented
separately in `stripe-customer-billing.md`.
## References
- Auth0: Demystifying Multi-Tenancy in B2B SaaS — https://auth0.com/blog/demystifying-multi-tenancy-in-b2b-saas/
- Auth0 Organizations — https://auth0.com/docs/manage-users/organizations
- Stytch: Organization tenancy — https://stytch.com/blog/organization-tenancy/

View File

@@ -0,0 +1,102 @@
# Stripe Customer and Subscription Billing
## Source Type
Product API documentation and SaaS architecture practice. Stripe Customer object
and B2B subscription billing integration patterns.
## Domain
Commercial billing, payment methods, subscriptions, and tenant-to-billing linkage
in multi-tenant SaaS.
## Why This Source Matters
Stripe's Customer object is the most widely deployed example of a **billing
customer** that is explicitly not a login account. It demonstrates why
"customer account" must be split into commercial records vs. identity records.
## Key Concepts
- **Customer (Stripe)**: billing entity with email, name, payment methods,
subscriptions, balance, and invoice settings.
- **Subscription**: recurring billing agreement tied to a Customer.
- **Payment method**: card or bank source attached to Customer for charges.
- **Metadata**: key-value pairs linking Stripe Customer to app tenant ID.
- **Delinquent**: billing health flag on Customer from invoice state.
- **Business name / individual name**: Customer may represent company or person.
- **customer_account (Stripe API)**: newer field referencing an Account object
representing a customer — explicit split from legacy Customer.
- **Webhook-driven sync**: Stripe owns payment state; app database owns business
state; webhooks bridge them.
- **Tenant mapping**: standard pattern stores `stripe_customer_id` on tenant record.
## Relevant Terminology
| Term | Source meaning |
| --- | --- |
| Customer | Stripe billing object; not authentication identity. |
| Subscription | Recurring charge agreement. |
| Invoice | Bill document; drives delinquent state. |
| Payment method | Stored payment instrument. |
| Balance | Credit or amount owed on Customer. |
| Metadata | App-defined correlation (e.g., tenant_id). |
| customer_account | Stripe Account representing customer (newer API). |
| Tenant (app) | Application isolation unit linked via metadata. |
## Modeling Assumptions
- **Billing state lives in payment provider**; app caches plan/feature access.
- **One Stripe Customer per tenant** is the common B2B pattern (not per login user).
- **B2B Customer** often has `business_name`; B2C may use `individual_name`.
- **Customer email** is billing contact, not necessarily login email.
- **Commercial identity can exist without Organization** (sole proprietor, individual
plan).
- **CRM "Account"** (Salesforce-style) follows similar commercial-record pattern.
## Identity-Canon Implications
- Stripe **Customer** maps to **Commercial Record** in Record layer — not Account,
not Customer Account, not Organization.
- Link Commercial Record to **Tenant** Scope and/or **Organization** / **Natural
Person** actor via **Commercial Relationship** or Identifier binding.
- Stripe **customer_account** field reinforces separate commercial vs. identity
account split at API level.
- **Subscription state** is Lifecycle State on Commercial Record (downstream).
- Supports S04 when billing is modeled alongside vendor/customer orgs.
## Terminology Conflicts
- **Customer (Stripe) vs. Customer (relationship role)**: same word, different
layers — billing object vs. vendor/customer commercial role.
- **Customer vs. Account**: Stripe uses "customer" and emerging "customer_account"
deliberately separate from login accounts.
- **Customer vs. Tenant**: integration stores stripe ID on tenant; not same entity.
- **CRM Account vs. Account (login)**: Salesforce Account = commercial record.
## Candidate Canonical Mappings
| Stripe / billing concept | Candidate canonical concept |
| --- | --- |
| Customer object | Commercial Record |
| Subscription | Commercial Record lifecycle / entitlement metadata |
| Payment method | Credential (payment instrument) — downstream |
| Metadata.tenant_id | Identifier binding to Tenant Scope |
| business_name | Commercial Record attribute |
| individual_name | Commercial Record attribute (person-backed) |
| customer_account (API) | Commercial Record variant / provider projection |
| Delinquent / balance | Lifecycle State on Commercial Record |
| Webhook event | Evidence Source for billing state change |
## Open Questions
- Should payment methods on Commercial Record map to Credential in canon, or
remain strictly downstream PCI-scoped artifacts?
- Does sole-proprietor billing (person-backed Commercial Record without
Organization) need a distinct pattern in scenario tests?
## References
- Stripe Customer object — https://docs.stripe.com/api/customers/object
- Stripe Billing — https://docs.stripe.com/billing
- Stripe org customer sharing — https://docs.stripe.com/get-started/account/orgs/sharing/customers-payment-methods

View File

@@ -189,5 +189,6 @@ an explicit representation path for each scenario (S01S15). All fifteen
scenarios remain representable without glossary or principle changes.
Remaining ambiguities are tracked in `OpenQuestions.md` (Realm promotion,
Customer Account concept, mandatory Synonymity Assertion fields). These affect
refinement, not scenario satisfiability.
mandatory Synonymity Assertion fields). Customer Account is resolved: use
Commercial Record for billing-side artifacts. These affect refinement, not
scenario satisfiability.

View File

@@ -53,7 +53,9 @@ Source evidence:
- ActivityPub `acct:` URI suggests account but actor is richer (`activitypub-actors-followers.md`)
- ZITADEL machine user = Service Account (`zitadel-organizations-projects.md`)
Canonical stance: Account is operational access record in a scope.
Canonical stance: Account is operational access record in a scope. Billing
records map to Commercial Record; commercial parties use Customer/Vendor roles
and Commercial Relationship.
## Conflict: Subject, Principal, Actor
@@ -199,10 +201,28 @@ Source evidence:
Canonical stance: Issuer = Scope authority + Trust Relationship; specify protocol
role when mapping.
## Conflict: Customer Account
Problem: `customer account` collapses login account, B2B subscriber organization,
Stripe billing customer, and CRM account into one product noun.
Source evidence:
- Auth0 uses Subscriber for tenant holder, not customer account (`b2b-saas-subscriber-tenancy.md`)
- Stytch: organization is the customer (`b2b-saas-subscriber-tenancy.md`)
- Stripe Customer is billing object with subscriptions, not login (`stripe-customer-billing.md`)
- ZITADEL/Keycloak org-as-tenant has no Customer Account type (`zitadel`, `keycloak` notes)
Canonical stance: **reject Customer Account** as canonical term. Resolve by layer:
- login/access → Account;
- subscribing company → Organization + Customer role + Tenant;
- billing/CRM → Commercial Record;
- vendor↔customer link → Commercial Relationship.
## Review Queue
- [ ] Decide Customer Account canonical concept — ZITADEL org-as-customer suggests
Organization + Tenant link, not separate Customer Account entity.
- [x] Customer Account — resolved; use Commercial Record + Commercial Relationship.
- [ ] Decide Realm specialization — Keycloak evidence supports Realm as Scope
specialization; promote in glossary if scenario review confirms.
- [ ] Split authz `member` relation from social Membership in downstream adapters.

View File

@@ -33,8 +33,14 @@ has incompatible meanings across source families.
| machine user | Service Account | ZITADEL | Product term for non-human org identity. |
| organization | Organization | Schema.org, Keycloak Orgs, ZITADEL, SCIM ext | Collective actor. SCIM `organization` attribute is not an Organization actor. |
| legal entity | Legal Entity | business, compliance | Organization recognized under law; separate from tenant. |
| customer | Customer | SaaS, vendor models | Commercial relationship role. ZITADEL org often plays customer tenant role. |
| vendor | Vendor | SaaS, multi-vendor | Provider role in commercial relationship. |
| customer | Customer (relationship role) | SaaS, vendor models | B2B subscriber org → Organization + Customer role + Tenant. Not Stripe Customer. |
| vendor | Vendor (relationship role) | SaaS, multi-vendor | Provider role; not realm or tenant. |
| subscriber | Organization + Customer role | Auth0 B2B SaaS | Convenience label only; not canonical. |
| stripe customer | Commercial Record | Stripe, billing | Billing object; link to Tenant via metadata. Not Account. |
| crm account | Commercial Record | Salesforce, CRM | Commercial record; not login Account. |
| customer account | Resolve by layer | billing, IAM, CRM | Not canonical — see TerminologyConflictMap. |
| commercial record | Commercial Record | Stripe, CRM, billing | Record layer; payment/subscription/commerce state. |
| commercial relationship | Commercial Relationship | vendor/customer SaaS | Vendor-to-customer typed relationship. |
| tenant | Tenant | ZITADEL org, SaaS, Keycloak (informal) | Administrative/isolation scope. Keycloak realm sometimes called tenant. |
| realm | Realm | Keycloak | Hard identity/admin namespace. Candidate Scope specialization. |
| scope | Scope | OIDC, Cerbos, OpenFGA store, proposal | Boundary for meaning, policy, or correlation. |
@@ -106,6 +112,7 @@ Terms above are grounded in backfilled notes under:
- `research/social-community-graphs/` (4 notes)
- `research/verifiable-claims/` (3 notes)
- `research/entity-resolution-privacy/` (3 notes)
- `research/commercial-subscription/` (2 notes)
## Remaining Backfill Needs