Friday, 26 October 2018

WebAuthn Authentication in AM 6.5

ForgeRock AccessManagement 6.5, will have out of the box integration for the W3C WebAuthn. This modern “FIDO2” standard allows cryptographic passwordless authentication – integrating with a range of native authenticators, from USB keys to fingerprint and facial recognition systems found natively in many mobile and desktop operating systems.

Why is this so cool? Well firstly we know passwords are insecure and deliver a poor user experience. But aren’t there loads of strong MFA solutions out there already? Well, there are, but many are proprietary, require complex integrations and SDK’s and ultimately, don’t provide the level of agility that many CISO’s and application designers now require. 

Rolling out a secure authentication system today, will probably only result in further integration costs and headaches tomorrow, when the next “cool” login method emerges.

Having a standards based approach, allows for easier inter-operability and a more agile platform for change.

AM 6.5 has introduced two components to allow this to happen: A WebAuthn registration node and a WebAuthn login node. Super simple drag and drop nodes that can augment existing authentication journeys or simply be used on their own.

To demonstrate, take a look at the following user experience flow. This is using a Samsung S8 Edge mobile with fingerprint authentication enabled, accessing AM 6.5 via a Chrome Canary browser. This flow is registering my “credential” against AM.

So what just happened? Well, basically AM triggered some client side JavaScript, that accessed the new credentials management API now available in the Chrome v70 browsers – you can also find it in the latest Microsoft Edge and Firefox browsers too. This API interacted with the Android OS to trigger a security key flow. The Android device then triggered a user interaction for a finger print, which caused a new public/private key pair to be generated and mapped to the user and relying party (AM) triggering the event. The public key was sent back to AM, whilst the private key was stored in the local device’s secure element.

On the AM side, this was simply using a standard intelligent authentication tree and the native callbacks.

So I’ve now registered some credentials. What can I do with that?

Well basically, we leverage that credential during login. Take a look at this video that shows the login journey.

Hardly rocket science eh? So here, again AM triggers some client side JavaScript that initiates the native OS prompting me for a fingerprint to locally authenticate to the device. On result of that, the device can react to a challenge response flow that AM initiates. I basically prove ownership of the private key to the corresponding public key that AM has against my user profile.

Once complete, I’m authenticated and redirected to my user profile as normal. Simples. And not a password in sight.

The powerful aspect is really the interchangeability. An app owner can easily change authenticators, without having to change the backend server side deployment. No complex code changes, or SDK roll-outs, or device integration. Simple and secure with excellent agility.

Tuesday, 2 October 2018

OAuth2 Key Rotation in AM 6.5

With OAuth2 being the defacto authorization model many of our customers use, we made a few improvements to how AM handles the use of secrets in v6.5 that is released later this year.  The nightly build features some neat improvements in the secrets management API.

The API has been overhauled, to make it simpler to use, simpler to integrate and more secure.  As you'd expect. A neat focus was on simplifying the use case of key rotation.  Rotation is an essential part of deployment models - either as a reaction to a breach (and implementing the 3 R's paradigm) or a simple best practice.  Here I'll show a simple demo for rotating an RSA key used to sign OAuth2 stateless access tokens.

Firstly few intro bits regarding the new Secrets Management setup.  We now have a new global configure option, for Secret Stores.

Here we see two out of the box key stores configured.  The basic Java keytore.jceks and a default-passwords-keystore used for bootstrapping access.

The default-keystore config, is useful for testing and dev, where you can quickly access the local file system based Java keystore.  The config for this is pretty straightforward.  The entrypass and storepass settings are de-referenced in the default-passwords-store, where these encrypted values are read from the filesystem to bootstrap access.

In production, many customers tho are likely to want to integrate with PKCS#11 fronted Hardware Security Modules (HSM's) or even a cloud vault.

Within the keystore configuration, there is a new mappings tab.  This tab is the interesting aspect with respect to rotation.  Here we can add in active and multiple secondary keys for specific purposes.  These purposes allow focused use of keys within the secrets API.  A general good practice is to have very focused use of key material, which is declared and can't be mis-configured.

Each secret id maps to the internal secrets API.  The active alias is the one currently in active circulation.  Clicking within an id, shows that other secondary alias's can be setup.  If for example, verification of an access_token fails with the active key, the secondary ones are tried.  Depending on what token type is presented to AM, if a JWT, AM can quickly match the kid in the header and map the appropriate secondary keys in the list.

The alias names are mapped into whatever is in the keystore.

So what does this mean in reality?  Well let me setup my OAuth2 provider to use the detault.rsa.sig.key signing alias for my stateless access_tokens.  Within the realm level OAuth2 service, click on the new Secrets tab.  This shows the default mappings come from my keystore.  On the Advanced tab, make sure to change the signing algorighm to be RS256.

After switching my provider to use stateless JWT's and not stateful server side tokens, I go through and issue myself a bearer token payload...with a nice access_token.

Lots of letters in that one.  Net-net, if I quickly decode the stateless access_token header, I see it was signed with a key id of the following:

If I now introspect the token against the ../oauth2/introspect endpoint, all is good and the token is good to go.

So, now I want to introduce a new signing key to the situation.  There are numerous ways to generate keys, so do this the way you feel is best.  I created a simple script, that creates a 2048 bit RSA private key, then imports into my AM ../openam/keystore.jceks file.

If I do a keytool -list on that keystore, I will see the my new key called newrsasigningkey:

So far so good.  I now simply update the mapping in my keystore config to use my new key and also make the new key my active key.

This basically means, that any new access_tokens being issued, will be signed with the new key,  and any inbound token that needs verifying, will try the new key first, then fall back to use the original test key second.  Simply allowing existing tokens signed with the old key to be validated correctly.

An access_token issued with the newrsasigningkey will have a new key id in the JWT header:

However, both the first and second access_tokens issued can be verified by the ../introspect endpoint.

Another neat bi-product, is that all of the configuration done via the UI above, could be done simply by using the native REST API's.  Easily viewable in the API explorer.  Simply copy and paste the necessary code widget into your app.

NB - worth noting, that when you create the new test key, make sure that the storepass entered via the keytool, matches that in the entrypass value in AM.