Skip to main content

Creating Personal Access Tokens in ForgeRock AM

Personal Access Tokens (PAT's) are used to provide scoped self-managed access credentials that can be used to provide access to trusted systems and services that want to act on a users behalf, or access user data.

Similar to OAuth tokens, they often don’t have an expiration and are used conceptually instead of passwords.  A PAT could be used in combination with a username when performing basic authentication.

For example see the page within Github which allows scope-related tokens to be created for services to access your Github profile.  Here Github allows you to provide a token that can gain access to services and data stored on Github.  The token is used in conjunction with your username over basic authentication.

PAT Creation

The PAT can be an opaque string - perhaps a SHA256 hash.  Using a hash seems the most sensible approach to avoid collisions and create a fixed-length portable string.  A hash without a key of course wont provide any creator assurance/verification function, but since the hash will be stored against the user profile and not treated like a session/token this shouldn't be an issue.

An example PAT value could be:

f83ee64ef9d15a68e5c7a910395ea1611e2fa138b1b9dd7e090941dfed773b2c:{“profile” : [ “givenName”, “fullName”, “mail” ] }
a011286605ff6a5de51f4d46eb511a9e8715498fca87965576c73b8fd27246fe:{"profile" : [ "postalladdress", "mail"]}

The key was simply created by running the resource and the associated permissions through sha256sum on Linux.  How you create the hash is beyond the scope of this blog, but this could be easily handled by say ForgeRock IDM and a custom endpoint in a few lines of JavaScript.

PAT Storage

The important aspect is where to store the PAT once it has been created.  Ideally this really needs to be stored against the users profile record in DJ.  I'd recommend creating a new schema attribute dedicated for PAT's that is multi-valued.  The user can then update their PAT's over REST the same as any other profile attribute.

For this demo I used the existing attribute called "iplanet-am-user-alias-list" for speed as this was multi-valued.  I added in a self-created PAT for my fake resource:

Using a multi-valued attribute allows me to create any number of PAT's.  As they don't have an expiration they might last for some time in the user store.

PAT Usage

Once stored, they could be used in a variety of ways to provide "access" to other users, application, service accounts or personas of yourself.  The most simple way, is to leverage the AM authorization engine as a decision point to verify that a PAT exists and what permissions it maps to.

Once the PAT is stored and created, the end user can provide it to another user/service that they want to use the PAT.  That service or user presents the username:PAT combination to the protected service they houses the data they want to gain access to.  That service calls the AM authorization API's to see if the user:PAT combination is valid.  A typical resource server to authorization server dance in the OAuth2 world.

The protected service would call {{OpenAM}}/openam/json/policies?_action=evaluate with a payload similar to:

Here I am calling the ../policies endpoint with a dedicated account called "policyeval" which has ability to read the REST endpoint and also read realm users which we will need later on.  Edit the necessary privileges tab within the Admin console.

If the PAT exists within the user profile of "smoff", AM returns an access=true message, along with the resource and associated permissions that can be used within the calling application:

So what needs setting up in the background to allow AM to make these decisions? Well all pretty simple really.

Create Authorization Resource Type for PAT's

Firstly create a resource type that matches the pat://*.* format (or any format you prefer):

Next we need to add a policy set that will contain our access policies:

The PATValidator only contains one policy called AllPATs, which is just a wildcard match for pat://*:*.  This will allow any combination of user:pat to be submitted for validation:

Make sure to set the subjects condition to "NOT Never Match" as we are not analysing user session data here.  The logic for analysis is being handled by a simple script.

PAT Authorization Script

The script is available here.

At a high level is does the following:

  1. Captures the submitted username and PAT that is part of the authorization request
  2. As the user will not have a local session, we need to make a native REST call to look up the user
  3. We do this by first generating a session for our policyeval user
  4. We use that session to call the ../json/users endpoint to perform a search for the users PATs
  5. We do a compare between the submitted PAT and any PAT's found against the user profile
  6. If a match is found, we pull out the assigned permissions and send back as a response attribute array to the calling application


There are any number of ways to create and use PAT's.  Another option for use, could be a custom authentication module that takes the username and hash and perform an authentication test.  The hash in this case would likely need a salt and some other storage protection mechanisms.

A third approach would be to integrate into the OAuth2 world, but this would require a bit more effort, especially with respect to token creation and scope mapping.


Popular posts from this blog

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 chan

Implementing Zero Trust & CARTA within AM 6.x

There is an increasing focus on perimeterless approaches to security design and the buzzy "defensive security architectures".  This blog will take a brief look at implementing a contextual and continuous approach to access management, that can help to fulfil those design aspirations. The main concept, is to basically collect some sort of contextual data at login time, and again at resource access time - and basically look for differences between the two.  But why is this remotely interesting?  Firstly, big walls, don't necessarily mean safer houses.  The classic firewall approach to security.  Keeping the bad out and the good in.  That concept no longer works for the large modern enterprise.  The good and bad are everywhere and access control decisions should really be based on data above and beyond that directly related to the user identity, with enforcement as close as possible to the protected resource as possible. With Intelligent AuthX, we can start to collect an

Set Session Limits Using Context

Session limits typically cover 4 main items: total number of sessions a user can have at any one time, the max length of each session, the max idle time and max caching time. In an out of the box deployment in ForgeRock AM, these settings are configured via the session service.  However there are few tweaks than can be made to allow these settings to be run via a per user or per tree flow.  For example. think of the following scenario - user is logging via a device, location or network that has a higher risk rating.   Perhaps you would like to reduce session length on a BYOD device running an out of support version of Android to have a length of only 15 minutes.  If they switched back to their main trusted device, we can spin that back to 1hr. Another example, could be the spotting of a higher suspicion of bot activity for a particular user.  Maybe we need to set the entire quota limit to 1, to stop a bot spawning multiple sessions with the same credentials. This is all pretty trivial