[keycloak-dev] Opinion on how secret the OIDC "client secret" should be?

Stian Thorgersen sthorger at redhat.com
Mon Sep 19 02:50:16 EDT 2016


As kubectl is a CLI installed on end-user machines it's a public client.
For a CLI I'd use a system browser and make the CLI start a temporary web
server on localhost:XXXX, or I'd fallback to using resource owner password
cred.

ID token is an authentication token. So if you use that you should use it
to authenticate with the service kubectl invokes and set up a session
cookie to preserve the security context. Would make more sense to me to use
the access token though, and have kubectl responsible to refresh it.

On 14 September 2016 at 20:59, Marc Boorshtein <
marc.boorshtein at tremolosecurity.com> wrote:

> Reposting on Eric's behalf
>
> On Sep 14, 2016 2:54 PM, "Eric Chiang" <eric.chiang at coreos.com> wrote:
>
>> Thanks Marc for the cc,
>>
>> Just to give some background for the reasoning behind this.
>>
>> Today the Kubernetes API server trusts ID Tokens issued to a single
>> client. Refreshing a token requires a client_secret, hence the flags Marc
>> provided in his example. Though we don't have official recommendations
>> about what the properties of the client passed in those flags should be
>> there's two obvious ways of going about this.
>>
>> 1) Have each kubectl share a client secret. Some authorization servers
>> provide mechanisms for declaring "public clients" to imposes restrictions
>> on its capabilities. For example Google, when it assumes client_secrets
>> aren't secret, restricts the redirect URLs for embedded apps to only
>> localhost and a magic OOB, doesn't let it do incremental authorization,
>> etc. Though as Marc noted this may have unintended consequences with
>> providers who assume this doesn't happen.
>>
>> 2) Another option is for kubectl to utilize the "azp" claim in the ID
>> Token[0], which allows clients to request ID Tokens on behalf of other
>> clients. This means each kubectl gets its own client_id and client_secret,
>> with each one requesting ID Tokens minted for a common client_id. However
>> that capability isn't generally supported by OIDC providers, though Google
>> does[1]. This is probably a more secure option, but the actual
>> implementations differ so widely that it becomes hard to make a general
>> statement.
>>
>> We'd be interested in knowing if either of these methods raise red flags
>> when combined with keycloak.
>>
>> Eric
>>
>> [0] https://openid.net/specs/openid-connect-core-1_0.html#IDToken
>> [1] https://developers.google.com/identity/protocols/CrossClientAuth
>>
>>
>>
>> On Wed, Sep 14, 2016 at 10:16 AM, Marc Boorshtein <
>> marc.boorshtein at tremolosecurity.com> wrote:
>>
>>> KC Team,
>>>
>>> Eric Chiang from CoreOS (cc'd on this email) and I have been talking
>>> on the Kubernetes sig-auth slack channel about how secret the "client
>>> secret" in OIDC should be.  The context for the question is that
>>> Kubernetes' OIDC implementation uses the id_token as the bearer token
>>> (as opposed to the access_token) to avoid a round trip.  Since the
>>> id_token should be short lived the question of how to get a new one
>>> using a refresh_token.  The current solution is to give kubectl the
>>> refresh_token, the idp discovery url and the client id and secret:
>>>
>>> kubectl config set-credentials --auth-provider=oidc
>>> kubectl config set-credentials --auth-provider-args=idp-issuer-url=(
>>> issuer url )
>>> kubectl config set-credentials --auth-provider-args=client_id=( your
>>> client id )
>>> kubectl config set-credentials --auth-provider-args=client_secret=(
>>> your client secret )
>>> kubectl config set-credentials --auth-provider-args=refresh-token=(
>>> your refresh token )
>>>
>>> This way kubectl can get a new id_token once the possessed one
>>> expires.  The question becomes does giving the client_secret directly
>>> to users become a security issue since its now a shared credential?
>>>
>>> Some issues I see are:
>>> 1.  Rotation becomes harder - how many people have this?
>>> 2.  While you can't generate an access_token with just this secret,
>>> you CAN impersonate an RP so if your are monitoring which RPs are
>>> making requests an attacker could generate excessive requests for a
>>> single RP even if those requests fail
>>> 3.  Since most IdPs will generate some kind of back-end record for a
>>> request if you have the client id and secret you could more easily do
>>> a DoS attack by flooding the server with authenticated requestes for
>>> authentication
>>>
>>> What are your thoughts?  Google provides an example asserting that the
>>> client secret ISN'T secret (reading through it I think the example
>>> contradicts its self)
>>> https://developers.google.com/api-client-library/python/auth
>>> /installed-app
>>>
>>> Thanks
>>>
>>>
>>> Marc Boorshtein
>>> CTO Tremolo Security
>>> marc.boorshtein at tremolosecurity.com
>>> Twitter - @mlbiam / @tremolosecurity
>>>
>>
>>
> _______________________________________________
> keycloak-dev mailing list
> 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/20160919/ac325ab2/attachment-0001.html 


More information about the keycloak-dev mailing list