amr claim? In my id_token? It's more likely than you think
- Mike Woodburne
- Jul 12
- 8 min read
As much as everyone loves to authenticate over and over again when trying to do work online, there are times when you just want to say "enough is enough - I've authenticated multiple times and I'm not going to authenticate anymore!" and it's my professional opinion that this is a reasonable position to take. After all, what good is it to have a strong security posture on your platform if nobody wants to use it because you've made it too secure? And what better way to drive away users than to authenticate them to death? I've come bearing good news, and that good news is that you don't always have to beat your users to death with additional authentication steps.
I'll take a brief pause to wait for the cheers to subside.
All done? Great! Let me tell you a bit more about what is on my mind.
Background
In this past year I've worked with multiple customers who are building out their SSO platform ("the platform") and have come across the following situation:
Security wants every user of the platform to perform MFA, no questions asked
Business partners who are using the platform want to bring their own identities via their own modern identity provider
The business partner's identity provider has their own policies around when multiple authentication factors are needed, and their users don't want to have to perform MFA with their identity provider and then have to perform it again on the platform
Sounds familiar? You aren't alone. Both sides of this story have reasonable and defensible positions, and both sides deserve to have their needs met. The good news here is that not only is this possible, there are also multiple ways to tackle this and most of them are pretty straightforward to do with most commercial IAM solutions.
A Quick Primer on Federated Authentication Assertions
Since SAML 2.0 and OpenID Connect 1.0 we have had the ability to request an Authentication Context from our identity providers, which is to say that as a service provider or relying party we have had the ability to ask our identity providers to authenticate users using previously agreed upon means, and as identity providers we can communicate back details about how we authenticated the user. This ability has continued to mature over time and the use of acr in OIDC has grown to become a critical part of frameworks such as Open Banking and FAPI profiles.
One area where Authentication Context falls short is that it focuses on communicating a level of assurance in the transaction, but does not always give the consumer the details of how that level of assurance was achieved. This was addressed in OpenID Connect 1.0 through the use of the amr (or Authentication Method Reference) claim, and further clarified through RFC 8176 which establishes a registry of amr values and defines an initial set of amr values. The amr claim is an array of one or more values that tell the consumer how the user was authenticated, which in turn gives us clarify as to how the assurance level of an Authentication Context was achieved. Authenticate the user via password? Add a "pwd" value to the amr claim. Was the user also authenticated through a fingerprint in addition to the password? Add an "mfa" and a "fpt" value to the amr claim along with the "pwd" value. I like to think of Authentication Context (or acr) as ordering a gluten-free chocolate cake (which, by the way, if you are ever on Maui you need to check out Pearl Island Bakery's gluten-free chocolate cake which you can get on Saturday mornings at the Upcountry Farmer's Market), and Authentication Method Reference (or amr) as giving us the list of ingredients.
Ok, so.... what?
I can hear you already - enough about the gluten free cake (although I bet you are getting hungry, right?) tell me how I can apply this in a way that allows me to reduce friction when authenticating our business partners! Well, as I mentioned above one of the values you can get in an amr claim is "mfa", which tells you as the consumer that the user was authenticated through multiple factors. This means that when I am receiving an id_token from a business partner, I can check the amr claim and if the claim includes the value "mfa" I can trust that to mean that the user's identity was verified by multiple factors of authentication. I can then use this information to choose to no longer prompt this user for additional factors of authentication, simplifying the authentication experience for our business partners.
What does this look like?
Obligatory Sequence Diagrams
Let's start with the less-than-ideal scenario, where both the partner and the platform are asking the user to perform MFA.

Next, let's see what it looks like when the business partner doesn't choose to prompt their user for additional authentication factors.

Finally, this is the flow when the business partner requests multiple authentication factors from the authenticating user.

For the end user in the second and third diagrams the friction is the same - they are going to end up providing two authentication factors. Who they provide those factors to isn't an issue, because all of the parties involved are talking to each other and communicating their actions to one another. It's really sweet, if you think about it.
That's great, but how is it done???
This blog post would probably make me sad if I were reading it and I didn't get any details on how I could implement something like this, and the last thing I want to do (today) is make you said. Since I know that solutions targeted towards Ping Identity are what make my readers happy, what better way to ensure we all have a great day than to provide details on how to implement a solution like this using PingOne Advanced Identity Cloud (P1AIC) and the PingOne Cloud (P1) platform. In this walkthrough P1AIC will play the role of the SSO platform, and P1 will be the business partner's identity provider.
Create an Application in PingOne
In your P1 environment, configure a new Application as Web App with your AIC tenant's AM endpoint (e.g. https://mytenant.forgeblocks.io/am) as redirect URI. Since you are going to use this in a federated login, you should probably assign the profile and email scopes to the application so you can get the data you'll need to link the P1 user with the P1AIC user. Don't forget to enable the Application when you are done!
Configure a Social Identity Provider in PingOne Advanced Identity Cloud
In the Access Management native console go to Services -> Social Identity Provider Service and set up a new Secondary Configuration for P1. Make sure to include the same scopes you assigned to the P1 Application, and configure the same redirect URI.
PROTIP: Save the client secret as an ESV and map the ESV to the Client Secret Label Identifier, because if you don't you are going to have to enter the client secret every time you save this page and you will forget. When you do forget, you will see an error in your AM logs for "failed to handle post auth" and you will have to re-save the config.
PROTIP PART 2 - ELECTRIC BOOGALOO: Use the UI Config properties to set a display name to be shown on the login screen or else the button will just say "Sign in with" and that is confusing to most people. The config property key is "buttonDisplayName", and the value is whatever you want that button to say after "Sign in with". There are more properties you can set but I'll never tell you what they are (unless you ask).
Configure Your P1AIC Journeys
I'm not going to walk you through the whole journey config, but you can see the journey below. This is not a production journey and should not be treated as one, but it gives you the building blocks you need. You can get the basics of how to set up Social Identity Provider authentication here.

The "magic" in this journey is happening in the Scripted Decision Node, which is checking the id_token from the social identity provider for the presence of an amr claim with a value of "mfa". The code for it is:
var outcomeMFANeeded = "true";
var AMR_MFA = "mfa";
var claims_set = nodeState.getObject("claims_set");
if ((claims_set) && (claims_set.amr) && (typeof claims_set.amr.indexOf === "function") && (claims_set.amr.indexOf(AMR_MFA) > -1)) {
outcomeMFANeeded = "false";
}
action.goTo(outcomeMFANeeded);That's it! The "claim_set" object placed into sharedState by the Social Provider Handler is a reference to all of the claims from the id_token. In this case we are just using it for amr, but I'm sure you are already thinking now about how you could leverage this for acr claims as well. If you aren't thinking about that, take 2 minutes now and mull it over. I'll wait.
The other journey you'll want to configure here is the inner journey for MFA. In this case I set it up for TOTP authenticator, but you can obviously use whatever factor(s) work best for your use case. Again - not a production quality journey, so don't go copying this and act all surprised when you don't like it.

Is This Real?
Of course this is real! Don't believe it? Here is a video showing this configuration in action. Nobody has ever misled someone through the use of a video recording.
Ok, Mike - now what?
Now what? I'm here giving you gold, but I guess that is a valid question. Here is what I would do if I were you:
Take some time to read up about acr, acr_values, and amr. This blog from SecureAuth is a nice quick read and should help fill in some of the gaps I nimbly jumped over in this blog: https://docs.secureauth.com/iam/blog/understanding-acr-and-amr-claims-in-authentication-practical-use-cases
Take a moment (heck, take two) and reflect on how you may be able to apply your newfound knowledge of acr and amr. Perhaps take a look at some of the frameworks that utilize acr and how they map their Authentication Context Reference back to actual authentication factors and identity processes.
Get some chocolate cake.
Implement! Take your tool(s) of choice and build out a simple login flow like what you see here, and then keep that experience in your pocket and take it out at parties. I guarantee everyone will be gathered around you ready to learn!
Additional Notes and Thoughts
I think we could discuss the benefits of when to use acr versus amr until we are blue in the face and just want to go home. The goal of this post wasn't to advocate for one over the other, it was simply to raise awareness around these concepts and share how easy they are to consume as an identity practitioner.
acr and amr both have their shortcomings, which you should familiarize yourself with. As an example, neither one of these claims will give you the context around why or when a user with an existing session ended up with their session and why they ended up authenticating the way they did. Context matters, and it could impact how and when you use these claims.
I think that using a tool like PingOne Protect in conjunction with either of these claims would really help strengthen your risk posture. In my opinion, just because someone authenticated 20 minutes ago using MFA it doesn't mean their session is secure right now (hot take, right? I know, I'm edgy.)

Comments