Okta Multi-Tenant Architecture¶
- Status: Accepted
- Deciders: shasca
- Date: 2025-04-10
Context and Problem Statement¶
CIAM needs to be able to support both external and internal applications and API usage. In OKTA, external and internal users and groups are segregated into different Okta ORGs. Okta ORGs do not have the capability to interact with each other's components. In this case, the authorization servers defined for APIs in Okta cannot trust tokens minted from auth servers in different ORGs. Front end and experience API applications have the ability to be deployed externally, but process APIs should be located centrally internally. An external Experience API would not be able to perform token exchange with the auth server for a Process API.
This decision decides the architecture to resolve this problem and establish both internal and external application/API cloud integrations.
Considered Options¶
Hub and Spoke¶
This option involves creating an Okta application hub organization. The application clients, authorization servers, and application permissions would be declared and maintained in the hub org, while users, AD federation, and AD group membership are maintained in the internal and external Okta orgs. The hub is populated by users through an Org2Org configuration that will just-in-time provision users into the hub org when they first access the application.
This method allows all API authorization servers to be located in the same Okta org and establish trust between different API authorization servers, which will allow for the token exchange flow required for one app/API to be authorized to call into another.
graph TD
A[External ORG<ul><li>Users</li><li>AD Federation</li><li>Business Roles</li></ul>] --> B[Hub Org<ul><li>OIDC Clients</li><li>Auth Servers</li><li>App Perms</li></ul>]
C[Corp ORG<ul><li>Users</li><li>AD Federation</li><li>Business Roles</li></ul>] --> B
D[CIAM App] --AUTHZ--> B
Duplicate Okta API/App artifacts¶
This option involves maintaining an internal and external org configuration that is used by the following:
- Terraform
- Front Door/APIM
- Azure App Configuration/KeyVault
- API tooling
This option will involve Terraform maintaining an internal and external configuration per app or API. The API Management and front door layers will handle interacting with JWT tokens created by both internal and external orgs. The API cloud platform NuGet packages will choose what configurations to use when interacting with Okta via information provided in the request.
Config Diagram
graph TD
A[Terraform] -->|<ul><li>OIDC Clients</li><li>Auth Servers</li><li>App/Business Roles</li></ul>| B[External ORG]
A -->|<ul><li>OIDC Clients</li><li>Auth Servers</li><li>App/Business Roles</li></ul>| C[Corp ORG]
A -->|<ul><li>Client ID/Secrets</li><li>Org/Auth Server URLS</li></ul>| D[Azure App Config]
Auth Diagram
graph TD
A[CIAM App] <--Determine EXT/CORP--> D[Azure Config]
A --AuthZ<br>w/ext config--> B[External ORG]
A --AuthZ<br>w/corp config--> C[Corp ORG]
Decision Outcome¶
Chosen option: "Duplicate Okta API/App artifacts"
This option adds a bit of configuration-based complexity, but in the long run is a simpler implementation based on the following:
- Okta Hub/Spoke proved to be a complex setup requiring objects created in both hub and spoke that reference each other for each app/API
- This would create complex pipeline/Terraform automations
- Increase difficulty to maintain declaration/deployment infrastructure
- Okta hub/spoke AD -> Okta group -> app role relationships would likely be difficult to maintain and automate
- Duplicate configuration option changes many existing Terraform/app artifacts, but the changes are not overly complex
- Duplicate configuration option simplifies tenant/user/authorization configuration per tenant, which will make for a smoother eventual transition to Entra ID from Okta