Many companies want to use modern identity and access management (IAM) capabilities in their software to improve the customer experience and stay competitive. But building a complete solution from scratch with these advanced behaviors would be difficult and expensive.
Companies are attracted to modern authentication options, such as Google sign in, using a password the user will not forget or passwordless login methods such as WebAuthn. Business use cases also need to be handled, for example, enabling a business partner to sign in with their own SAML identity provider, or enabling call center operatives to securely operate on behalf of a user using Client Initiated Backchannel Authentication (CIBA).
These features are enabled via the OAuth family of specifications, where you externalize the difficult security work to a third-party authorization server, provided by experts. Your APIs, web apps and mobile apps then receive tokens after users authenticate, resulting in much simpler application code, and delivering a security behavior that is easier to extend over time.
Meanwhile, your business domain will deal with user transactions of some form, such as purchases, insurance claims or medical records. This is typically mapped to users based on database IDs, and in some systems these transactions may have existed for 10 years or more:
One of the difficult areas of integrating the IAM system is designing how applications will identify users from OAuth tokens in business terms. This requires insight, but once you have it, you can continue to increase your business data while also using the latest security features.
In this post, I will drill into the details of integrating the business and IAM worlds. The goal is to help companies clarify their requirements before changing security code in their apps. There will be a focus on end-to-end flows and providing your apps with the identity data they need.
The starting point for migrating to OAuth varies between companies. It used to be common for websites to manage their own credentials, perhaps storing hashed passwords in a database. Or you may be using social logins, via Google or Facebook, but are limited to simple authentication. Lastly, you may be using an authorization server but with only basic features and annoyances.
Engineers at software companies may not always see a clear migration path for integrating an IAM system. In the following sections, I therefore propose some high-level steps that can be taken regardless of the source system’s architecture. Each of these steps involves some design details that companies need to understand and adapt to their specific use cases. You will then be able to manage the migration in a risk-free manner.
Step 1: Design User Account Data
In an OAuth architecture, there are always two sources of user data: business data and identity data. In a simple system, you may decide to move most user fields to the identity data, where it can be managed via a built-in SCIM API. It is often possible to migrate passwords without needing to change them:
It is usual to move at least some personally identifiable information (PII) to the IAM data so that privacy concerns can be managed and audited there. Applications then receive this data in tokens and in some cases may store a read-only denormalized copy of it.
Where you store business-focused user fields can require careful consideration according to your use cases. In some corporate platforms I’ve worked on, multiple large products were used, with complex business rules that changed often, so it was considered more convenient to keep roles and permissions within the business data. In a medical system, a patient identifier might be used in an authentication screen, but you may prefer not to move that value to the identity data.
An alternative option is to only store limited user fields within the IAM data and to link the business data to the identity data. The IAM system should allow you to manage user data in the way that works best for your business.
Step 2: Design API Access Tokens
Access tokens should be handled securely, via the Phantom Token pattern, but ultimately each API will receive a JWT access token. By default, this will only identify the user via a subject claim, which is most commonly a generated UUID (universally unique identifier) that is not useful to business-focused APIs:
To enable business continuity, your APIs will need to receive tokens whose claims identify the user in business terms, as in these examples:
During token issuing, the IAM system may need to securely reach out to your business data to read domain-specific user attributes. These are then issued as claims that your main APIs can trust and use for authorization.
Step 3: Design End-to-End Flows
Once you have designed your data, you must decide how end-to-end flows will work after migration to the OAuth system. For an existing user, the flow might look like this, where there is no impact on end users, since existing passwords are used, and no impact on APIs since the user’s existing identifiers are supplied:
You also need to account for new users who will onboard after the migration to the OAuth architecture. New users may also need to be created in the business data, and one option is to do this via a custom action during authentication:
The IAM system will most likely provide out-of-the-box user verification features such as email and SMS. Look for good general extensibility in terms of custom authentication screens and custom actions that can involve your business data when needed.
A familiar way to visualize this is the way in which medical or government systems often present a series of screens during authentication. These screens prompt for various factors, which might include patient identifiers or government eIDs. After the details have been entered, the IAM system may then need to call out to domain-specific APIs to validate the values submitted.
Another area to understand is how to manage changes to the primary authentication method, which will duplicate user accounts by default. Instead, the IAM system should allow you to achieve the following picture, where multiple authentication methods are linked to the same business identity:
The IAM system will provide account linking features to enable this, which requires two high-level capabilities. Firstly, scripted actions should enable you to work with attributes from both the primary account and the external system to match them together, such as by email. Secondly, when the logic is not deterministic, the user can be prompted to prove their identity via an existing authentication method, as part of onboarding to a new method.
Step 4: Make User Updates
Once you understand how end-to-end flows will work, the next step is to populate the IAM system with existing users. This is a scripted ETL process that consists of three steps that you should be able to run and retry multiple times with minimal or no impact on your current system.
First, migrate credentials by connecting the new IAM system to the existing credential store or import credentials via SCIM. Next, migrate user data to the IAM system, which will create an account ID for each user. Finally, update the business data if required.
You also need to account for user edit operations, and it is common to update existing user edit screens to save data to two data sources:
Always ensure that you can join the data between the two sources at rest. This will ensure that future IAM migrations are possible, in which case the account identifier or subject claim will be updated with a value from the new provider. For this reason, the subject claim should not be used as a foreign key in your business data.
Step 5: Implement Proof of Concept (POC) Applications
There is a learning curve to implementing OAuth and OpenID Connect flows in applications for teams who have not done so before. Demo apps can be useful here to pave the way for your flagship applications. This can involve coding simple UIs with a couple of screens and doing enough work to sign off on UX, reliability and data integration.
The application guidance and support you receive from your IAM provider is also important, since best practices for each type of app may have its own nuances that you may need help with. Also aim to keep code portable and standards-based to avoid vendor lock-in:
When done correctly, this will result in simple application code and extendable security behavior, all by just reconfiguring the IAM system. Over time, you will do more work within the IAM system to deal with other security scenarios. This will use the large building blocks provided, which are continually being improved for you.
Once the previous design steps have been completed for your use cases, and after some initial work, you will have clarified your requirements of what you need from the IAM system. A good approach can be to collect these into a list consisting of core behavior related to end-to-end flows, advanced security features and application guidance.
Some IAM providers may not support all of the behavior you need since the best OAuth solutions require good extensibility in addition to support for security standards. Therefore, before committing to an implementation, ensure that you can work around any limitations so that you can guarantee business continuity.
Integrating identity into your business domain requires insight and can require different data flows depending on your use cases. The IAM system should be used as a toolbox that allows you to customize the important areas.
At Curity, we solve identity problems every day and support many standards. We understand, though, that companies also need extensibility features. We support all of the behaviors from this post and also provide a wide range of learning resources to help you along the way:
- Integrate Identity with Business Data
- Introducing the Neo-security Architecture
- Identity and Access Management Primer
- Application Guides
Feature image via Pixabay