[keycloak-dev] Scope parameter support

Marek Posolda mposolda at redhat.com
Fri Jul 1 08:34:36 EDT 2016

On 01/07/16 09:37, Stian Thorgersen wrote:
> I don't like option (a) as it would be very clear what scopes are 
> available and what they result in. You'd have to search through all 
> roles and protocol mappers to find a list of scopes as well as somehow 
> manually build the picture of what a scope implies.
> A scope could affect:
> * Behavior - for example openid and offline_access. We can hard code 
> those, but what about others and custom ones?
For "openid", I think we can hardcode. I was thinking about adding SPI 
like ScopeParamMapper or something and drive the behaviour with it, 
however it won't work well and will require callbacks in various stages 
(ie. IDToken itself is created at some point, but whole 
AccessTokenResponse itself and control which tokens go to it is 
different point.

For offline_access we already has that driven by realm role actually.
> * Roles - limit what roles are included. This is probably the simplest 
> case as it's just about removing roles.
Not sure what exactly you mean. For roles, we already have the 
"scopeParamRequired" flag, so we can both include and remove. For 
example user is member of roleA, roleB, roleC and they have:
role-a : scopeParamRequired=false
role-b : scopeParamRequired=true
role-c : scopeParamRequired=true

and request will have "scope=role-b" then in token will be included both 
role-a and role-b . Just role-c won't be (as it requires 
scopeParamRequired but wasn't included in scopeParam).

We currently use it for offline_access role, which is default role, but 
have scopeParamRequired, so it's included just if "scope=offline_acces" 
is used.
> * Claims - limit what claims are included in the token. This boils 
> down to protocol mappers. Some protocol mappers would want to be 
> included/excluded based on scope, but I can also see that some 
> protocol mappers would internally look at scope to determine what to 
> include.
> * Authorization - could also affect authorization separately? The 
> token contains the scope param separately, so authorization policies 
> could be written directly on scope rather than roles/attributes
> Another thing is that the consent screen (and also showing application 
> access in account management console) should probably take about scope 
> rather than individual roles. For example:
> * Gallery wants to view your personal details
> * Backup application wants to access your photos
> A few more points:
> * It should be possible to view scopes available for a realm directly, 
> not by scanning through roles and protocol mappers
> * It should be possible to set a description on a scope
> * It should be possible to define a scope that maps to multiple roles
> * It should be possible to define a scope that maps to multiple 
> protocol mappers roles
> * It may be useful to be able to have protocol mappers that behave 
> differently depending on the scope. Complexity may outweigh usefulness 
> here though.
> With that in mind I don't think option (a) is great. Option (b) would 
> need introducing a whole new concept.
> How about we use a combination of (a) and (b), by using composite 
> roles? Something along the lines of:
> * scope maps to a role. but the role could be a composite role and 
> hence expand to other roles.
> * Protocol mappers could require a specific role to be applied
> * We could add a page to view scopes for a realm
>   - This would show the corresponding role as well as effective roles 
> if it's a composite role
>   - It would also list the protocol mappers included
+1 to this concept and "mapping" scope param values to roles. However 
there are some things to clarify.

- OIDC specs has definition for scopes like "phone" , "email" and 
"profile" . So we will need the roles for those. Isn't that confusing a 
bit? IMO our RoleModel applies well for the scope parameter, just not 
sure if it's not rather mis-using of role concept and bit confusing for 

- My understanding is, that scope is per-client thing rather than 
per-realm thing? For example if you use "scope=photo", it's applicable 
just for client "photogallery". Also the same scope parameter may have 
different meaning for different clients ( eg. if you use "scope=admin" 
in client "product-app" , the token will receive claims/permissions for 
managing products. However using "scope=admin" in client "customer-app" 
, the token will manage customers). So with respect to this, scope looks 
to me more like either per-client thing or per-clientTemplate thing (if 
some logic is common for more clients).

- We will need some way how to map value of scope parameter to 
particular role.
The simple (but probably not correct) way: On role definition, we can 
have something like "Scope param value" where you can configure value 
"photo" and it would mean that the "scope=photo" is related to this 
paricular role.
However what if there are clashes? For example someone can configure the 
scope parameter value "photo" for realm role "realm-photo-role" or 
client role "photogalery/client-photo-role" . Then when you use 
"scope=photo", which one will be used?

So after we add roleNamespaces, I can imagine something like this:
- Each client will have reserved namespace, where all roles mapped to 
"scope" parameter lives. Also each clientTemplate will have such namespace.

- After creation of client, there will be a set of corresponding roles 
added automatically for the client like:

You won't need to configure "Scope param name" as that will be based on 
the roleName

- Those roles won't be default roles and won't be automatically assigned 
to users. However any user, who uses "scope=phone" can request the scope 
"phone" with corresponding protocolMappers and children composite roles.

- If role is assigned to user directly, it will be always used even if 
it's not used in scope parameter. So user assigned to role "phone" will 
automatically receive "phone" and "phone_verified" protocolMappers.

- Keycloak will browse roles from the "scope-param" namespace of 
particular client, and then also roles from "scope-param" namespace of 
clientTemplate. So clientTemplate can have namespace for scope 
parameters, which can be used if there is some "common" scope applicable 
to more clients with common set of protocolMappers from this clientTemplate.

- For the scopes like "phone" "address" and "profile" it's pretty 
straightforward. It seems we will need protocolMappers for every OIDC 
defined claim (address, phone, gender, birthday etc) and those will have 
role required. So for example protocolMapper for "birthday" will require 
role "profile" , protocolMapper for "phone" will require role "phone" 
etc. Basic existing protocolMappers ( name, "preferred_username" etc)  .

- For the "prefix:/clients/my-client-id/scope-param/offline_access" 
role, it will have one composite role, which is current realm role 
"offline_access" . The current "offline_access" realm role is default 
role with scopeParamRequired=true, so it's applied just if it's 
requested (directly or indirectly) through scope parameter. If client 
doesn't need offline tokens and "offline_access" scope, the namespaced 
role "prefix:/clients/my-client-id/scope-param/offline_access". Also if 
you remove realm role "offline_access" from user, you disallow him to 
request offline tokens. It's currently realm role, hence it's global 
setting (so you can't reject user from offline tokens for "clientA" but 
allow him request offline tokens in "clientB") .


> One more thing is that maybe when a composite role is used on the 
> consent screen we could have an option if the composite role 
> description should be shown rather than the individual roles?
> On 30 June 2016 at 15:56, Marek Posolda <mposolda at redhat.com 
> <mailto:mposolda at redhat.com>> wrote:
>     It seems that for OIDC certification, we will need more proper support
>     for "scope" parameter. There are few tests from OIDC conformance
>     testsuite, which end with WARNING because of issues with "scope"
>     parameter.
>     -----------------------------
>     - In OIDC specification, the "scope" parameter is actually
>     REQUIRED. And
>     you must add the scope value "openid" to all authorization requests.
>     Hence if you don't use "scope=openid", the request is pure OAuth2
>     request, but it's not OIDC request.
>     In https://issues.jboss.org/browse/KEYCLOAK-3147 we discuss the
>     possibility that we should change our adapters and add
>     "scope=openid" to
>     all requests, and also the possibility to remove IDToken if it's not
>     OIDC request (and maybe other things). However it may be potential
>     issue
>     with backward compatibility with older adapters (which don't add
>     "scope=openid" at all).
>     - OIDC also prescribes the "scope=offline_access", which you use
>     if you
>     want offline token. We actually support this as we have realm role
>     "offline_access", with scopeParamRequired=true . So this role is
>     applied
>     just if it's included in scope parameter. This is our only support of
>     scope param actually. ATM we reference the realm roles by name (role
>     name must match the value of scope parameter) and clientRoles by
>     "clientId/roleName" . So it's not very flexible and won't work well in
>     the future with role namespaces.
>     - OIDC defines four other scope values, which we don't support,
>     with the
>     meaning like this:
>     profile
>          OPTIONAL. This scope value requests access to the End-User's
>     default profile Claims, which are: "name", "family_name",
>     "given_name",
>     "middle_name", "nickname", "preferred_username", "profile", "picture",
>     "website", "gender", "birthdate", "zoneinfo", "locale", and
>     "updated_at".
>     email
>          OPTIONAL. This scope value requests access to the "email" and
>     "email_verified" Claims.
>     address
>          OPTIONAL. This scope value requests access to the "address"
>     Claim.
>     phone
>          OPTIONAL. This scope value requests access to the "phone_number"
>     and "phone_number_verified" Claims.
>     - Not directly related to scopes, however OIDC also has one parameter
>     "claims" described in section
>     http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter .
>     This allows to define some additional claims, which should be included
>     in IDToken or UserInfo endpoint in addition to claims specified by
>     "scope" parameter.
>     -----------------
>     My current thinking is, that we will have 2 kinds of
>     protocolMappers and
>     roles.
>     1) "Always applied" - Those roles/protocolMappers are always
>     applied to
>     token even if they are not specified by scope parameter.
>     2) "Applied on demand" - Those roles/protocolMappers are applied
>     just if
>     they are specifically requested by scope parameter
>     For roles, we already have that with "scope param required" flag
>     defined
>     per roleModel. However for protocolMappers we don't have it yet.
>     IMO We will also need some more flexible way to specify how the
>     value of
>     scope parameter will be mapped to roles and protocolMappers. For
>     example
>     if I use "scope=foo", it can mean that I want realm role "foo1",
>     client
>     role "client1/foo2" and protocolMapper for "firstName" and
>     "lastName" etc.
>     I can see 2 possibilities:
>     a) Configure allowed scope param separately per each role /
>     protocolMapper
>     If some role has "Scope param required" checked, you will have
>     possibility to configure list of available values of scope parameter,
>     which this role will be applied to. This will be configured per-each
>     role separately.
>     Example: I have realm role "foo" . I check "scope param required" to
>     true. Then I will define "scope param values" :  "bar" and "baz". It
>     means that if someone uses parameter "scope=bar" or
>     scope=baz", then role "foo" will be applied to token. Otherwise it
>     won't
>     be applied.
>     Similarly it will be for protocolMappers. We will add switch "Scope
>     param required" to protocolMappers and we will use list of available
>     values of scope parameter, which is configured per each protocolMapper
>     separately.
>     b) Configure scope parameter in separate place
>     We will have another tab "Scope parameter config" (or maybe rather
>     another sub-tab under existing "Scope" tab). Here you will define the
>     allowed values of scope parameter. For each allowed value, you will
>     define protocolMappers and roles to apply. Hence for example for
>     "profile" scope parameter, you will define all protocolMappers for
>     corresponding claims ( name, family_name, ...) here.
>     We will still need "scope param required" switch for
>     protocolMappers in
>     case (b).
>     My current thinking is to go with (a). So when you go to some role (or
>     protocolMapper) in admin console you will see if you need scope
>     parameter and what are available values of scope parameter to
>     request it.
>     WDYT? Another ideas?
>     Marek
>     _______________________________________________
>     keycloak-dev mailing list
>     keycloak-dev at lists.jboss.org <mailto:keycloak-dev at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/keycloak-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-dev/attachments/20160701/48de5b1f/attachment-0001.html 

More information about the keycloak-dev mailing list