How to implement silent downscoping?

I am testing out access policies for API access management. I am creating a set of policies which map groups to API scopes. For example, if a user/service is assigned group A, they can have access to X set of scopes. In addition, I could create another policy which says group B (ie admin), can have access to X set plus Y scopes.

Now, If I were to build an SPA application which handles both A and B groups I would like to log the user in by requesting X + Y scopes up front.

If the user is in group A, I would like the returned granted scopes to only include X (this is silent downscoping I think) despite requesting all up front.
If the user is in group B, then they should be returned a token with scopes X + Y.

My issue here is that if I request all of them up front for a user in group A, then it will always fail because the policy which defines group B fails.

Hi cberigan

I think inline hooks would be perfect for this. Before you let Okta issue a token, it calls your endpoint where you can check a few things

In your endpoint, check for the user current groups and based on that you can decide what scopes you send back.

We usually use AWS Lambda for this, you can protect it with Okta API tokens and it costs basically nothing.

It looks like I can’t replace the scopes claim in the token from the inline hook. Says the path is Unauthorized.

Unauthorized path was specified(op=replace, path=/claims/scp)

I think the path is /identity/claims/ OR /access/claims

"access": {
      "claims": {
        "ver": 1,
        "jti": "AT.W-rrB-z-kkZQmHW0e6VS3Or--QfEN_YvoWJa46A7HAA",
        "iss": "https://${yourOktaDomain}/oauth2/default",
        "aud": "api://default",
        "cid": "customClientIdNative",
        "uid": "00uq8tMo3zV0OfJON0g3",
        "sub": "",
        "firstName": "Add-Min",
        "preferred_username": ""
 "identity": {
      "claims": {
        "sub": "00uq8tMo3zV0OfJON0g3",
        "name": "Add-Min O'Cloudy Tud",
        "email": "",
        "ver": 1,
        "iss": "https://${yourOktaDomain}/oauth2/default",
        "aud": "customClientIdNative",
        "jti": "ID.YxF2whJfB3Eu4ktG_7aClqtCgjDq6ab_hgpiV7-ZZn0",
        "amr": [
        "idp": "00oq6kcVwvrDY2YsS0g3",
        "nonce": "asf",
        "preferred_username": "",
        "auth_time": 1547594229
      "token": {
        "lifetime": {
          "expiration": 3600

scp is not in the example it seems but try print out a request from okta yourself from your endpoint, or if you can give us one here then we can have a better look.

That’s not how it works.Take a look at

The path the inline hook must send is relative to the ID or token depending on the type field which specifies access or ID token.

The scp claim is not allowed to be modified. Okta can’t do silent downscoping on the scp claim in its current state.

It would be nice if Okta would allow or provide a different policy execution strategy to allow this.