Understanding OpenAM Remote OAuth2 Consent Service


In this article, we use OpenAM as a synonym for ForgeRock Access Manager. At the time of writing — September 2018 — AM was the current version.

OpenAM can collect the user consent in an OAuth2 flow via its built in consent collector or it can call an external collector. The advantages of an external collector are:

  • It has a fully customizable UI (you write yr own app using whichever UI framework you like.
  • It has a fully customizable reponse (you might want to have a consent decision like “accept”, “deny”, and maybe “cancel” , to cancel the whole flow).
  • It has a fully customizable consent. For example, if you have a parameterized scope as in PSD2 payment transaction, you don’t want to present the scope as “Do you consent to pay for transaction txID 123?" Rather, you want to resolve the txID via an external service so that the consent screen contains a message like, “Do you want Musicstore Inc to withdraw 965 € for certain guitar Fender Telecaster Nashville?”

When AM asks RCS for consent, it sends a signed (optionally, encrypted) JWT to RCS. RCS replies by letting a user-agent POST a signed JWT to AM:

Consent from RCS is gather via signed (optionally enrypted) JWTs.

Configuring OpenAM

Following the documentation in the OAuth2 guide, you need to

Here are my settings for an OAuth2 service and RCS agent:

OAuth2 Authorization Service settings with enabled RCS.

Here are my settings for OAuth2 Authorization Service with enabled RCS:

Settings for RCS agent. Redirect URL and JWK URI are to be set.

A NodeJS RCS service

RCS needs three things:

  1. A URL where AM can get the keys (JWK).
  2. An endpoint for AM to redirect user to.
  3. A method to collect the scope user consented to. In this example, the user will FORM POST the granted scope (“uid”, “mail”, and so on), and RCS will create the JWT.

A sample service (not for production) can be found here: GitHub - steffow/RCS . By design, this service has only the bare minimum of UI so that you can add your favorite framework.

Let’s have a look on what the RCS flow with the above NodeJS service looks like. This assumes you created an OAuth2 client called test on AM. If a user wants to use a certain application, that application will redirect him via sth like:


After successful login (with standard AM try “demo/changeit”), AM will redirect the user to the remote consent service (NodeJS). The RCS will display the required scope: uid mail telephoneNumber:


The sample consent page above is deliberately unformatted, so you can customize it accordingly.

When user selects Sign, that form will be posted to RCS app where the consented scope will be added to the JWT and signed. Note that the uid has not been consented to, and is not part of the scope:

  "clientId": "test",
  "iss": "rcs",
  "csrf": "8+oLdL1CIuRO3pXXCrWWGRR3hFCzhgpZaukufpnBhD4=",
  "client_description": "",
  "aud": "http://id.init8.net:8080/openam/oauth2",
  "save_consent_enabled": false,
  "claims": {},
  "scopes": [
  "exp": 1536323245,
  "iat": 1536323065,
  "client_name": "test",
  "consentApprovalRedirectUri": "http://id.init8.net:8080/openam/oauth2/authorize?client_id=test&response_type=code&redirect_uri=http://localhost:3001/redirect&scope=uid%20mail%20telephoneNumber&state=1234zy",
  "username": "demo",
  "decision": true

The user-agent (browser) needs to post the signed JWT to AM’s consentApprovalRedirectUril. In our sample app, we will present a FORM with a hidden field:


If you select Submit Consent, the signed JWT will be posted to AM. AM replies with

http://localhost:3001/redirect?code=8hGJGaU1leCVG4fFqxgDoxNrNGg &scope=telephoneNumber%20m

which can be traded for an access_token:

That’s it.

Share your stuff

Whenever you have a cunning RCS with an über-user-interface, send stuff to ForgeRock marketplace at ForgeRock Marketplace.