[keycloak-dev] token exchange

Stian Thorgersen sthorger at redhat.com
Thu Aug 17 01:05:38 EDT 2017

Actually, Bill has convinced me that ID token shouldn't be used for
authentication. If anything a special token only available in direct grant
should be used. The problem with ID token is that it's sent to the clients
themselves which would effectively give all clients full access to a users

* User logs in to app 1 through web flows
* App 1 gets an access token with limited roles, but also an ID token that
could be used for authentication
* App 1 uses the ID token to "authenticate" itself as the user to App 2 and
can now obtain an access token with more privileges then it should

So using ID token to authenticate a user is a completely broken concept.

On 15 August 2017 at 19:51, Pedro Igor Silva <psilva at redhat.com> wrote:

> We have discussed this before (I think because of Kubernetes), I don't see
> issues about using the IDToken as a bearer for "authentication". Of course,
> as long as you enforce validations that check if token can be trusted.
> In fact, I was about to start a discussion around IDToken and signature.
> In UMA 2.0 you can use different claim token formats to obtain a token
> (RPT) from the token endpoint. There is a specific grant type for that. One
> of the main changes we had in the specs.
> A common format is "http://openid.net/specs/openid-connect-core-1_0.html#
> HybridIDToken", which is about using an IDToken.
> On Tue, Aug 15, 2017 at 12:32 PM, Bill Burke <bburke at redhat.com> wrote:
>> I would be worried about the security implications of allowing an ID
>> token as a way to obtain access.  If you have even one client in the domain
>> that is not fully trusted then you are toast.  So how is it set up to make
>> things easy?  One "master" client is defined in realm.  That client is
>> given permission to obtain exchange for anything.  That client is marked as
>> confidential.  Generic CLI tool is configured with client id and secret of
>> "master" client.
>> On 8/15/17 2:50 AM, Stian Thorgersen wrote:
>> First of all I'm not arguing against token exchange service. It's a very
>> useful thing IMO and I can see loads of use-cases for it. I'm just
>> wondering about how usable it will be for the CLI tool and I'm worried
>> about how complicated it would be to setup. If the ID token was signed that
>> could serve as a the "identity cookie" for a CLI SSO session (if ID token
>> is not suitable we could introduce some sort of identity token that can be
>> used by direct grant to allow SSO sessions). Using direct grant you can
>> then easily obtain a token for a specific client by just passing a valid
>> "identity cookie" same way as the web browser does. Is that not simpler to
>> setup and use?
>> On 14 August 2017 at 15:42, Bill Burke <bburke at redhat.com> wrote:
>>> CLI tool I wrote doesn't allow token exchange, yet, but you're correct,
>>> I'm thinking of using it to perform token exchange.
>>> Our ID tokens are not signed right now.  Also you still need client to
>>> client exchange so that you can "downgrade" a token to talk to an untrusted
>>> service.  I've also added new fine-grain permissions "exchange-from" and
>>> "exchange-to".
>>> For example, lets say Client A gets token and invokes on service B which
>>> needs to invoke on untrusted service C.
>>> 1. Service B asks to exchange the token created for A to talk to C
>>> 2. Token exchange endpoint looks at issuer, its A, so it sees if service
>>> B has permission to "exchange-from" tokens created for A
>>> 3. Token exchange then sees if B has permission to "exchange-to" B.
>>> FYI, I'm also expanding this so that you can exchange an access token
>>> for a social provider token.  Automatic refreshes and everything if the
>>> provider supports it.  Gonna change how client initiated linking works too
>>> so that instead of doing the silly hash algorithm required by the call,
>>> clients would call the exchange first, get an error response like "not
>>> linked" that contained a browser URL that the client can use to create the
>>> link.
>>> Also no reason I couldn't do the same for exchange an external token to
>>> a internal one.  Would work the same as our IDP, import the user, etc.
>>> On 8/14/17 7:06 AM, Stian Thorgersen wrote:
>>> I'm assuming the basic token exchange service comes from the way the CLI
>>> tool works? I.e. you login to the tool then it allows exchanging the token
>>> for a particular CLI client?
>>> Would it not be better to obtain an ID token and use direct grant to
>>> obtain a token for the client using the ID token as the authentication
>>> mechanism?
>>> On 1 August 2017 at 19:10, Pedro Igor Silva <psilva at redhat.com> wrote:
>>>> On Mon, Jul 31, 2017 at 1:54 PM, Bill Burke <bburke at redhat.com> wrote:
>>>> >
>>>> >
>>>> > On 7/31/17 12:18 PM, Bill Burke wrote:
>>>> >
>>>> >
>>>> >
>>>> > On 7/31/17 11:35 AM, Pedro Igor Silva wrote:
>>>> >
>>>> > On Fri, Jul 28, 2017 at 5:24 PM, Bill Burke <bburke at redhat.com>
>>>> wrote:
>>>> >
>>>> >> I've implemented a simple token exchange API [1] that allows you to
>>>> >> exchange an access token created for one client to another client.
>>>> The
>>>> >> REST API follows the oauth token exchange api [2] very loosely.
>>>> >>
>>>> >> subject_token: a keycloak access token
>>>> >>
>>>> >> audience: takes a client id
>>>> >>
>>>> >> It then converts the access token created for one client and
>>>> converts it
>>>> >> to another.  It lives under the token endpoint.
>>>> >>
>>>> >> The security model is as follows:
>>>> >>
>>>> >> * Authenticate calling client the same way as password grant.
>>>> >>
>>>> >> * The calling client must have service account enabled
>>>> >>
>>>> >> * Service account must have a realm role "token-exchanger" grant
>>>> edto it
>>>> >> or, it must have a client role "token-exchanger" granted to it.  This
>>>> >> exchanger client role is a role defined by the target client you are
>>>> >> exchanging the token to.
>>>> >>
>>>> >>
>>>> >> Is this a good security model?  I'm thinking of not creating these
>>>> roles
>>>> >> right now and to enable support for exchange would require defining
>>>> the
>>>> >> roles specified above.
>>>> >>
>>>> >
>>>> > I think roles are too coarse-grained to represent this kind of
>>>> policy. A
>>>> > better option would be to explicitly define the clients that are
>>>> allowed to
>>>> > exchange tokens for a particular resource server. Eg.:
>>>> >
>>>> > RS A allows Client B, C and D to exchange their tokens where the
>>>> target
>>>> > audience is RS A (or if using "resource", a specific resource in RS
>>>> A).
>>>> >
>>>> >
>>>> > I changed it a little.  actors are:
>>>> >
>>>> > * Authenticated client asking for change
>>>> > * Clients that are the audience of the token being exchanged
>>>> > * Client you want the token to be exchanged to
>>>> >
>>>> > So, the authenticated client must be in the audience of the token
>>>> being
>>>> > exchanged, or, have permission to exchange from that particular
>>>> audience.
>>>> > The authenticated client also must have permission to exchange to the
>>>> > audience it wants to exchange to.
>>>> >
>>>> > Good idea to change it to use the fine grain admin permissions.
>>>> There's a
>>>> > couple of issues/problems with doing this that I think are easily
>>>> done:
>>>> >
>>>> > * public clients can't have service accounts.
>>>> > * Client Policy looks at kc_client_id attribute which is pulled from
>>>> the
>>>> > issuedFor claim in the token.  This isn't correct as we permission
>>>> checks
>>>> > based on the authenticated client, not the token.
>>>> >
>>>> > So I'll have to create a new Identity type that either wraps the
>>>> service
>>>> > account or ClientModel and sets the "kc_client_id" property.
>>>> >
>>>> Our policy evaluation engine is based on the claims within the token.
>>>> The
>>>> "issueFor" is basically the "azp" claim from OIDC. In fact, we don't
>>>> even
>>>> need that "kc_client_id". We could make this configurable though, and
>>>> let
>>>> users decide whether they want to check the "authenticated client" or
>>>> "azp"
>>>> ?
>>>> Btw, I'm about to finish UMA Grant Type, one of the changes I'm doing
>>>> for
>>>> UMA 2.0. My changes will conflict with yours. Are you going to merge
>>>> your
>>>> changes soon ?
>>>> Another thing I noticed is that maybe we could have a SPI for custom
>>>> grant
>>>> types. What you did and what I'm doing may justify a specific SPI for
>>>> plugging custom grant types. Maybe too much, but maybe a nice to have.
>>>> >
>>>> >
>>>> > Bill
>>>> >
>>>> _______________________________________________
>>>> keycloak-dev mailing list
>>>> keycloak-dev at lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/keycloak-dev

More information about the keycloak-dev mailing list