Skip to main content

Concept: Suborganizations

Introduction

Suborganizations (suborgs) are a key feature of SlashID, designed so you can quickly implement the right user structures for complex applications like multi-tenancy SaaS, multi-sided marketplaces, and similar. Suborganizations are a flexible abstraction that can be mapped to your domain in a number of ways. A few simple examples:

  • Teams: My Organization -> Software Engineering -> Backend
  • Projects: My Organization -> Software Products -> Website
  • Physical Locations: My Organization -> Country -> City -> Address -> Room

This guide explains and demonstrates SlashID suborgs using two case studies. Read on to become familiar with the key concepts of suborgs, see detailed use cases, and use them to understand how to build an effective authentication and authorization infrastructure.

info

You can find an example multi-tenancy CMS application using suborgs in this GitHub repository and a step-by-step guide here.

Meet the Parents: Organizations

Organizations are one of the fundamental concepts in the SlashID ecosystem. They are the central coordination points for other entities, such as persons and groups. Each organization has two properties:

  • A tenant name that identifies the customer that owns it; a single customer can have multiple organizations.
  • An organization name that identifies that organization within the tenant. For example, you may have separate organizations for testing and production.

When you register as a customer with SlashID, you will receive an organization ID and API key per organization. You will use the organization ID in two ways:

  • With the SlashID Javascript or React SDK to identify your organization when your users authenticate
  • As a header in HTTP requests to our endpoints, along with your API key, to identify and authorize API calls

When someone registers as a user of your app using SlashID, a new person is created under your organization. This person exists only inside your organization, and has a unique ID. Even if the same physical individual signs up for a different organization with the same email address or phone number, they will be represented by a completely separate entity within SlashID, with a different person ID.

Meet the Children: Suborganizations

A single standard organization may be enough for your needs: you can use the building blocks of persons, groups, and attributes to quickly develop sophisticated authentication and authorization functionality for your system.

However, there are also more complex use cases where a single organization is not enough; for example if you need to:

  • implement a multi-tenancy SaaS app
  • implement a multi-sided marketplace (where you need to manage multiple distinct user bases)
  • develop and host whitelabel apps for third parties
  • map your company’s physical structure to your authentication/authorization logic (for example, your company has different physical offices)
  • develop multiple customer-facing apps with a shared backend

We will take a deep dive into two of these examples later on.

All these complex use cases have the same need to separate some aspects of user management and authentication, while unifying others. In some cases, you may need to retain a consistent user identity across apps; in some others you may need completely separate user management while retaining a single common admin point. To accommodate the many and varied requirements we discovered while talking to customers and prospects, we developed suborgs, aiming for a flexible but simple API.

What is a Suborganization?

A suborganization is nothing more than a special type of SlashID organization. It has a unique organization ID, an API key, persons, groups, and so on. Suborgs can be used for user authentication and in API calls, just like regular organizations. However, there are some key differences, which we will see in action in the case studies below:

  • Suborganizations can be created using SlashID’s APIs. Unlike normal organizations, you can use the suborgs API to create as many suborgs as you need. When you do so, you must provide the ID and API key for your organization, which becomes the “parent” of the new “child” suborganization.
  • Parent organizations have full control over child suborganizations. To perform administrative actions on an organization, you must provide the API key as a header in the request. For suborgs, you can use either the suborg’s API key or the parent organization’s API key. This means the administrator of the parent organization can retain control over all suborgs, while also giving control to the administrators of individual suborgs by sharing the suborgs’ API keys.
  • Identity, groups, and person attributes can be shared across suborganizations and their parents. As you would expect, standard SlashID organizations are kept completely separate. However, as discussed above, there are use cases where it is useful or necessary to share some information across organizations, and you can configure suborgs to do so.

The two case studies below illustrate these differences step-by-step, showing how suborgs can be used to solve complex problems via a straightforward API.

Case Study 1: Multi-tenant SaaS App

Imagine you are developing a multi-tenant Software-as-a-Service (SaaS) app, which we'll call Entertainment720, which provides multimedia and marketing software for various clients. Each one of your customers has their own instance of your app, which provides authentication and user management out of the box. Each customer needs to operate and be managed separately from the others, with no visibility or data sharing between them. However, as the platform owner, you need to retain some visibility into each instance (for example, to perform analytics).

Implementing with SlashID

Step 1: Set up your Organization

After doing some discovery work, you decide to use SlashID to get secure authentication and user management for your app out of the box.

You register with SlashID and obtain an organization ID and API key. This organization represents your platform, and the ID and key will be used to perform subsequent operations. At this point, you will choose a tenant name and organization name. The tenant name is consistent across all of your organizations (both normal organizations and suborgs), while the organization name is specific to the organization.

Your current structure looks like this:

SaaS Figure 1

Step 2: Create Suborganizations for your Customers

You can now use suborgs to represent your customers. With their own suborg, each of your customers can immediately use SlashID authentication and user management features to onboard and log in their own users.

Creating a suborg for your customers is a simple API call; choose a sub_org_name that helps you identify them:

curl -X POST --location 'https://api.slashid.com/organizations/suborganizations' \
--header 'SlashID-OrgID: <ORGANIZATION_ID>' \
--header 'SlashID-API-Key: <API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"sub_org_name": "Parks & Rec Dept"
}'

This is the response, containing the ID and API key of the new suborganization:

{
"result": {
"api_key": "wY7gDtUDjxGMdynd6BKaaLojHFE=", // API key of the new suborganization
"id": "97724371-a0a1-4b93-bf51-6ba2feb1acdf", // ID of the new suborganization
"org_name": "Parks & Rec Dept", // as in the request
"tenant_name": "E 720" // same as for the parent organization
}
}

The new suborganization will also inherit configuration from the parent, but you can change this via the organization configuration APIs.

Your structure now looks like this:

SaaS Figure 2

Step 3: Share the Suborganization credentials

You can now share the suborg ID and API key with your customers’ administrator(s), and they can begin using SlashID features immediately.

Each one of your customers will have their own user base, groups, and configuration.

You can create as many suborgs as you need:

SaaS Figure 3

Step 4: Gather analytics

Use the API key of your parent organization to retrieve information about the child suborgs; for example, to count the number of users.

caution

The API key of the parent organization grants the same powers as the API key of the child. This means it can be used to access and modify user data, including personally identifiable information (PII), such as email addresses and phone numbers. It is strongly recommended that access to the parent API key is strictly limited and monitored, and is compliant with applicable data protection and localization laws.

Conclusion

In this case study, you have seen the suborgs API used to easily create a multi-tenant SaaS app with secure authentication out of the box, plus fully featured user management, while maintaining both security and visibility.

Case Study 2: Healthcare Platform

Imagine you run a healthcare platform, PolyMed, that connects specialist clinics with patients. Additionally, clinics can also use your platform to manage their clinicians, allowing them to log in and communicate with their patients directly. This is an example of a multi-sided marketplace, as you interact with two distinct user bases (patients and clinicians).

Each patient may attend multiple clinics, but you want a consistent patient identity across all the clinics they attend. Clinicians are also users associated with each clinic, but need to be able to access patient data and other privileged information, so you need consistent access controls in place across all clinics.

You also want to share patient data across clinics easily and securely, when the patient has authorized it. Last, you want to perform analytics on patient onboarding and attendance to clinics.

Implementing with SlashID

Step 1: Set up your organization

As in the previous case study, your discovery process has shown that SlashID provides all the features you need out of the box.

You register with SlashID to obtain an organization ID and API key; your structure looks like this:

Healthcare Figure 1

Step 2: Create suborganizations for clinics

Use the suborgs API to create a suborg per clinic, as in Case Study 1. However, there are two additional features you need this time:

  • Consistent identity across clinics
  • Consistent access control

To implement these requirements, we will use person pools and group pools.

Person Pools and Group Pools

In the first Case Study describing the multimedia platform, each suborg had a completely separate set of users. Even if the same individual had registered with multiple instances of your app using the same email address, there would be no visibility between customers, and the person resulting from each registration would have a unique ID.

In this case, however, you want to have a consistent identity across clinics.

For consistent identity between suborgs, you can create "person pools". This means that if the same person registers with multiple clinics using the same handles (email addresses or phone numbers), they will have a consistent unique identifier in all suborgs sharing that person pool.

Similarly, in the first Case Study, each suborg had its own set of groups to which persons can belong. In this case, you want the same groups in each clinic, as these can be used for access control. Keeping the same set of groups in each suborg means you can have consistent access control across all the clinics on your platform. To achieve this, suborgs can share "group pools". This means all suborgs see the same set of groups, but group membership is specific to the suborg.

Let’s see these in action with the SlashID APIs.

First, you create a suborg for one of the clinics hosted on your healthcare platform, as in the previous case study.

curl -X POST --location 'https://api.slashid.com/organizations/suborganizations' \
--header 'SlashID-OrgID: <ORGANIZATION_ID>' \
--header 'SlashID-API-Key: <API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"sub_org_name": "TrueSight Opticians"
}'

{
"result": {
"api_key": "/cgMbOUYjFGMUv4hIvKoMxhVIJ0=",
"id": "85637a0a-a574-326a-bac3-d1f46d62dbd9",
"org_name": "TrueSight Opticians",
"tenant_name": "PolyMed"
}
}

As before, the response gives you a suborg ID and API key.

Healthcare Figure 2

Now you want to create a second suborg for another clinic. However, you want the two clinics to have consistent identity, meaning they share a person pool - to do this, we specify the persons_org_id in the body. This field specifies which other organization the new suborg shares a person pool with - it can be the parent organization, or any child of the parent.

Similarly, you can set the groups_org_id field to get consistent groups across clinics. Again, this could be the parent, or any child of the parent. It does not have to be the same organization ID as the persons_org_id.

info

If the persons_org_id and groups_org_id fields are not specified, new pools will be created, as in the previous case study.

curl -X POST --location 'https://api.slashid.com/organizations/suborganizations' \
--header 'SlashID-OrgID: <ORGANIZATION_ID>' \
--header 'SlashID-API-Key: <API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"sub_org_name": "PuraDerm Skincare",
"persons_org_id": "85637a0a-a574-326a-bac3-d1f46d62dbd9", // org ID of TrueSight
"groups_org_id": "85637a0a-a574-326a-bac3-d1f46d62dbd9" // org ID of TrueSight
}'


{
"result": {
"api_key": "FkImXyWgZhuqTGTh70fXzuI1PMo=",
"id": "d89e29fc-2693-d3b7-764c-debc9561eea2",
"org_name": "PuraDerm Skincare",
"tenant_name": "PolyMed"
}
}

You finally have two suborgs sharing a person pool and a group pool.

Healthcare Figure 3

You can extend this configuration to an arbitrary number of suborgs by specifying persons_org_id and groups_org_id for each of them.

Step 3: Create groups

Now that you have some suborgs to represent your clinics, you can create the groups needed to manage their users, starting with “patients” and “clinicians”, using the SlashID groups API:

    "api_key": "/cgMbOUYjFGMUv4hIvKoMxhVIJ0=",
"id": "85637a0a-a574-326a-bac3-d1f46d62dbd9",
curl -X POST --location 'https://api.slashid.com/groups' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight org ID
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0=' \ // TrueSight API key
--header 'Content-Type: application/json' \
--data '{
"name": "patients"
}'

curl -X POST --location 'https://api.slashid.com/groups' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight org ID
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0=' \ // TrueSight API key
--header 'Content-Type: application/json' \
--data '{
"name": "clinicians"
}'

We used the organization ID for TrueSight (your optician clinic) to create the groups, and we see that listing the groups for that suborg returns the expected result:

curl -X GET --location 'https://api.slashid.com/groups' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight org ID
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0=' // TrueSight API key

{
"result": [
"patients",
"clinicians"
]
}

The same API call to get groups with the PuraDerm (your dermatology clinic) organization ID returns the same results, as expected since you previously configured them to share a group pool.

curl -X GET --location 'https://api.slashid.com/groups' \
--header 'SlashID-OrgID: d89e29fc-2693-d3b7-764c-debc9561eea2' \ // PuraDerm org ID
--header 'SlashID-API-Key: FkImXyWgZhuqTGTh70fXzuI1PMo=' // PuraDerm API key

{
"result": [
"patients",
"clinicians"
]
}

The same call with the PolyMed parent organization ID shows there are no groups - because the parent is not in the same groups pool as the suborgs.

curl -X GET --location 'https://api.slashid.com/groups' \
--header 'SlashID-OrgID: <ORGANIZATION_ID>' \
--header 'SlashID-API-Key: <API_KEY>'

{
"result": []
}

Step 4: Register clinicians

Now you can register clinicians - let’s register one clinician for each clinic, adding them to the “clinicians” group directly in the person creation API call.

curl -X POST --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0=' \
--header 'Content-Type: application/json' \
--data-raw '{
"handles": [
{
"type": "email_address",
"value": "m.green@truesight.com"
}
],
"groups": [
"clinicians"
]
}'

{
"result": {
"active": true,
"person_id": "0642553c-04f1-77a7-b108-e12cbb52d5a7",
"region": "us-iowa"
}
}
curl -X POST --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: d89e29fc-2693-d3b7-764c-debc9561eea2' \ // PuraDerm
--header 'SlashID-API-Key: FkImXyWgZhuqTGTh70fXzuI1PMo=' \
--header 'Content-Type: application/json' \
--data-raw '{
"handles": [
{
"type": "email_address",
"value": "g.house@puraderm.com"
}
],
"groups": [
"clinicians"
]
}'

{
"result": {
"active": true,
"person_id": "17a2b5720-1d70-22a1-cf18-f6623102d6bf",
"region": "us-iowa"
}
}

You can now see that the members of the “clinicians” group for each clinic are as expected:

curl -X GET --location 'https://api.slashid.com/groups/clinicians/persons' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0='

{
"result": [
"0642553c-04f1-77a7-b108-e12cbb52d5a7" // person ID for m.green@truesight.com
]
}
curl -X GET --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: d89e29fc-2693-d3b7-764c-debc9561eea2' \ // PuraDerm
--header 'SlashID-API-Key: FkImXyWgZhuqTGTh70fXzuI1PMo='

{
"result": [
"17a2b5720-1d70-22a1-cf18-f6623102d6bf" // person ID for g.house@puraderm.com
]
}

Step 5: Register patients

Now you can register some patients. Normally, users would onboard directly via a user-facing authentication frontend using the SlashID Javascript SDK or React SDK, but for the purposes of this guide we’ll use the SlashID APIs. First, create a patient in the PuraDerm clinic:

curl -X POST --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: d89e29fc-2693-d3b7-764c-debc9561eea2' \ // PuraDerm
--header 'SlashID-API-Key: FkImXyWgZhuqTGTh70fXzuI1PMo=' \
--header 'Content-Type: application/json' \
--data-raw '{
"handles": [
{
"type": "email_address",
"value": "mscarn@mymail.com"
}
],
"groups": [
"patients"
]
}'

{
"result": {
"active": true,
"person_id": "2462b5821-1411-26ab-c516-d61251ffdeba",
"region": "us-iowa"
}
}

Listing the persons for each clinic, we see two for PuraDerm (the clinician and the patient), and one for TrueSight (the clinician):

curl -X GET --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: d89e29fc-2693-d3b7-764c-debc9561eea2' \ // PuraDerm
--header 'SlashID-API-Key: FkImXyWgZhuqTGTh70fXzuI1PMo='

{
"result": [
"17a2b5720-1d70-22a1-cf18-f6623102d6bf", // g.house@puraderm.com
"2462b5821-1411-26ab-c516-d61251ffdeba" // mscarn@mymail.com
]
}
curl -X GET --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0='

{
"result": [
"0642553c-04f1-77a7-b108-e12cbb52d5a7" // m.green@truesight.com
]
}

Now register the same patient for TrueSight, using the same email address:

curl -X POST --location 'https://api.slashid.com/persons' \
--header 'SlashID-OrgID: 85637a0a-a574-326a-bac3-d1f46d62dbd9' \ // TrueSight
--header 'SlashID-API-Key: /cgMbOUYjFGMUv4hIvKoMxhVIJ0=' \
--header 'Content-Type: application/json' \
--data-raw '{
"handles": [
{
"type": "email_address",
"value": "mscarn@mymail.com"
}
],
"groups": [
"patients"
]
}'

{
"result": {
"active": true,
"person_id": "2462b5821-1411-26ab-c516-d61251ffdeba",
"region": "us-iowa"
}
}

We can see that the person ID of the newly created patient in TrueSight is the same as the person ID for PuraDerm - this is the consistent identity that you get from sharing a person pool between suborgs.

We can use the person ID to make API calls regarding that person, and that person ID will be the subject claim in tokens issued after successful authentication, for both organizations.

info

It’s important to remember that to have consistent identity, a user must register with the same handle in all organizations and suborgs - but they can add different handles later.

For example, suppose Blake registers with TrueSight using their email blake@mymail.com, then adds their phone number +1234567890 so they can do MFA with OTP via SMS. If an admin of the TrueSight clinic used the API to list the handles for that person ID, they would see both.

Blake could then register with the PuraDerm clinic using either of these handles, and they would get the same ID - because the two suborgs share a person pool. However, the PuraDerm admin would only see the handle used to register with them - we don’t expose a person’s handles until they’ve been explicitly used to register with an organization.

On the other hand, if Michelle registered with TrueSight using her email address, but with PuraDerm using her phone number, she would get different IDs for each, even though they share a person pool - because she used different handles and there’s no way to tie them together.

Step 6: Access control with groups

You now have patients and clinicians belonging to each of the clinics on your platform, each belonging to the appropriate group. You can now start to leverage groups to enforce access control to different resources.

After successful authentication, SlashID issues a signed JSON Web Token (JWT) for the authenticated person. This token includes the set of groups the person belongs to, so your systems can check these values to make authorization decisions - for example, allowing clinicians to see patient data. If these decisions need to be made on the frontend, you can use the SlashID React components and get this functionality out of the box within a few minutes.

Conclusion

In this Case Study, you saw a more complex usecase for suborganizations, including the use of person pools and group pools to keep consistent user identity and groups across suborgs. The combination of suborgs and groups can implement non-trivial structures with a few simple API calls, taking care of the complexities of security and user management.

Summary

In this guide you have explored SlashID suborgs and the APIs to manage them. Suborgs, combined with shared person and group pools, are extremely customizable structures that allow you to model complex use cases with a straightforward set of APIs, providing flexible but secure information sharing where needed. Using these simple building blocks, SlashID gives you the tools to build the authentication and authorization you need, taking care of identity and letting you focus on what’s important to your business.

Look out for future guides and blog posts, where we will deep dive into more case studies to explore DataVault, attribute-based access control (ABAC), and role-based access control (RBAC).

Have questions or want to find out more? Check out our documentation or reach out to us.

Ready to get started with SlashID? Register here!