On 06/02/2016 01:23 AM, Jamie Lennox wrote:
Hi All,
I'd like to bring to the attention of the wider security groups and
OpenStack users the Service Users Permissions [1] spec currently
proposed against keystonemiddleware.
To summarize quickly OpenStack has long had the problem of token
expiry happening in the middle of a long running operation and failing
service to service requests and there have been a number of ways
proposed around this including trusts and using the service users to
perform operations.
Ideally in a big system like this we only want to validate a token and
policy once on a user's first entry to the system, however all
services only communicate via the public interfaces so we cannot tell
at validation time whether this is the first, second, or twentieth
time we are validating a token. (If we ever do OpenStack 2.0 we should
change this)
Validating the "token" happens only once.
Validating the "user" permissions can happen multiple times, assuming
that nothing changes, the operation goes through.
The part I have trouble with is not Validating the delegation from the
end user to the service user. This is a CVE waiting to happen.
A users token should be short (5 minutes) and just kick off the
workflow. But that should then be used to create a delegation for the
remote service. THat delegation can last longer than the duration of
the token, to cover the long running tasks, but should not last forever.
While the usual discussion centers aroun Nova based tasks, think about
all the *aaService endpoint that are going to have this same need. If I
kick off a workflow via Trove or Sahara, that endpoint should only be
able to do what I ask it to do: spin up the appropriate number of vms
in the corresponding projects, and so on.
The delegation mechanism needs to be lighter weight than trusts, but
should have the sma constraints (redelegation and so on).
To do all of this right, however, requires a degree of introspection
that we do not have in OpenStack. Trove needs to ask Nova "I want to do
X, what role do I need?" and there is no where in the system today that
this information lives.
So, while we could make something that works for service users as the
problem is defined by Nova today, that would be, in a word, bad. We
need something that works for the larger OpenStack ecosystem, to include
less trusted third party services, and still deal with the long running
tasks.
S4U2Proxy from the Kerberos world is a decent approximation of what we
need. A user with a service ticket goes to a remote service and askes
for an operation. That service then gets its own proxy service ticket,
based on its own identity and the service ticket of the requesting
user. This Proxy service ticket is then used for operations on behalf
of the real user. The proxy ticket can have a reduced degree of
authorization, but does not require a deliberate delegation agreement
between each user and the service.
The proposed spec provides a way to simulate the at-edge validation
for service to service communication. If a request has an
X-Service-Token header (an existing concept) then instead of
validating the user's token we should trust all the headers sent with
that request (X_USER_ID, X_PROJECT_ID etc). We would still validate
the X-Service-Token header. This has the effect that one service
asserts to another that it has already validated this token and the
receiving service shouldn't validate it again and bypass the expiry
problem.
The glaring security issue here is that a user with the service role
can now emulate any request on behalf of any user by sending the
expected authenticated headers. This will place an extreme level of
trust on accounts that up to now have generally only been able to
validate a token. There is both the concern here that a malicious
service could craft new requests with bogus credentials as well as
services deciding that this provides them the ability to do
non-expiring trusts from a user where it can simply replay the headers
it received on previous requests to perform future operations on
behalf of a user. This is _absolutely not_ the intended use case but
something I expect to come up.
There is a variation of this mentioned in the spec where we pass only
the user-id, project-id and audit information from service to service
and then middleware can recreate the token from this information
similar to how fernet tokens work today. There is additional
processing here which in the standard case will simply reproduce the
same headers that the last service already knew and it still allows a
large amount of emulation from the service.
There are possibly ways we can secure this header bundle via signing
however the practical result is essentially a secondary expiry time
and an operational complexity that will make PKI tokens and rotating
fernet keys appear trivial for the benefit of securing a service that
we already trust with our tokens.
As this has such far reaching implications throughout openstack i
would like outside input on whether the risks are worth the reward in
this case, and what we would need to do to secure a deployment like this.
Please comment here and on the spec.
Thanks,
Jamie
[1] https://review.openstack.org/#/c/317266/
__________________________________________________________________________
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
__________________________________________________________________________
OpenStack Development Mailing List (not for usage questions)
Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev