Pages

Wednesday, 11 April 2018

Zero Trust at Authentication & Authorization Time

In the current focus on zero trust architectures (Google Google's Beyond Corp approach)... it can be quite useful to start to look for subtle differences between the context at login time and the context that is captured and presented during resource access time.


The classic flow is something like the following:

Using context captured at authN time at authZ time

Contextual data is captured during authentication, which at its most basic, could be IP, User-Agent or geo-location.  That information is then stored against the user’s profile (or anywhere accessible in honesty).  

Zero Trust and CARTA


That information is then retrieved and compared at authorization time – following Forrester's Zero-Trust model, or Gartner’s CARTA (Continuous Adaptive Risk & Trust Assessment) concept.  Any slight changes that may have occurred in the time since login, will be captured and, even if the session/cookie/access_token is live and valid, if the context has altered access is denied, redirected, audited differently and so on.

Why is that important?  Numerous scenarios can arise when token validity is not enough.  What about session hijacking, man-in-the-middle (MITM) attacks, replay attacks and so on?  Applying a layer of context provides a type of access binding, similar in concept to things like proof-of-possession.  Reducing the gaps that may exist between token issuance and token use.

The classic half-parabola, sees assurance at its highest just after login time – perhaps the application of MFA has provided a nice high value.  But the seconds, minutes and hours after the initial login, will see the level of associated trust degrade:

Degrading assurance as time goes by



So by the time the user is accessing resources, long after authentication time, the actual assurance could be low.  To solve this, things like step-up or transaction based authentication can be used to regain trust.

Another approach, is the concept of “continuous” access.  This takes the above and makes tiny interruptions, in an attempt to re-calibrate the trust level up again.  This can result in a “saw tooth” trust concept:

Continual trust "bounce"

Capturing Context At Login Time

So let's create a basic authentication tree in ForgeRock AM looking something like the following:

Basic tree capturing IP and User Agent


So we just group together the Save IP To Profile and Save User-Agent To Profile nodes after a success DataStore authentication has taken place.

The settings for each capture node, allow for the hashing of the captured value.  This is important for privacy preservation (also worth noting that consent would be needed and end user notification given, explaining that this level of information is being stored…).


Optional hashing of context data


So a basic login, using already available fields, would look something like the following:


Example of context storage



Great.  So how can we use this stuff at authorization time?  Pretty simple really.  We just use a scripted authorization condition to check the inbound values against those stored on the user profile.


The newer agents 5.0 (https://backstage.forgerock.com/docs/openam-jee-policy-agents/5/java-agents-guide/#jee-agent-continuous-security) or simple REST calls via IG or native apps, can provide AM with any environmental attribute.  

Integration Over REST


A simple request to the ../openam/json/policies?_action=evaluate endpoint looking like the following would do it:

{
    "resources": [
    
        "http://app.example.com:8080/main.html"
    
    ],
    
    "application":"ResponsiveAccess",
    
    "environment" : {
        
        "IP":["127.0.0.5"],
        "User-Agent": ["Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.37"] 
        
    }
}


The script evaluates both the inbound context and the static context on the user profile.  Any differences would result in the necessary advice being triggered:

Mismatch advice



Integration Using Policy Agents


The newer agents 5.0 can provide access to continuous security header and cookie data, when making a call into the AM policy decision point.  This is pretty trivial to setup.

Within the agent profile, specify what context data to capture and submit.



Hear we're just adding the User-Agent - the requesters IP arrives by default, in a attribute called requestIP (see for more details - https://backstage.forgerock.com/docs/openam-jee-policy-agents/5/java-agents-guide/#j2ee-agent-continuous-security-properties).

That is all there is to it.  Within the protected resource policy, simple reference the Zero Trust script to compare the user-agents and IP addresses.



To demo this, simply login via the capture context tree to save the necessary user-agent and IP address.  Using a user-agent spoofer (there are loads of them out there...) alter your browser and see the immediate change to 403 in the PDP response.  Whilst the agents cache, the cache is keyed against not just the protected resource, but also the associated environmental payload object that contains the contextual data.  Hence even a slight change, results in immediate denial of access.

NB - this blog was updated August 2nd 2018 with reference to Google and new screen shots.