[keycloak-dev] token exchange

Stian Thorgersen sthorger at redhat.com
Thu Aug 17 00:57:49 EDT 2017


True ID token is not the right thing to use. What about a special session
token that can be used together with direct grant to allow SSO in direct
grant:

* First time you call direct grant it returns a session token - could add a
special query param to request this
* Once you have a session token (this is the equivalent of the identity
cookie for the web flows) you can obtain a tokens through direct grant and
it'll always be linked to the same user session

On 15 August 2017 at 17:32, 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