A thought about tokens and cloud<br>=========================<br><br>Below is a quick thought I've been mulling over on and off in my free time.   It relates to how we build authentication structures for use inside of the cloud.<br>
<br><br>The Dream<br>========<br><br>Imagine if you will an alternate future:<br><br>I spin up an instance 
on my openstack cloud.  I do NOT inject a key.  I instead try to log in 
directly using my keystone credentials ( whatever they may be, maybe two factor? ).  This means that cloud providers
 can cut perms on running instances remotely with simple changes to 
keystone or backend authentication systems.  They can also allow users 
to begin to login to systems they previously did not have access to 
without sharing keys or injecting anything into those instances.  In short this gets us non suck ACL control on instances from keystone.<br><br>Some folks will point out this is not cross cloud friendly.  It's totally not.  And maybe IAM is the solution for that.  But maybe we'll need this for real IAM support.<br>
<br>The history<br>========<br><br>A long while back I tried to build pam authentication services for keystone.  This was a great idea that resulted in terrible failure.<br><br>The fundamental problem I ran into basically stems from all ssh clients wanting to perform an getpwnam() on a user requesting to authenticate BEFORE handing auth creds off to PAM. <br>
<br>In short, if the instance can't query by user name for posix schema information ( uid, gid, home_dir, etc ) BEFORE any authentication query can occur the authentication will fail.  And there is just no way around that without modifying the way ssh works.  Which is probably never going to happen as the radius folks have tried and failed for years to do so.<br>
<br>So what we need is an NSS ( Name Switch Service ) access to keystone.<br><br>I mean sure,  if you backend to LDAP and allow anonymous read queries from your instance network space, you can just use the nss module to ldap.  However that's not very portable between openstack clouds.  And it means building administrative utilities for LDAP in addition to openstack.  <br>
<br>But the problem becomes more fundamental when you consider the issue....<br><br>The problem<br>=========<br><br>This got me to thinking about the fundamental nature of cloud instances and performing any sort of elevated permissions query or unauthenticated query to our APIs.  We need a service ticket functionality but we can't protect anything we place on instances.  <br>
<br>However instances can be fully qualified as part of the cloud.  You can in effect tie a token to an instance and ensure that when the token is used it's being used on an instance it's intended for.  Do we want that?  What does it get us REALLY?<br>
<br>Then there's single use tokens...  do they get used once and die?  do they only allow for a reduced set of queries?  can there bet a getpwnam only token?<br><br>In effect the issue we face is a very complex one.  I don't think we should try to solve every problem, but we will want a token structure that is flexible as we can possibly make it.  Because there's a good chance we'll end up running in a few different directions before we settle on something we like.  And I don't want use to be revisiting token structure in v4 api.<br>
<br>Token Structure<br>============<br><br>looking at the straw man...<br><br>{<br>
user : { id,  other user specific attributes },<br>
domain : {id},<br>
project : { roles [role ids]},<br>
auth_mechanisms[],<br>
services:[<br>
    compute: [<a href="https://nova/endpoint" target="_blank">https://nova/endpoint</a>],<br>
    identity: [<a href="https://keystone/endpoint" target="_blank">https://keystone/endpoint</a>],<br>
...<br>
]<br>
}<br><br>We'll want for the user attributes to be expandable to include things like posix schema... or windows domain schema... or who knows.<br><br>Domain ID works for me... but I am a fan of comment fields that can be NULL but also be there in case someone  wants to send some extra info down the line.<br>
<br>projects...  an interesting question.  <br>
<br>I think the multiple token spanning token is... interesting.  I think roles could be an answer for some of the ACL control for a token... but i have not trodden that path yet.<br><br>
projects : [{ id: id1, roles [role1, role2]}, { id: id2, roles [role1, role3]},  <br><br>service identifiers are great.  again you may want to make internal vs public url tokens that are idenfitied as such on the backend... with a quick identifier on the front end just to let you know they are?<br>
<br>I think also on the backend allowing a token to be reserved for use with a specific instance id and a means to verify that instance id is the query origin.<br><br>I think that matters.<br><br>Also the question for external queries becomes an issue.  What happens when i need to make a query from outside to the publicurl by nest some internal query structure?  No idea if we'd ever need to... but it's good to leave an area to plug something in if we need it.<br>
<br><br>Conclusion<br>========<br><br>I don't have one.<br><br>Just a few thoughts.  And I think they can help.<br><br>-Matt<br>
<br><br><br><div class="gmail_quote">On Thu, Jan 24, 2013 at 7:03 AM, Adam Young <span dir="ltr"><<a href="mailto:ayoung@redhat.com" target="_blank">ayoung@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 01/24/2013 04:06 AM, David Chadwick wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
On 24/01/2013 00:50, Adam Young wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
By the way, introducing holder of key into tokens solves the bearer<br>
problem and does not require SSL/TLS. What it requires is simply that<br>
the client signs the message containing the token with the key and<br>
includes a nonce/timestamp in the signed message so that the recipient<br>
can validate that the user is the holder of the token and the token<br>
has not been replayed.<br>
</blockquote>
Are you saying that the whole web requests would then be signed? Yes,<br>
that would work, and would be very effecient, but it would require<br>
extending all of the HTML aware parts to allow for signatures. I think<br>
that would be a  very valuable extension.<br>
</blockquote>
<br>
The body of the POST needs to be signed. This does not stop a MITM, but then neither does SSL if you have a forged cert in the name of the sender.<br>
<br>
David<br>
</blockquote>
<br></div>
Just thinking this through:<br>
<br>
Keystone still is the authority on keys and signing, so I think this might actually prevent a man-in-the-middle attack.  The key signed in the token is the one used to sign the message.  The token is signed by the keystone server.  The token is authenticated against keystone.   So a man in the middle either has to try to use the secret key associated with the public key from the token, which they won't have access to, or they have to inject their own key.<br>

<br>
If they inject their own key, they need to get a new token.  Which means they would need to convince Keystone that they are the original user, and that keystone should sign a different key.  That is a pretty high barrier to overcome.<br>

<br>
<br>
Am I missing something?<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
______________________________<u></u>_________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org" target="_blank">OpenStack-dev@lists.openstack.<u></u>org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/<u></u>cgi-bin/mailman/listinfo/<u></u>openstack-dev</a><br>
</div></div></blockquote></div><br>