<p dir="ltr">Ok. So it sounds like I'm not entirely off track and this will probably be the road we go down for our deployment until we have a better option. We need an MFA solution, and this doesn't seem like too terrible an option. </p>
<p dir="ltr">Basically after a bunch of digging this was the only solution I found that wouldn't break everything, still cover our requirements, maybe let us do something interesting with CLI tools.</p>
<p dir="ltr">For the UX thing, we're likely going to edit our horizon login form to have an optional passcode field and have the form concatenate before passing it to the keystone client. Having a proper two-step login process with passcode entry on a second page didn't really seem to be viable with stock keystone and mostly stock horizon so this seemed easier and workable.</p>
<p dir="ltr">A side UX part that is good here though is that the CLI is still usable without any extra work. Just enter your password+passcode and it works. Although for the CLI and clients we are actually looking at options to allow a sort of wrapper script to connect to a Yubikey and ask for a passcode. I'm not sure how doable that is, but anything that let's us do MFA while still working as simply as using envvars is good. Would be interesting if we can get something working with a Yubikey.</p>
<p dir="ltr">As for the MFA on one project but not another... That doesn’t really work. MFA only makes sense on a per user basis. Plus if you need an account for API actions and automation, you make another user with limited roles, but trying to make something like MFA work on a per project basis is something we ruled out very early. For my testing I never actually bothered even setting or using the project field on the credentials construct as it seemed redundant.</p>
<p dir="ltr">The best way to think about it I've found  is: imagine the horizon UX. You are logged into one project without MFA and then you swap to another that somehow now magically does need MFA. How do you enforce that? How do you log the user out, and make them enter MFA to then move to the other project? You are logged in already, with a valid token, how could you even tag that token as not logged via MFA? There are so many problems, and so many questions.</p>
<p dir="ltr">MFA on a per project basis might be doable, but with a lot of pain and refactoring it seems like, none of which is worth it, and most of which makes for awful UX.<br></p>
<p dir="ltr">At any rate, I would love to help if I can in this area, as it is something that interests me and something that we are going to be doing for our deployment. If worth the effort, I can polish up and write tests for the plugin I've written. It may not be the best solution long term, but it is the only one that seemed workable with what is present in OpenStack and without considerable effort.</p>
<p dir="ltr">At the very least, I'll do a full write up as to what we end up doing with our deployment, and how that went for us.</p>
<div class="gmail_extra"><br><div class="gmail_quote">On 18/07/2016 6:51 PM, Morgan Fainberg <morgan.fainberg@gmail.com> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br /><div><br /><div class="elided-text">On Sun, Jul 17, 2016 at 10:37 PM, Steve Martinelli <span dir="ltr"><<a href="mailto:s.martinelli@gmail.com">s.martinelli@gmail.com</a>></span> wrote:<br /><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Several comments inline<br /><div><br /><div class="elided-text">On Mon, Jul 18, 2016 at 12:20 AM, Adrian Turjak <span dir="ltr"><<a href="mailto:adriant@catalyst.net.nz">adriant@catalyst.net.nz</a>></span> wrote:<br /><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb( 204 , 204 , 204 );padding-left:1ex">Hello,<br />
<br />
I've been looking at options for doing multi-factor auth (MFA) on our<br />
infrastructure and I'm just wanting to know if the option I've decided<br />
to go with seems sensible.<br />
<br />
As context, we are running stock Keystone (to be backed by LDAP), we<br />
wanted to be able to enable MFA on a per user basis, and a user with MFA<br />
enabled should either be blocked from using the APIs or required MFA to<br />
use the APIs.<br />
<br /></blockquote><div><div><br /></div><div>We discussed adding MFA support in Newton at the Austin summit and didn't come to a happy conclusion (aside from "let federated users have MFA since it's built in"). Part of the trouble was deciding where to enforce MFA. Should a user *always* require MFA just because he has a TOTP credential? What if the user has multiple projects, and wants MFA to access projectA, but not projectB. </div></div><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb( 204 , 204 , 204 );padding-left:1ex">
I was looking at the current TOTP module in keystone, but seeing as that<br />
simply adds another optional Auth method to keystone it seems fairly<br />
useless for our needs. Unless I'm missing something, there seems to be<br />
no way in Keystone to enforce "use these two auth methods together". Is<br />
that the case? If not, it is something that has been considered? Or it<br />
is assumed people will write their own auth plugins rather than<br />
combining existing ones?<br /></blockquote><div><br /></div><div>It was definitely not assumed that folks would write there own auth plugins. The TOTP auth plugin was meant to be just be an alternative to password auth. We had hoped it would provide the building blocks for MFA, but see above comment.</div><div><br /></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb( 204 , 204 , 204 );padding-left:1ex">
From there I went toward writing our own Keystone Auth plugin and had a<br />
lot of success with that. The current iteration is a combination of the<br />
password and totp plugins where for users with TOTP credentials we<br />
expect a 6 digit password appended to the password. In the config I then<br />
replace the default password plugin with my own.<br /></blockquote><div><br /></div><div>I assume appending the TOTP password to the regular password is gonna be a big 'nope' from UX folks :)</div><div>Though points for being clever and avoiding the whole negotiate/challenge the user for extra information.</div><div> </div></div></div></div></blockquote><div><br /></div><div>For what it's worth, this is typically how TOTP works with federated users, you have a fixed known number of digits (6) added to a known password. For example, when I auth, I have my "password" and then the TOTP token concatenated. The server then splits the passed in value and handles authentication. I've seen it where it is done both with a fixed length "pin/password" and a "up to XXX characters" password.</div><div><br /></div><div>I don't know why the UX folks would have issues with this, since it is a common and relatively painless option. The hard part still is "does this user always need 2FA or only for certain projects?" As to that, my inclination is the user must always use 2FA if it is enabled for the user; some projects may require a user to have 2FA. So in short, if you use a project that requires 2FA, the user will always use 2FA. Alternatively, the user could disable 2FA but would be restricted from using the projects that require it.</div><div><br /></div><div>Since we aren't guaranteed a web-interface, the really cool things like U2F, wont always work (which is more of the challenge/response style).</div><div> </div><blockquote style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="elided-text"><blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb( 204 , 204 , 204 );padding-left:1ex">
<br />
In testing this seems to work as intended. All normal users are<br />
unaffected while users with a TOTP credential now must append their<br />
passcode to their password.<br />
<br />
I've made a blueprint for this plugin:<br />
<a href="https://blueprints.launchpad.net/keystone/+spec/password-totp-plugin">https://blueprints.launchpad.net/keystone/+spec/password-totp-plugin</a><br />
<br />
and the code I am currently testing is in the associated review:<br />
<a href="https://review.openstack.org/#/c/343422/">https://review.openstack.org/#/c/343422/</a><br />
<br />
If this plugin is useful to others, and this seemed like a sensible<br />
solution, I will write some unit tests and work on getting it merged.<br />
<br />
<br />
So, my main question, does this plugin seem like a sensible solution to<br />
MFA in OpenStack in the way we needed or are there other paths I should<br />
be going down?<br />
<br />
Cheers,<br />
-Adrian Turjak<br />
<br />
__________________________________________________________________________<br />
OpenStack Development Mailing List (not for usage questions)<br />
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br />
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br />
</blockquote></div><br /></div></div>
<br />__________________________________________________________________________<br />
OpenStack Development Mailing List (not for usage questions)<br />
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br />
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br />
<br /></blockquote></div><br /></div></div>
</blockquote></div><br></div>