[openstack-dev] [all] [clients] [keystone] lack of retrying tokens leads to overall OpenStack fragility
Angus Lees
gus at inodes.org
Fri Sep 12 07:46:53 UTC 2014
On Thu, 11 Sep 2014 03:21:52 PM Steven Hardy wrote:
> On Wed, Sep 10, 2014 at 08:46:45PM -0400, Jamie Lennox wrote:
> > For service to service communication there are two types.
> > 1) using the user's token like nova->cinder. If this token expires there
> > is really nothing that nova can do except raise 401 and make the client
> > do it again. 2) using a service user like nova->neutron. This should
> > allow automatic reauthentication and will be fixed/standardied by
> > sessions.
> (1) is the problem I'm trying to solve in bug #1306294, and (for Heat at
> least) there seems to be two solutions, neither of which I particularly
> like:
>
> - Require username/password to be passed into the service (something we've
> been trying to banish via migrating to trusts for deferred
> authentication)
> - Create a trust, and impersonate the user for the duration of the request,
> or after the token expires until it is completed, using the service user
> credentials and the trust_id.
>
> It's the second one which I'm deliberating over - technically it will work,
> and we create the trust anyway (e.g for later use to do autoscaling etc),
> but can anyone from the keystone team comment on the legitimacy of the
> approach?
>
> Intuitively it seems wrong, but I can't see any other way if we want to
> support token-only auth and cope with folks doing stuff which takes 2 hours
> with a 1 hour token expiry?
A possible 3rd option is some sort of longer lived, but limited scope
"capability token".
The user would create a capability token that represents "anyone possessing
this token is (eg) allowed to write to swift as $user". The token could be
created by keystone as a trusted 3rd party or by swift (doesn't matter which),
in response to a request authenticated as $user. The client then includes
that token in the request *to cinder*, so cinder can pass it back to swift
when doing the writes.
This capability token would be of much longer duration (long enough to
complete the cinder->swift task), which is ok because it is of a much more
limited scope (ideally as fine grained as we can bother implementing).
(I like this option)
A 4th option is to have much longer lived tokens everywhere (long enough for
this backup), but the user is able to expire it early via keystone whenever
they feel it might be compromised (aiui this is exactly how things work now -
we just need to increase the timeout). Greater exposure to replay attacks,
but if detected they can still be invalidated quickly.
(This is the easiest option, it's basically just formalising what the
operators are already doing)
A 5th option (wow) is to have the end user/client repeatedly push in fresh
tokens during long-running operations (and heat is the uber-example since it
basically wants to impersonate the user forever). Those tokens would then
need to be refreshed all the way down the stack for any outstanding operations
that might need the new token.
(This or the 4th option seems ugly but unavoidable for "forever" services like
heat. There has to be some way to invalidate their access if they go rogue,
either by time (and thus needs a refresh mechanism) or by invalidation-via-
keystone (which implies the token lasts forever unless invalidated))
However we do it: the "permission" to do the action should come from the
original user - and this is expressed as tokens coming from the original
client/user in some form. By allowing services to create something without
the original client/user being involved, we're really just bypassing the token
authentication mechanism (and there are easier ways to ignore the token ;)
--
- Gus
More information about the OpenStack-dev
mailing list