[keycloak-dev] token exchange

Stian Thorgersen sthorger at redhat.com
Thu Aug 17 07:54:30 EDT 2017


On 17 August 2017 at 13:47, Pedro Igor Silva <psilva at redhat.com> wrote:

> I don't know Stian. We are talking about authentication and that is what
> the IDToken is all about. In fact, even Google [1] has some references
> about using IDTokens as a way to *authenticate* users.
>

Sure, but that's to authenticate to one specific application, not to
authenticate to the IdP itself. The concept of authenticating with the IdP
with a ID token is broken.


>
> There are also specs with extensions to OAuth2 that do allow usage of
> *assertions" with the token endpoint [2] [3]. For instance, SAML and JWT
> assertions.
>
> [1] https://developers.google.com/identity/sign-in/web/backend-auth
> [2] https://www.rfc-editor.org/rfc/rfc7523.txt
> [3] https://tools.ietf.org/html/rfc7521
>
> On Thu, Aug 17, 2017 at 2:05 AM, Stian Thorgersen <sthorger at redhat.com>
> wrote:
>
>> 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
>> account:
>>
>> * 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
>>
>
> It depends on how you set your policies.
>
>
>>
>> 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/openi
>>> d-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