<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc [
]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="std"
     docName="draft-kushwaha-scim-tenant-resource-00"
     ipr="trust200902"
     submissionType="IETF"
     consensus="true"
     version="3">

  <front>
    <title abbrev="Tenant-Aware SCIM">SCIM Extension for Tenant-Aware Identity Provisioning</title>
    <seriesInfo name="Internet-Draft" value="draft-kushwaha-scim-tenant-resource-00"/>

    <author fullname="Saurabh Kushwaha" initials="S." surname="Kushwaha">
      <organization>Oracle</organization>
      <address>
        <postal>
          <city>Pleasanton</city>
          <region>CA</region>
          <country>United States of America</country>
        </postal>
        <email>saurabh.kushwaha@oracle.com</email>
      </address>
    </author>

    <date year="2026" month="August" day="25"/>

    <area>Security</area>
    <workgroup>SCIM</workgroup>

    <keyword>SCIM</keyword>
    <keyword>identity</keyword>
    <keyword>provisioning</keyword>
    <keyword>multi-tenancy</keyword>
    <keyword>tenant isolation</keyword>

    <abstract>
      <t>
        This document defines a System for Cross-domain Identity Management
        (SCIM) extension for tenant-aware identity provisioning. The extension
        introduces a "Tenant" resource type, tenant-membership extensions for
        the "User" and "Group" resources, a lifecycle state machine for tenants
        and memberships, tenant-scoped uniqueness discovery, a normative
        tenant-context resolution rule built around the highest-precedence
        authenticated indicator together with a stated tenant-binding invariant,
        concurrency requirements for membership mutation, tenant-aware
        filtering, and an OPTIONAL region-aware metadata profile. The extension
        is backward compatible with SCIM 2.0 and is intended for multi-tenant
        Software as a Service (SaaS), cloud identity, business-to-business
        identity, identity governance, and multi-region identity deployments.
        Scoped role and entitlement bindings are delegated to the SCIM Roles
        and Entitlements and RoleAssignment work rather than redefined here.
      </t>
    </abstract>
  </front>

  <middle>

    <!-- ===================================================== -->
    <section anchor="intro">
      <name>Introduction</name>
      <t>
        The System for Cross-domain Identity Management (SCIM) 2.0
        <xref target="RFC7643"/> <xref target="RFC7644"/> standardizes
        provisioning of identity resources between an identity provider and a
        service provider. SCIM defines "User" and "Group" resource types, an
        extension mechanism based on schema URIs, and a protocol with endpoints
        for resource discovery and lifecycle. SCIM resources are represented in
        JSON <xref target="RFC8259"/>.
      </t>
      <t>
        SCIM does not define a portable "Tenant" resource. <xref
        target="RFC7644"/>, Section 1.1 acknowledges that a service provider may
        be multi-tenant and lists deployment techniques for conveying tenant
        context (URL prefix, subdomain, HTTP header, authentication context),
        but does not specify a "Tenant" resource type, a tenant-membership
        schema, a tenant-scoped uniqueness model, a tenant lifecycle model, or a
        normative rule for resolving tenant context when more than one tenant
        indicator is present and the indicators disagree. The SCIM use cases
        <xref target="I-D.ietf-scim-use-cases-reloaded"/> describe multi-tenant
        deployment topologies but likewise do not define an on-the-wire tenant
        resource or a context-resolution rule.
      </t>
      <t>
        In practice, each identity platform fills the gap proprietarily. The
        same logical concept (tenant, organization, identity domain, workspace,
        customer account) is therefore not portable across SCIM endpoints. In
        zero-trust deployments <xref target="NIST-SP-800-207"/>, where
        authorization is evaluated continuously, an ambiguous or stale tenant
        context is itself a security liability, which raises the importance of a
        precise tenant-resolution rule. This document proposes a
        backward-compatible SCIM 2.0 extension that closes this gap.
      </t>
      <t>
        The contribution of this document is the portability of the tenant
        concept through SCIM and the precise, security-relevant rules that
        govern it: a tenant resource and membership model, a context-resolution
        rule with a stated invariant, a lifecycle state machine, and a
        tenant-scoped uniqueness model. This document does not invent tenancy
        and does not require identity platforms to abandon their internal
        representations; it defines a vendor-neutral abstraction layer.
      </t>

      <section anchor="related">
        <name>Relationship to Other SCIM Work</name>
        <t>
          This extension is intended to compose with, not duplicate, other SCIM
          resource and extension work:
        </t>
        <dl newline="false" spacing="normal">
          <dt>Roles and entitlements:</dt>
          <dd>
            The discovery of which roles and entitlements a service provider
            accepts, including values that vary per customer or tenant, is
            addressed by <xref target="I-D.ietf-scim-roles-entitlements"/>.
            Portable, scoped role bindings of the form "subject has role R in
            scope S" (where S MAY be a tenant) are addressed by the
            RoleAssignment work <xref target="I-D.poreddy-scim-role-assignment"/>,
            whose scope type "tenant" references a Tenant defined by this
            document. Accordingly, this document does NOT carry tenant-local
            roles or entitlements on the membership object; see <xref
            target="user-membership"/>. Implementations that require scoped role
            bindings <bcp14>SHOULD</bcp14> use RoleAssignment with a scope that
            references a Tenant "id" defined here.
          </dd>
          <dt>Use cases:</dt>
          <dd>
            Multi-tenant deployment topologies and reconciliation flows are
            described in <xref target="I-D.ietf-scim-use-cases-reloaded"/>. This
            document provides the schema and protocol surface those topologies
            require.
          </dd>
          <dt>Core resources:</dt>
          <dd>
            This document extends the "User" and "Group" resources of <xref
            target="RFC7643"/> and adds the "Tenant" resource type. It does not
            modify the core schema or protocol and is additive in the sense of
            <xref target="RFC7643"/>, Section 4.
          </dd>
        </dl>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="conventions">
      <name>Conventions and Definitions</name>
      <t>
        The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
        "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
        NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
        "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
        "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are
        to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref
        target="RFC8174"/> when, and only when, they appear in all capitals, as
        shown here.
      </t>
      <t>The following terms are used throughout the document:</t>
      <dl newline="false" spacing="normal">
        <dt>Tenant:</dt>
        <dd>
          A logical administrative boundary within a service provider. A Tenant
          corresponds to an organization, customer account, workspace, realm,
          identity domain, or SaaS tenant.
        </dd>
        <dt>Tenant context:</dt>
        <dd>The Tenant to which a SCIM request applies.</dd>
        <dt>Tenant indicator:</dt>
        <dd>
          A signal in a SCIM request that conveys tenant intent. Indicators are
          one of: a JWT or OAuth access-token claim, a URL path segment, an HTTP
          header, a request-host subdomain, or a field in the request body.
        </dd>
        <dt>Authenticated tenant indicator:</dt>
        <dd>
          A tenant indicator whose integrity is cryptographically bound to the
          request, such that a network-positioned adversary cannot alter it
          without detection. By default, the only authenticated indicator is the
          access-token claim of <xref target="claim"/>.
        </dd>
        <dt>Tenant-scoped resource:</dt>
        <dd>
          A SCIM resource whose ownership function maps it to exactly one
          Tenant. Tenants own Users, Groups, Memberships, and (transitively)
          their members and attributes.
        </dd>
        <dt>Authorized tenant set:</dt>
        <dd>
          The set of Tenants for which a SCIM client holds at least one
          authorization grant for at least one operation.
        </dd>
        <dt>Effective tenant (T*):</dt>
        <dd>
          The single Tenant to which a request is resolved by the rule of <xref
          target="resolution"/>.
        </dd>
        <dt>Service provider:</dt>
        <dd>A SCIM service provider as defined in <xref target="RFC7644"/>.</dd>
      </dl>
    </section>

    <!-- ===================================================== -->
    <section anchor="schema-uris">
      <name>Schema URIs</name>
      <t>This document defines four SCIM schema URIs:</t>
      <artwork><![CDATA[
urn:ietf:params:scim:schemas:core:2.0:Tenant
urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User
urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:Group
urn:ietf:params:scim:schemas:extension:multiTenancy:2.0:ServiceProviderConfig
]]></artwork>
      <t>
        The Tenant resource is a new resource type and therefore uses a primary
        schema URI in the "core" namespace, consistent with <xref
        target="RFC7643"/>, Section 10 and with the convention adopted by other
        new SCIM resource types. The two membership schemas extend existing
        resource types and therefore use the "extension" namespace. These URIs
        are requested for registration in the IANA "SCIM Schema URIs" registry;
        see <xref target="iana"/>.
      </t>
    </section>

    <!-- ===================================================== -->
    <section anchor="tenant-resource">
      <name>Tenant Resource</name>
      <t>A Tenant resource is exposed at the SCIM endpoint "/Tenants".</t>

      <section anchor="tenant-endpoints">
        <name>Endpoints</name>
        <t>
          A service provider implementing this extension <bcp14>SHALL</bcp14>
          support the following endpoints with the semantics defined in <xref
          target="RFC7644"/>:
        </t>
        <artwork><![CDATA[
GET    /Tenants            (list/search)
GET    /Tenants/{id}       (read)
POST   /Tenants            (create)
PUT    /Tenants/{id}       (replace)
PATCH  /Tenants/{id}       (modify)
DELETE /Tenants/{id}       (delete; see lifecycle rules)
]]></artwork>
        <t>
          DELETE is subject to the cascade rules of <xref
          target="lifecycle"/>.
        </t>
      </section>

      <section anchor="tenant-attributes">
        <name>Attributes</name>
        <t>
          The Tenant resource has the following attributes. Each entry below
          follows <xref target="RFC7643"/>, Section 2.2. Unless otherwise noted,
          the type is "string", "multiValued" is false, "required" is false,
          "caseExact" is false, "mutability" is "readWrite", "returned" is
          "default", and "uniqueness" is "none".
        </t>
        <dl newline="false" spacing="normal">
          <dt>id:</dt>
          <dd>
            Type string. Required true. Mutability readOnly. Returned always.
            Uniqueness server. A unique, stable, non-reassignable identifier
            assigned by the service provider. Compared octet-by-octet; see <xref
            target="canon"/>.
          </dd>
          <dt>externalId:</dt>
          <dd>
            Type string. Uniqueness server. A client-supplied identifier; see
            <xref target="RFC7643"/>, Section 3.1.
          </dd>
          <dt>displayName:</dt>
          <dd>Type string. Required true. A human-readable name for the Tenant.</dd>
          <dt>status:</dt>
          <dd>
            Type string. Required true. Canonical values "active", "suspended",
            "archived", "pending". Transitions are governed by <xref
            target="lifecycle"/>.
          </dd>
          <dt>type:</dt>
          <dd>
            Type string. Canonical values "customer", "partner", "internal",
            "workspace", "organization".
          </dd>
          <dt>domains:</dt>
          <dd>
            Complex multi-valued. Each entry has sub-attributes "value" (string,
            required, the FQDN), "primary" (boolean; at most one entry
            <bcp14>MAY</bcp14> be true), and "verified" (boolean, readOnly; true
            if and only if the service provider has independently verified domain
            ownership). FQDN comparison follows <xref target="canon"/>.
          </dd>
          <dt>homeRegion:</dt>
          <dd>
            Type string. Optional. Identifier of the Tenant's home region.
            Present only when the region profile (see <xref
            target="region-profile"/>) is supported.
          </dd>
          <dt>regions:</dt>
          <dd>
            Complex multi-valued. Optional. Present only when the region profile
            is supported. Sub-attributes are defined in <xref
            target="region-profile"/>.
          </dd>
          <dt>meta:</dt>
          <dd>
            Complex. Required. ReadOnly. As defined in <xref target="RFC7643"/>,
            Section 3.1. "meta.resourceType" <bcp14>SHALL</bcp14> be the string
            "Tenant". "meta.version" <bcp14>SHALL</bcp14> be supported to enable
            the concurrency control of <xref target="concurrency"/>.
          </dd>
        </dl>
      </section>

      <section anchor="tenant-example">
        <name>Example</name>
        <sourcecode type="json"><![CDATA[
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Tenant"
  ],
  "id": "tenant-acme",
  "externalId": "customer-1001",
  "displayName": "Acme Corporation",
  "status": "active",
  "type": "customer",
  "domains": [
    {"value": "acme.example.com", "primary": true, "verified": true}
  ],
  "meta": {
    "resourceType": "Tenant",
    "version": "W/\"a330bc54f0671c9\"",
    "location": "https://sp.example.com/scim/v2/Tenants/tenant-acme"
  }
}
]]></sourcecode>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="user-membership">
      <name>Tenant Membership Extension for User</name>
      <t>
        The Tenant Membership extension for User is identified by the URI
        "urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User".
      </t>

      <section anchor="user-membership-attrs">
        <name>Attributes</name>
        <dl newline="false" spacing="normal">
          <dt>memberships:</dt>
          <dd>
            <t>
              Complex multi-valued. ReadWrite. Each entry represents the user's
              relationship to one Tenant. Sub-attributes:
            </t>
            <ul spacing="compact">
              <li>"value" (string, required, readWrite): the referenced Tenant's
                "id".</li>
              <li>"$ref" (reference, required, readOnly,
                referenceTypes=["Tenant"]): the URI "/Tenants/{id}".</li>
              <li>"status" (string, required, readWrite): canonical values
                "active", "suspended", "invited", "pending", "deactivated".
                Transitions are governed by <xref target="lifecycle"/>.</li>
              <li>"primary" (boolean, readWrite): at most one entry
                <bcp14>MAY</bcp14> be true.</li>
            </ul>
          </dd>
        </dl>
        <t>
          This object intentionally does NOT carry tenant-local "roles" or
          "entitlements". Scoped role and entitlement bindings are expressed
          using RoleAssignment <xref target="I-D.poreddy-scim-role-assignment"/>
          with a scope that references the Tenant "id", and the set of available
          roles and entitlements is discovered using <xref
          target="I-D.ietf-scim-roles-entitlements"/>. This avoids re-encoding
          scope into role strings and keeps a single interoperable mechanism for
          scoped authorization data. See <xref target="related"/>.
        </t>
      </section>

      <section anchor="effective-state">
        <name>Effective State</name>
        <t>
          A user's effective state in Tenant "t" is determined by composing the
          core user state, the tenant state, and the membership state, in this
          order:
        </t>
        <ol spacing="normal">
          <li>If core "User.active" is false, the effective state is "inactive"
            in every Tenant.</li>
          <li>Otherwise, if "Tenant(t).status" is "suspended" or "archived", the
            effective state is "inactive" in "t" regardless of membership
            status.</li>
          <li>Otherwise, the effective state is derived from "membership.status"
            for the matching membership: "active" is active; "suspended" and
            "deactivated" are inactive; "invited" and "pending" are inactive
            until activation.</li>
          <li>If no membership exists for "t", the user has no presence in "t",
            and SCIM operations targeting "t" for that user
            <bcp14>SHALL</bcp14> be rejected with HTTP 404.</li>
        </ol>
      </section>

      <section anchor="user-membership-example">
        <name>Example</name>
        <sourcecode type="json"><![CDATA[
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User"
  ],
  "id": "user-123",
  "userName": "alex@example.com",
  "active": true,
  "urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User": {
    "memberships": [
      {
        "value": "tenant-acme",
        "$ref": "/Tenants/tenant-acme",
        "status": "active",
        "primary": true
      },
      {
        "value": "tenant-contoso",
        "$ref": "/Tenants/tenant-contoso",
        "status": "suspended",
        "primary": false
      }
    ]
  }
}
]]></sourcecode>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="group-membership">
      <name>Tenant Membership Extension for Group</name>
      <t>
        The Tenant Membership extension for Group is identified by the URI
        "urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:Group".
      </t>

      <section anchor="group-membership-attrs">
        <name>Attributes</name>
        <dl newline="false" spacing="normal">
          <dt>value:</dt>
          <dd>
            Type string. Required when "scope = tenant". Mutability readWrite.
            The owning Tenant's "id".
          </dd>
          <dt>$ref:</dt>
          <dd>
            Type reference. ReferenceTypes ["Tenant"]. Required when "scope =
            tenant". Mutability readOnly. The URI "/Tenants/{id}".
          </dd>
          <dt>scope:</dt>
          <dd>
            Type string. Required. Mutability readWrite. Canonical values
            "tenant", "global".
          </dd>
        </dl>
      </section>

      <section anchor="group-constraints">
        <name>Constraints</name>
        <t>
          Tenant-scoped groups <bcp14>SHALL</bcp14> belong to exactly one
          Tenant. A client <bcp14>SHALL NOT</bcp14> create a Group with "scope =
          tenant" and no "value". Cross-tenant Group membership is not modeled;
          cross-tenant collaboration is expressed at the User level via multiple
          memberships.
        </t>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="spc">
      <name>ServiceProviderConfig Extension</name>
      <t>
        A service provider implementing this extension <bcp14>SHALL</bcp14>
        advertise its tenant-related capabilities through
        "/ServiceProviderConfig", using the schema URI
        "urn:ietf:params:scim:schemas:extension:multiTenancy:2.0:ServiceProviderConfig".
      </t>

      <section anchor="spc-attrs">
        <name>Attributes</name>
        <dl newline="false" spacing="normal">
          <dt>multiTenancy:</dt>
          <dd>
            <t>Complex. Required. Mutability readOnly. Sub-attributes:</t>
            <ul spacing="compact">
              <li>"supported" (boolean): true if and only if the service
                provider supports any portion of this extension.</li>
              <li>"tenantResourceSupported" (boolean): true if and only if
                "/Tenants" is available.</li>
              <li>"tenantMembershipSupported" (boolean): true if and only if the
                user and group membership extensions are supported.</li>
              <li>"tenantAwareFilteringSupported" (boolean): true if and only if
                filters referencing membership attributes are supported.</li>
              <li>"tenantScopedUniquenessSupported" (boolean): true if and only
                if tenant-scoped uniqueness is configurable for natural-key
                attributes.</li>
              <li>"regionAwareTenancySupported" (boolean): true if and only if
                the region profile is implemented.</li>
              <li>"tenantSelectionMethods" (string, multi-valued): the indicator
                methods the service provider accepts. Values are drawn from
                "tokenClaim", "path", "header", "subdomain", "body".</li>
              <li>"tenantSelectionPrecedence" (string, multi-valued): an ordered
                list of methods denoting their precedence. The default order is
                ["tokenClaim", "path", "header", "subdomain", "body"].</li>
              <li>"authenticatedSelectionMethods" (string, multi-valued): the
                subset of "tenantSelectionMethods" the service provider treats
                as authenticated (see <xref target="conventions"/>). The default
                value is ["tokenClaim"].</li>
              <li>"tenantClaim" (string): the JWT claim name carrying tenant
                context. Default "tenant_id".</li>
              <li>"tenantHeader" (string): the HTTP header field name carrying
                tenant context. Default "SCIM-Tenant-Id".</li>
              <li>"tenantScopedUniqueness" (complex): a record of which natural
                keys are scoped to Tenant rather than server. Sub-attributes are
                attribute names ("userName", "externalId", "groupDisplayName")
                mapped to the string "tenant" or "server".</li>
            </ul>
          </dd>
        </dl>
      </section>

      <section anchor="spc-example">
        <name>Example</name>
        <sourcecode type="json"><![CDATA[
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig",
    "urn:ietf:params:scim:schemas:extension:multiTenancy:2.0:ServiceProviderConfig"
  ],
  "urn:ietf:params:scim:schemas:extension:multiTenancy:2.0:ServiceProviderConfig": {
    "multiTenancy": {
      "supported": true,
      "tenantResourceSupported": true,
      "tenantMembershipSupported": true,
      "tenantAwareFilteringSupported": true,
      "tenantScopedUniquenessSupported": true,
      "regionAwareTenancySupported": true,
      "tenantSelectionMethods": [
        "tokenClaim","path","header","subdomain","body"
      ],
      "tenantSelectionPrecedence": [
        "tokenClaim","path","header","subdomain","body"
      ],
      "authenticatedSelectionMethods": ["tokenClaim"],
      "tenantClaim": "tenant_id",
      "tenantHeader": "SCIM-Tenant-Id",
      "tenantScopedUniqueness": {
        "userName": "tenant",
        "externalId": "tenant",
        "groupDisplayName": "tenant"
      }
    }
  }
}
]]></sourcecode>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="resolution">
      <name>Tenant Context Resolution</name>
      <t>
        This section defines a single rule that resolves a request to one
        effective Tenant "T*" and states the invariant the rule preserves. The
        rule subsumes both indicator precedence and indicator-conflict handling;
        the two are not independent mechanisms.
      </t>

      <section anchor="resolution-rule">
        <name>Resolution Rule and Binding Invariant</name>
        <t>
          Let TI(q) be the set of present, canonicalized (<xref
          target="canon"/>) tenant indicators in request q, and let A(q) be the
          subset of TI(q) that the service provider treats as authenticated (by
          default, the access-token claim only; see
          "authenticatedSelectionMethods"). The service provider
          <bcp14>SHALL</bcp14> resolve and admit a request as follows:
        </t>
        <artwork><![CDATA[
T* = value of the highest-precedence element of A(q), if A(q) is
     non-empty; otherwise the highest-precedence element of TI(q).

A request is ADMISSIBLE if and only if:
  (1) the client is authorized for T*, AND
  (2) for every indicator i in TI(q): canonicalize(i) = T*.

Tenant Binding Invariant:
  For any operation that commits a state change, the effective tenant
  equals T*, and the client holds an authorization grant for T*.
]]></artwork>
        <t>
          Step (1) is the authorization gate. Step (2) is the cross-check that
          prevents a lower-precedence (possibly spoofable) indicator from
          silently redirecting the request. Because T* is taken from the
          highest-precedence authenticated indicator whenever one is present,
          effective context is never derived from a spoofable source when an
          authenticated indicator exists. Each rule preserves the invariant:
          derivation sets the effective tenant to T*; step (1) ensures
          authorization for T*; step (2) ensures no other indicator disagrees;
          and canonicalization (<xref target="canon"/>) ensures the comparisons
          in (2) are sound. Implementations <bcp14>SHALL</bcp14> evaluate the
          gate and cross-check in a way that does not leak tenant existence or
          authorization; see <xref target="error-uniformity"/>.
        </t>
      </section>

      <section anchor="resolution-errors">
        <name>Rejection and Error Uniformity</name>
        <t>
          When a request is not admissible, the service provider
          <bcp14>SHALL</bcp14> respond as follows:
        </t>
        <ul spacing="normal">
          <li>If the client is not authorized for T* (step (1) fails), the
            service provider <bcp14>SHALL</bcp14> return HTTP 404 and
            <bcp14>SHALL</bcp14> return a response that is indistinguishable from
            the response for a nonexistent Tenant (see <xref
            target="sec-enum"/>). The service provider <bcp14>SHALL NOT</bcp14>
            reveal that an indicator conflict occurred.</li>
          <li>If the client is authorized for T* but a lower-precedence
            indicator disagrees (step (2) fails), the service provider
            <bcp14>SHALL</bcp14> return HTTP 400 with a SCIM error response with
            "scimType = invalidValue". Such a response <bcp14>MAY</bcp14>
            identify T* (for which the client is authorized) but
            <bcp14>MUST NOT</bcp14> echo any conflicting tenant identifier for
            which the client is not authorized.</li>
        </ul>
        <t>
          Because the 400 conflict response is reachable only after the
          authorization gate for T* has been passed, it does not act as an
          existence or authorization oracle for any other Tenant.
        </t>
      </section>

      <section anchor="canon">
        <name>Identifier Canonicalization</name>
        <t>
          Before comparison under <xref target="resolution-rule"/>, each
          indicator is mapped to a Tenant "id" and normalized:
        </t>
        <ul spacing="normal">
          <li>A "tokenClaim", "path", "header", or "body" indicator carries a
            Tenant "id" directly. Tenant "id" values are compared octet-by-octet
            (case-sensitive); the service provider <bcp14>SHALL NOT</bcp14> apply
            case folding or Unicode normalization to "id".</li>
          <li>A "subdomain" indicator carries an FQDN that is mapped to a Tenant
            "id" through the verified "domains" of a Tenant. FQDNs are compared
            after lowercasing, removal of any trailing dot, and conversion of
            any internationalized labels to their A-label (Punycode) form. An
            unverified domain <bcp14>SHALL NOT</bcp14> resolve a tenant
            context.</li>
        </ul>
        <t>
          If an indicator cannot be mapped to a Tenant "id" (for example, an
          unrecognized subdomain), it is treated as not resolving to any Tenant;
          the request is then handled as in <xref target="resolution-errors"/>
          with respect to T*.
        </t>
      </section>

      <section anchor="multi-tenant-admin">
        <name>Multi-Tenant Administrative Clients</name>
        <t>
          A single client (for example, an identity-governance administrator)
          may be authorized for many Tenants under one access token. Such a
          token cannot name a single Tenant in "tenant_id". To support this
          case:
        </t>
        <ul spacing="normal">
          <li>If the access token asserts an authorized tenant set rather than a
            single Tenant, the token claim does not by itself fix T*. A(q) is
            then empty for the purpose of <xref target="resolution-rule"/>, and
            T* is taken from the highest-precedence present indicator in TI(q).</li>
          <li>The resolved T* <bcp14>SHALL</bcp14> be a member of the token's
            authorized tenant set; otherwise the authorization gate (step (1))
            fails and <xref target="resolution-errors"/> applies. This preserves
            the Tenant Binding Invariant: T* remains constrained by an
            authenticated grant even though it is not named by an authenticated
            indicator.</li>
        </ul>
      </section>

      <section anchor="claim">
        <name>Token Claim</name>
        <t>
          A service provider that consumes OAuth 2.0 <xref target="RFC6749"/>
          access tokens or JWT-profile access tokens <xref target="RFC9068"/>
          <bcp14>SHALL</bcp14> accept a JWT claim named "tenant_id" of type
          string. The claim value <bcp14>SHALL</bcp14> be the SCIM Tenant "id"
          the client asserts as the request's tenant context.
        </t>
        <t>
          A service provider <bcp14>MAY</bcp14> additionally accept
          implementation-specific claims (for example, "tid" for compatibility
          with deployed ecosystems) and <bcp14>SHALL</bcp14> advertise the
          primary accepted claim in
          "ServiceProviderConfig.multiTenancy.tenantClaim". When multiple claims
          carrying tenant context are present in a single token, the claim named
          by "tenantClaim" <bcp14>SHALL</bcp14> take precedence.
        </t>
      </section>

      <section anchor="header">
        <name>HTTP Header Field</name>
        <t>
          When an HTTP header-field indicator is used, the canonical field name
          is "SCIM-Tenant-Id" and its value is the Tenant "id". The field name
          follows the structured-naming guidance of <xref target="RFC9110"/>,
          Section 16.3.2 and is registered as a provisional HTTP field name; see
          <xref target="iana"/>. The header field is a tenant-context indicator
          only and, unless it is listed in "authenticatedSelectionMethods",
          <bcp14>SHALL NOT</bcp14> be treated as authenticated.
        </t>
      </section>

      <section anchor="resolution-precedence">
        <name>Precedence Configuration</name>
        <t>
          The default precedence is ["tokenClaim", "path", "header",
          "subdomain", "body"], reflecting that a signed access-token claim is
          cryptographically bound to the request through OAuth bearer
          presentation <xref target="RFC6750"/>, while URL path, header,
          subdomain, and body are mutable by intermediaries or by the client.
          Implementations <bcp14>MAY</bcp14> alter the precedence per deployment.
          Any deviation from the default <bcp14>SHALL</bcp14> be reflected in
          "ServiceProviderConfig.multiTenancy.tenantSelectionPrecedence", and any
          deviation from the default authenticated set
          <bcp14>SHALL</bcp14> be reflected in "authenticatedSelectionMethods". A
          service provider <bcp14>SHALL NOT</bcp14> place an unauthenticated
          indicator ahead of an authenticated one in a way that would allow an
          unauthenticated indicator to determine T* while an authenticated
          indicator is present.
        </t>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="lifecycle">
      <name>Lifecycle State Machine</name>
      <t>
        This section specifies the permissible states and transitions for the
        Tenant resource and for User memberships, and the cascade effects of
        Tenant transitions on memberships. Service providers
        <bcp14>SHALL</bcp14> reject transitions not listed here with HTTP 400 and
        "scimType = invalidValue".
      </t>

      <section anchor="tenant-states">
        <name>Tenant States</name>
        <table anchor="tenant-transitions">
          <name>Tenant status transitions</name>
          <thead>
            <tr><th>From</th><th>To</th><th>Effect</th></tr>
          </thead>
          <tbody>
            <tr><td>(create)</td><td>pending, active</td><td>Initial state on POST.</td></tr>
            <tr><td>pending</td><td>active</td><td>Tenant becomes operational.</td></tr>
            <tr><td>pending</td><td>archived</td><td>Abandoned before activation.</td></tr>
            <tr><td>active</td><td>suspended</td><td>Members become inactive (<xref target="effective-state"/>); resources retained.</td></tr>
            <tr><td>suspended</td><td>active</td><td>Members' effective state recomputed from membership status.</td></tr>
            <tr><td>active, suspended</td><td>archived</td><td>Terminal-soft state; read-only; members inactive.</td></tr>
            <tr><td>archived</td><td>(DELETE)</td><td>Permitted subject to <xref target="lifecycle-delete"/>.</td></tr>
          </tbody>
        </table>
        <t>
          While a Tenant is "suspended" or "archived", the service provider
          <bcp14>SHALL</bcp14> reject state-changing operations on resources
          owned by that Tenant with HTTP 409 and "scimType = mutability", except
          operations that themselves transition the Tenant status.
        </t>
      </section>

      <section anchor="membership-states">
        <name>Membership States</name>
        <table anchor="membership-transitions">
          <name>Membership status transitions</name>
          <thead>
            <tr><th>From</th><th>To</th><th>Notes</th></tr>
          </thead>
          <tbody>
            <tr><td>(create)</td><td>invited, pending, active</td><td>Initial state on membership add.</td></tr>
            <tr><td>invited</td><td>pending, active, deactivated</td><td>Invitation accepted or withdrawn.</td></tr>
            <tr><td>pending</td><td>active, deactivated</td><td>Provisioning completed or abandoned.</td></tr>
            <tr><td>active</td><td>suspended, deactivated</td><td>Temporary or permanent removal of presence.</td></tr>
            <tr><td>suspended</td><td>active, deactivated</td><td>Reinstatement or permanent removal.</td></tr>
            <tr><td>deactivated</td><td>active</td><td>Re-activation; permitted only while the Tenant is "active".</td></tr>
            <tr><td>(any)</td><td>(remove)</td><td>Removing the membership ends the user's presence in the Tenant; see <xref target="concurrency-patch"/>.</td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="lifecycle-delete">
        <name>Tenant Deletion and Cascade</name>
        <t>
          A service provider <bcp14>SHALL NOT</bcp14> silently cascade-delete
          Users or Groups when a Tenant is deleted. On "DELETE /Tenants/{id}":
        </t>
        <ol spacing="normal">
          <li>If the Tenant owns any tenant-scoped Group or any User whose only
            membership is in this Tenant, the service provider
            <bcp14>SHALL</bcp14> reject the request with HTTP 409 and "scimType =
            uniqueness" unless the client supplies an explicit cascade
            indication that the service provider documents and advertises. This
            prevents accidental destruction of identities.</li>
          <li>For a User with memberships in other Tenants, deletion of this
            Tenant <bcp14>SHALL</bcp14> remove only the membership entry that
            references this Tenant; the User resource is retained.</li>
          <li>A Tenant <bcp14>SHOULD</bcp14> be in status "archived" before
            deletion.</li>
        </ol>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="concurrency">
      <name>Concurrency and PATCH Semantics</name>
      <t>
        Membership "status" is security-relevant: it gates a user's presence and
        effective state in a Tenant. Concurrent modification of memberships is
        therefore a correctness and security concern, not only a convenience.
      </t>

      <section anchor="concurrency-etag">
        <name>Optimistic Concurrency</name>
        <t>
          Service providers <bcp14>SHALL</bcp14> support resource versioning via
          "meta.version" and HTTP entity-tags as described in <xref
          target="RFC7644"/>, Section 3.14 and <xref target="RFC9110"/>, Section
          8.8.3. A client that mutates a membership (adds, replaces, or removes a
          membership entry, or changes "membership.status")
          <bcp14>SHOULD</bcp14> supply an "If-Match" precondition. A service
          provider <bcp14>SHALL</bcp14> reject a membership-mutating request
          whose "If-Match" precondition does not match the current version with
          HTTP 412. A service provider <bcp14>MAY</bcp14> require the precondition
          and reject a membership-mutating request that omits "If-Match" with
          HTTP 428 <xref target="RFC6585"/>. These requirements prevent
          lost-update races that could otherwise reinstate or escalate a user's
          presence in a Tenant.
        </t>
      </section>

      <section anchor="concurrency-patch">
        <name>PATCH Targeting of Memberships</name>
        <t>
          A single membership is targeted in a PATCH operation using a
          value-path filter per <xref target="RFC7644"/>, Section 3.5.2, with
          the schema URI prefix. For example, to suspend a user's membership in
          one Tenant:
        </t>
        <sourcecode type="json"><![CDATA[
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User:memberships[value eq \"tenant-acme\"].status",
      "value": "suspended"
    }
  ]
}
]]></sourcecode>
        <t>
          An "op" of "remove" whose path selects an entire membership entry
          (for example, "...:memberships[value eq \"tenant-acme\"]") ends the
          user's presence in that Tenant; subsequent operations targeting that
          Tenant for that user are handled per <xref target="effective-state"/>,
          item 4. A service provider <bcp14>SHALL</bcp14> reject a PATCH that
          would leave two membership entries referencing the same Tenant with
          HTTP 409 and "scimType = uniqueness".
        </t>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="filtering">
      <name>Tenant-Aware Filtering</name>
      <t>
        A service provider that sets "tenantAwareFilteringSupported = true"
        <bcp14>SHALL</bcp14> accept SCIM filters referencing extension attributes
        per <xref target="RFC7644"/>, Section 3.4.2.2. The schema URI is
        separated from the attribute path by a colon:
      </t>
      <artwork><![CDATA[
GET /Users?filter=
  urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User:
  memberships.value eq "tenant-acme"

GET /Groups?filter=
  urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:Group:
  value eq "tenant-acme"

GET /Tenants?filter=status eq "active"
]]></artwork>
      <t>
        Tenant-aware filtering is a convenience for clients and is never the
        isolation boundary. Regardless of any filter, a service provider
        <bcp14>SHALL</bcp14> scope results to the client's authorized tenant set
        and <bcp14>SHALL NOT</bcp14> return resources owned by a Tenant for which
        the client is not authorized (<xref target="behavior-summary"/>).
      </t>
    </section>

    <!-- ===================================================== -->
    <section anchor="compat">
      <name>Tenant-Scoped Uniqueness and Backward Compatibility</name>
      <t>
        This section specifies how tenant-scoped uniqueness interacts with the
        "uniqueness = server" constraint of <xref target="RFC7643"/> on
        attributes such as "userName". The notion that "externalId" is
        interpreted relative to a tenant has long-standing precedent in SCIM; this
        section generalizes the idea and makes it discoverable.
      </t>
      <t>
        A service provider <bcp14>MAY</bcp14> scope uniqueness of "userName",
        "externalId", and "Group.displayName" to Tenant rather than to server.
        When it does so it <bcp14>SHALL</bcp14> advertise the scope in
        "ServiceProviderConfig.multiTenancy.tenantScopedUniqueness".
      </t>
      <t>The contract with <xref target="RFC7644"/> clients is preserved as follows:</t>
      <ol spacing="normal">
        <li>Single-tenant clients interact with exactly one Tenant per SCIM
          endpoint binding (typically via a tenant-specific base URL). Within
          that binding, "userName" appears server-unique because the binding pins
          tenant context.</li>
        <li>A client <bcp14>SHALL NOT</bcp14> see resources from a Tenant for
          which it is not authorized. Even if two Tenants contain users with
          identical "userName", an unaware single-tenant client observes at most
          one of them.</li>
        <li>The resource identifier "id" and "meta.location" remain
          server-unique and uniquely addressable. This document
          <bcp14>SHALL NOT</bcp14> weaken "id" uniqueness on "User", "Group", or
          "Tenant".</li>
      </ol>
      <t>
        Cross-tenant clients require an explicit contract. When a client is
        authorized for more than one Tenant and queries a natural key that is
        tenant-scoped (for example, "GET /Users?filter=userName eq \"alex\""),
        the service provider <bcp14>MAY</bcp14> return more than one matching
        resource across the client's authorized Tenants. Such clients
        <bcp14>SHOULD</bcp14> constrain natural-key queries with a tenant
        predicate (for example, a "memberships.value" term or the tenant
        context of <xref target="resolution"/>) to obtain a single result, and
        <bcp14>MUST NOT</bcp14> assume that a natural-key match is unique across
        Tenants.
      </t>
      <t>
        A deployment migrating from "server" to "tenant" uniqueness
        <bcp14>MUST</bcp14> first verify that no Tenant pair contains conflicting
        natural keys, and <bcp14>SHOULD</bcp14> perform the migration while the
        affected Tenants are in status "suspended" to avoid concurrent creation
        of conflicting keys.
      </t>
    </section>

    <!-- ===================================================== -->
    <section anchor="region-profile">
      <name>Region-Aware Tenant Metadata (Optional Profile)</name>
      <t>
        This profile is <bcp14>OPTIONAL</bcp14> and addresses data residency and
        active/passive replication topology, which are largely orthogonal to the
        core tenant model. It is documented here for completeness and
        <bcp14>MAY</bcp14> be moved to a companion document; see <xref
        target="open-issues"/>. A service provider that does not implement
        multi-region tenancy <bcp14>SHALL</bcp14> set "regionAwareTenancySupported
        = false" and <bcp14>SHALL NOT</bcp14> include "homeRegion" or "regions"
        on Tenant resources.
      </t>

      <section anchor="region-subattrs">
        <name>Tenant.regions Sub-Attributes</name>
        <dl newline="false" spacing="normal">
          <dt>region:</dt>
          <dd>Type string. Required. Region identifier (deployment-specific).</dd>
          <dt>mode:</dt>
          <dd>
            Type string. Required. Canonical values "readWrite", "readOnly",
            "authenticationOnly", "unavailable".
          </dd>
          <dt>status:</dt>
          <dd>
            Type string. Mutability readOnly. Canonical values "available",
            "degraded", "unavailable".
          </dd>
          <dt>writeAuthority:</dt>
          <dd>
            Type boolean. Required. Mutability readOnly. At most one region per
            Tenant <bcp14>SHALL</bcp14> have "writeAuthority = true".
          </dd>
        </dl>
      </section>

      <section anchor="region-write-rule">
        <name>Region Write Authority Rule</name>
        <t>
          When "regions" is present, a service provider <bcp14>SHALL</bcp14>
          reject a state-changing operation if the receiving region has
          "writeAuthority = false" for the resolved Tenant. The rejection
          <bcp14>SHALL</bcp14> return HTTP 409 with "scimType = mutability" and a
          "Link" header field to the home region's SCIM root, per the discovery
          semantics of <xref target="RFC7644"/>, Section 4.
        </t>
      </section>

      <section anchor="region-example">
        <name>Example</name>
        <sourcecode type="json"><![CDATA[
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Tenant"
  ],
  "id": "tenant-acme",
  "displayName": "Acme Corporation",
  "status": "active",
  "homeRegion": "region-a",
  "regions": [
    {"region":"region-a","mode":"readWrite",
     "status":"available","writeAuthority":true},
    {"region":"region-b","mode":"authenticationOnly",
     "status":"available","writeAuthority":false}
  ],
  "meta": {
    "resourceType": "Tenant",
    "location": "https://sp.example.com/scim/v2/Tenants/tenant-acme"
  }
}
]]></sourcecode>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="behavior-summary">
      <name>Normative Behavior Summary</name>
      <t>A service provider that claims conformance to this document:</t>
      <ul spacing="normal">
        <li><bcp14>MUST</bcp14> expose tenant capability metadata through
          "/ServiceProviderConfig".</li>
        <li><bcp14>MUST</bcp14> resolve each request to a single effective Tenant
          T* per <xref target="resolution"/> and preserve the Tenant Binding
          Invariant.</li>
        <li><bcp14>MUST NOT</bcp14> derive effective context from an
          unauthenticated indicator when an authenticated indicator is
          present.</li>
        <li><bcp14>MUST</bcp14> respond to an unauthorized-Tenant request
          indistinguishably from a nonexistent-Tenant request (<xref
          target="sec-enum"/>), and <bcp14>MUST NOT</bcp14> let conflict handling
          act as an existence or authorization oracle.</li>
        <li><bcp14>MUST NOT</bcp14> return tenant-scoped resources from a Tenant
          for which the SCIM client is not authorized, regardless of any
          filter.</li>
        <li><bcp14>MUST</bcp14> enforce the lifecycle transitions of <xref
          target="lifecycle"/> and <bcp14>MUST NOT</bcp14> silently cascade-delete
          identities on Tenant deletion.</li>
        <li><bcp14>MUST</bcp14> support "meta.version" and reject stale
          membership-mutating requests per <xref target="concurrency"/>.</li>
        <li><bcp14>MUST</bcp14> reject region-bypass writes when the region
          profile is implemented and the receiving region lacks write
          authority.</li>
        <li><bcp14>SHOULD</bcp14> support tenant-aware filtering for "Users",
          "Groups", and "Tenants".</li>
        <li><bcp14>SHOULD</bcp14> advertise tenant-scoped uniqueness rules.</li>
        <li><bcp14>MAY</bcp14> accept implementation-specific tenant claims for
          compatibility and <bcp14>MUST</bcp14> advertise the primary accepted
          claim name.</li>
      </ul>
    </section>

    <!-- ===================================================== -->
    <section anchor="security">
      <name>Security Considerations</name>

      <section anchor="sec-threat">
        <name>Threat Model</name>
        <t>
          The threat model assumes a network-positioned adversary that may craft
          arbitrary HTTP requests including any combination of tenant indicators,
          that holds valid credentials for some subset of Tenants, that cannot
          forge signatures of the trusted OAuth issuer, that cannot break TLS
          confidentiality or integrity, and that may observe response codes,
          bodies it is authorized to receive, and response timing.
        </t>
        <t>The named attack classes are:</t>
        <ol spacing="normal">
          <li>Indicator confusion: induce a state mutation for a Tenant whose
            authenticated context disagrees with another indicator.</li>
          <li>Cross-tenant access: read or mutate a resource owned by a Tenant
            for which the adversary is not authorized.</li>
          <li>Unauthorized membership: create a membership in a Tenant for which
            the adversary is not authorized.</li>
          <li>Region bypass: cause a write to commit at a region with
            "writeAuthority = false".</li>
          <li>Lost-update escalation: use a concurrent membership update to
            reinstate or escalate presence in a Tenant.</li>
        </ol>
      </section>

      <section anchor="sec-invariant">
        <name>Why the Rules Hold</name>
        <t>
          Resistance to attack classes 1-3 reduces to the Tenant Binding
          Invariant of <xref target="resolution-rule"/>: every committed
          state-changing operation acts on T*, and the client is authorized for
          T*. Indicator confusion (class 1) is prevented because T* is taken from
          the highest-precedence authenticated indicator when one is present, and
          step (2) rejects any disagreement; an adversary cannot move effective
          context to a Tenant other than the one named by an indicator it can
          authenticate. Cross-tenant access and unauthorized membership (classes
          2-3) are prevented by the authorization gate, step (1), which is
          evaluated for T* before any state change. Region bypass (class 4) is
          prevented by the write-authority rule of <xref
          target="region-write-rule"/>. Lost-update escalation (class 5) is
          prevented by the concurrency requirements of <xref
          target="concurrency-etag"/>. These are argued as invariant-preservation
          properties rather than proved formally; a formal symbolic model is
          identified as future work in <xref target="open-issues"/>.
        </t>
      </section>

      <section anchor="sec-indicator-trust">
        <name>Indicator Trust</name>
        <t>
          The default precedence places the token claim first because it is
          cryptographically bound to the request. An implementation that
          downgrades this ordering <bcp14>MUST</bcp14> justify the change in a
          deployment-specific threat model and <bcp14>MUST</bcp14> reflect the
          change in "tenantSelectionPrecedence" and
          "authenticatedSelectionMethods". A service provider
          <bcp14>SHALL NOT</bcp14> accept an unsigned tenant claim from any
          indicator that is not authenticated as if it were authenticated.
        </t>
      </section>

      <section anchor="sec-enum">
        <name>Tenant Enumeration</name>
        <t>
          A service provider <bcp14>SHALL</bcp14> respond identically to requests
          for an unauthorized Tenant and a nonexistent Tenant, returning HTTP 404
          with no body content that distinguishes the two cases. Differential
          timing between the two paths <bcp14>SHOULD</bcp14> be minimized;
          constant-time existence checks are <bcp14>RECOMMENDED</bcp14> for tenant
          lookup.
        </t>
      </section>

      <section anchor="error-uniformity">
        <name>Error Message Leakage</name>
        <t>
          Error responses <bcp14>MUST NOT</bcp14> echo Tenant identifiers from
          indicators that resolved to Tenants the client is not authorized for.
          As specified in <xref target="resolution-errors"/>, conflict-rejection
          (400) responses are reachable only after the authorization gate for T*
          has passed, and <bcp14>SHALL</bcp14> describe the conflict without
          revealing any tenant identifier for which the client is unauthorized.
        </t>
      </section>

      <section anchor="sec-timing">
        <name>Side-Channel Timing</name>
        <t>
          Tenant-scoped uniqueness checks <bcp14>MAY</bcp14> leak existence via
          response-time variance. Service providers <bcp14>SHOULD</bcp14> apply
          constant-time comparison or response-time padding for natural-key
          uniqueness probes that occur during create operations.
        </t>
      </section>

      <section anchor="sec-audit">
        <name>Audit Scoping</name>
        <t>
          Audit events <bcp14>SHALL</bcp14> be scoped to the Tenant the event
          affects. Cross-tenant administrative audit views
          <bcp14>SHALL</bcp14> be restricted to clients explicitly authorized for
          cross-tenant administration.
        </t>
      </section>

      <section anchor="sec-region-meta">
        <name>Region Metadata Exposure</name>
        <t>
          When the region profile is enabled, "Tenant.regions" reveals deployment
          topology and failover posture. This metadata <bcp14>SHOULD</bcp14> be
          exposed only to clients with administrative authorization for the
          Tenant.
        </t>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="privacy">
      <name>Privacy Considerations</name>

      <section anchor="priv-membership">
        <name>Membership Disclosure</name>
        <t>
          Tenant membership reveals customer, partner, employment, or
          administrative relationships. Service providers <bcp14>SHALL</bcp14>
          apply least-privilege response shaping. A client authorized only for
          Tenant "t" <bcp14>SHALL NOT</bcp14> receive memberships of the same User
          in Tenants other than "t".
        </t>
      </section>

      <section anchor="priv-minimization">
        <name>Attribute Minimization</name>
        <t>
          "ListResponses" from "/Tenants" <bcp14>SHOULD</bcp14> by default return
          only "id", "displayName", and "status". Per-Tenant user counts,
          membership counts, and similar aggregate properties
          <bcp14>MUST NOT</bcp14> be returned unless explicitly requested by a
          suitably authorized administrative client.
        </t>
      </section>

      <section anchor="priv-residency">
        <name>Data Residency and Cross-Border Transfer</name>
        <t>
          When the region profile is implemented, "homeRegion" and "regions"
          metadata may correspond to the lawful basis under which the Tenant's
          personal data is processed. Service providers <bcp14>SHOULD</bcp14>
          ensure that the "homeRegion" of a Tenant is consistent with the
          data-residency commitment made to the Tenant's data controller; that
          cross-region replication is governed by an appropriate data-transfer
          mechanism, including but not limited to Standard Contractual Clauses
          under <xref target="GDPR"/>, Articles 44 through 49, or equivalent
          mechanisms in other regimes; and that the exposure of "Tenant.regions"
          is consistent with data-subject rights under the applicable regime.
        </t>
      </section>

      <section anchor="priv-analytics">
        <name>Cross-Tenant Analytics</name>
        <t>
          Aggregate analytics across Tenants <bcp14>SHALL NOT</bcp14> be exposed
          through SCIM endpoints. Such analytics are out of scope of this
          document.
        </t>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="iana">
      <name>IANA Considerations</name>

      <section anchor="iana-schema">
        <name>SCIM Schema URIs</name>
        <t>
          This document requests registration of the following entries in the
          "SCIM Schema URIs" registry maintained by IANA. The reference for each
          entry is this document.
        </t>
        <dl newline="true" spacing="normal">
          <dt>urn:ietf:params:scim:schemas:core:2.0:Tenant</dt>
          <dd>Name: Tenant</dd>
          <dt>urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:User</dt>
          <dd>Name: User Tenant Membership</dd>
          <dt>urn:ietf:params:scim:schemas:extension:tenantMembership:2.0:Group</dt>
          <dd>Name: Group Tenant Membership</dd>
          <dt>urn:ietf:params:scim:schemas:extension:multiTenancy:2.0:ServiceProviderConfig</dt>
          <dd>Name: Multi-Tenancy ServiceProviderConfig</dd>
        </dl>
      </section>

      <section anchor="iana-rt">
        <name>SCIM Resource Types</name>
        <t>
          This document requests registration of the following entry in the
          "SCIM Resource Types" registry. The reference is this document.
        </t>
        <dl newline="false" spacing="compact">
          <dt>Name:</dt><dd>Tenant</dd>
          <dt>Endpoint:</dt><dd>/Tenants</dd>
          <dt>Schema:</dt><dd>urn:ietf:params:scim:schemas:core:2.0:Tenant</dd>
        </dl>
      </section>

      <section anchor="iana-jwt">
        <name>JSON Web Token Claims</name>
        <t>
          This document requests registration of the following claim in the
          "JSON Web Token Claims" registry per <xref target="RFC7519"/>, Section
          10.1. Because tenant identifiers are deployment-specific and several
          equivalent claims are already deployed, the registration is requested
          as provisional, with the expectation that the SCIM and OAuth
          communities confirm or revise the name before any permanent
          registration.
        </t>
        <table>
          <thead>
            <tr><th>Claim Name</th><th>Claim Description</th><th>Change Controller</th><th>Reference</th></tr>
          </thead>
          <tbody>
            <tr><td>tenant_id</td><td>The SCIM Tenant id asserted as request context</td><td>IETF</td><td>This document, <xref target="claim"/></td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="iana-http">
        <name>HTTP Field Name</name>
        <t>
          This document requests provisional registration of the HTTP field name
          "SCIM-Tenant-Id" in the "Hypertext Transfer Protocol (HTTP) Field Name
          Registry" per <xref target="RFC9110"/>, Section 16.3.1, with status
          "provisional", a reference to this document, and the field semantics of
          <xref target="header"/>.
        </t>
      </section>
    </section>

    <!-- ===================================================== -->
    <section anchor="open-issues">
      <name>Open Issues for Working Group Discussion</name>
      <t>The following items are expected to receive WG attention.</t>
      <ul spacing="normal">
        <li>Whether the region-aware profile (<xref target="region-profile"/>)
          should be a separate companion document, for example
          "draft-kushwaha-scim-tenant-regions".</li>
        <li>Whether tenant hierarchy (parent/child Tenants) should be in scope or
          deferred.</li>
        <li>Confirmation of the canonical-value sets and transitions in <xref
          target="lifecycle"/>.</li>
        <li>The precise relationship to RoleAssignment <xref
          target="I-D.poreddy-scim-role-assignment"/> and Roles/Entitlements
          <xref target="I-D.ietf-scim-roles-entitlements"/>, including whether a
          Tenant should be a registered RoleAssignment scope type.</li>
        <li>Whether a formal symbolic model (for example, in a Tamarin or ProVerif
          style) of the resolution rule and the Tenant Binding Invariant should
          accompany this document.</li>
        <li>Whether "tenantClaim" should permit a multi-valued list of accepted
          claim names rather than a single primary, and whether a new IETF claim
          is warranted versus profiling an existing claim.</li>
      </ul>
    </section>

  </middle>

  <back>

    <references anchor="normative-refs">
      <name>Normative References</name>

      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner" fullname="S. Bradner"/>
          <date year="1997" month="March"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>

      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba" fullname="B. Leiba"/>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>

      <reference anchor="RFC7643" target="https://www.rfc-editor.org/info/rfc7643">
        <front>
          <title>System for Cross-domain Identity Management: Core Schema</title>
          <author initials="P." surname="Hunt" role="editor"/>
          <author initials="K." surname="Grizzle"/>
          <author initials="E." surname="Wahlstroem"/>
          <author initials="C." surname="Mortimore"/>
          <date year="2015" month="September"/>
        </front>
        <seriesInfo name="RFC" value="7643"/>
        <seriesInfo name="DOI" value="10.17487/RFC7643"/>
      </reference>

      <reference anchor="RFC7644" target="https://www.rfc-editor.org/info/rfc7644">
        <front>
          <title>System for Cross-domain Identity Management: Protocol</title>
          <author initials="P." surname="Hunt" role="editor"/>
          <author initials="K." surname="Grizzle"/>
          <author initials="M." surname="Ansari"/>
          <author initials="E." surname="Wahlstroem"/>
          <author initials="C." surname="Mortimore"/>
          <date year="2015" month="September"/>
        </front>
        <seriesInfo name="RFC" value="7644"/>
        <seriesInfo name="DOI" value="10.17487/RFC7644"/>
      </reference>

      <reference anchor="RFC7519" target="https://www.rfc-editor.org/info/rfc7519">
        <front>
          <title>JSON Web Token (JWT)</title>
          <author initials="M." surname="Jones"/>
          <author initials="J." surname="Bradley"/>
          <author initials="N." surname="Sakimura"/>
          <date year="2015" month="May"/>
        </front>
        <seriesInfo name="RFC" value="7519"/>
        <seriesInfo name="DOI" value="10.17487/RFC7519"/>
      </reference>

      <reference anchor="RFC8259" target="https://www.rfc-editor.org/info/rfc8259">
        <front>
          <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
          <author initials="T." surname="Bray" role="editor"/>
          <date year="2017" month="December"/>
        </front>
        <seriesInfo name="STD" value="90"/>
        <seriesInfo name="RFC" value="8259"/>
        <seriesInfo name="DOI" value="10.17487/RFC8259"/>
      </reference>

      <reference anchor="RFC6749" target="https://www.rfc-editor.org/info/rfc6749">
        <front>
          <title>The OAuth 2.0 Authorization Framework</title>
          <author initials="D." surname="Hardt" role="editor"/>
          <date year="2012" month="October"/>
        </front>
        <seriesInfo name="RFC" value="6749"/>
        <seriesInfo name="DOI" value="10.17487/RFC6749"/>
      </reference>

      <reference anchor="RFC9068" target="https://www.rfc-editor.org/info/rfc9068">
        <front>
          <title>JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens</title>
          <author initials="V." surname="Bertocci"/>
          <date year="2021" month="October"/>
        </front>
        <seriesInfo name="RFC" value="9068"/>
        <seriesInfo name="DOI" value="10.17487/RFC9068"/>
      </reference>

      <reference anchor="RFC9110" target="https://www.rfc-editor.org/info/rfc9110">
        <front>
          <title>HTTP Semantics</title>
          <author initials="R." surname="Fielding" role="editor"/>
          <author initials="M." surname="Nottingham" role="editor"/>
          <author initials="J." surname="Reschke" role="editor"/>
          <date year="2022" month="June"/>
        </front>
        <seriesInfo name="STD" value="97"/>
        <seriesInfo name="RFC" value="9110"/>
        <seriesInfo name="DOI" value="10.17487/RFC9110"/>
      </reference>

      <reference anchor="RFC6585" target="https://www.rfc-editor.org/info/rfc6585">
        <front>
          <title>Additional HTTP Status Codes</title>
          <author initials="M." surname="Nottingham"/>
          <author initials="R." surname="Fielding"/>
          <date year="2012" month="April"/>
        </front>
        <seriesInfo name="RFC" value="6585"/>
        <seriesInfo name="DOI" value="10.17487/RFC6585"/>
      </reference>
    </references>

    <references anchor="informative-refs">
      <name>Informative References</name>

      <reference anchor="RFC6750" target="https://www.rfc-editor.org/info/rfc6750">
        <front>
          <title>The OAuth 2.0 Authorization Framework: Bearer Token Usage</title>
          <author initials="M." surname="Jones"/>
          <author initials="D." surname="Hardt"/>
          <date year="2012" month="October"/>
        </front>
        <seriesInfo name="RFC" value="6750"/>
        <seriesInfo name="DOI" value="10.17487/RFC6750"/>
      </reference>

      <reference anchor="I-D.ietf-scim-roles-entitlements" target="https://datatracker.ietf.org/doc/draft-ietf-scim-roles-entitlements/">
        <front>
          <title>SCIM Roles and Entitlements Extension</title>
          <author initials="D." surname="Zollner"/>
          <author initials="U." surname="Vartak"/>
          <date year="2025" month="October"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-scim-roles-entitlements-01"/>
      </reference>

      <reference anchor="I-D.poreddy-scim-role-assignment" target="https://datatracker.ietf.org/doc/draft-poreddy-scim-role-assignment/">
        <front>
          <title>SCIM RoleAssignment Draft Specification</title>
          <author initials="P." surname="Poreddy"/>
          <date year="2025" month="November"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-poreddy-scim-role-assignment-01"/>
      </reference>

      <reference anchor="I-D.ietf-scim-use-cases-reloaded" target="https://datatracker.ietf.org/doc/draft-ietf-scim-use-cases-reloaded/">
        <front>
          <title>System for Cross-domain Identity Management: Definitions, Overview, Concepts, and Requirements</title>
          <author initials="P." surname="Correia"/>
          <author initials="P." surname="Dingle"/>
          <date year="2026" month="January"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-scim-use-cases-reloaded-02"/>
      </reference>

      <reference anchor="NIST-SP-800-207" target="https://doi.org/10.6028/NIST.SP.800-207">
        <front>
          <title>Zero Trust Architecture</title>
          <author initials="S." surname="Rose"/>
          <author initials="O." surname="Borchert"/>
          <author initials="S." surname="Mitchell"/>
          <author initials="S." surname="Connelly"/>
          <date year="2020" month="August"/>
        </front>
        <seriesInfo name="NIST" value="SP 800-207"/>
      </reference>

      <reference anchor="GDPR" target="https://eur-lex.europa.eu/eli/reg/2016/679/oj">
        <front>
          <title>Regulation (EU) 2016/679 (General Data Protection Regulation)</title>
          <author>
            <organization>European Parliament and Council</organization>
          </author>
          <date year="2016" month="April"/>
        </front>
        <seriesInfo name="OJ" value="L 119"/>
      </reference>
    </references>

    <section anchor="acks" numbered="false">
      <name>Acknowledgments</name>
      <t>
        The author thanks the IETF SCIM Working Group for prior work on <xref
        target="RFC7643"/> and <xref target="RFC7644"/>, and the broader identity
        community for ongoing discussions on multi-tenant provisioning.
      </t>
    </section>

    <section anchor="changelog" numbered="false">
      <name>Change Log</name>
      <t>draft-kushwaha-scim-tenant-resource-00: Initial submission. This
        revision, relative to the author's working draft, incorporates the
        following substantive changes:</t>
      <ul spacing="compact">
        <li>Set the document stream to IETF with intended status Standards Track
          (the prior "independent + standards-track" combination was
          inconsistent).</li>
        <li>Added <xref target="related"/> positioning this work against
          RoleAssignment, Roles and Entitlements, and the SCIM use cases, and
          removed tenant-local "roles"/"entitlements" from the User membership
          object in favor of RoleAssignment.</li>
        <li>Replaced the separate "precedence" and "conflict" rules with a single
          resolution rule based on the highest-precedence authenticated indicator
          and added the Tenant Binding Invariant (<xref target="resolution"/>).</li>
        <li>Closed the conflict/enumeration oracle by making the 400 conflict
          response reachable only after the authorization gate
          (<xref target="resolution-errors"/>).</li>
        <li>Added identifier canonicalization (<xref target="canon"/>) and
          handling of multi-tenant administrative clients (<xref
          target="multi-tenant-admin"/>).</li>
        <li>Added an explicit lifecycle state machine with cascade and deletion
          rules (<xref target="lifecycle"/>).</li>
        <li>Added concurrency and PATCH-targeting requirements for membership
          mutation (<xref target="concurrency"/>).</li>
        <li>Specified the cross-tenant-client contract for tenant-scoped
          uniqueness (<xref target="compat"/>).</li>
        <li>Corrected the Tenant primary schema URI to the "core" namespace and
          added an HTTP field-name registration; softened the JWT claim
          registration to provisional (<xref target="iana"/>).</li>
      </ul>
    </section>

  </back>
</rfc>
