Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Workflow of multi-factor authentication of RubyGems #1725

ecnelises opened this issue May 26, 2018 · 0 comments


Copy link

commented May 26, 2018

Updated on Sep. 1st

Hello, I'm going to adding multi-factor authentication feature to our gem tool and site. There's an original issue on this at 2016, see Issue #1252. Some parts on this feature has been merged into main stream of and deployed, while some are pending. See my report of GSoC 2018.


Workflow of my implementation is below:

  • User can choose turning on multi-factor auth on their profile settings. (the option is hidden by default now)
  • There are two levels of auth: ui_mfa_only and ui_and_api_mfa. The former only requires digit code when logging in, while the latter needs code when doing critical actions through API (push, yank, etc.). Level can be changed in profile settings page.
  • If user enabled ui_and_api_mfa, when entering gem signin, gem push, gem yank, there's a prompt like Digit Code: asking digit code to continue. If no code provided or code is incorrect, 401 Unauthorized returned.
  • There's check about drift and prior of digit codes, which means inputing code for last or next time interval would also be seen as correct, but you cannot do an authentication twice in the same interval. (If your code is 411511, you typed in for an auth, done. The code is asked seconds later but it's not expired, you'll get auth failed if you type it again.)
  • Implementation on cmd client is: sending request as normal, if Unauthorized got, check if --mfa option provided digit code, otherwise ask one from user and send it again.


For any concern with compatibility with your auth app or device, it uses TOTP (a time-based OTP generation algorithm), which is compatible with most of 2fa auth apps.

Implementation of both client and server should keep compatible with old clients or private gem servers without MFA related code.


There're several decisions to be made.

  1. Check against reuse of digit codes seems unnecessary and inconvenient. Many sites with MFA/2FA do not check if you just succeeded auth in this OTP interval (default 30 secs). And if a user wants to execute a command which needs digit code but not logged in, he/she would need to give code twice and the code should not be the same! See PR #1761.
  2. Now gem should send request normally to detect if MFA/2FA is needed. While has an API endpoint providing MFA auth level of current user. Should we use this API to detect user's MFA status? Current approach needs hacks for testing but using the MFA status API may bring compatibility problems.
  3. Should we provide something like a safe period in gem client with which user needn't give digit code again inside a time interval after last successful authentication?

Any comments are welcome.

@ecnelises ecnelises referenced this issue Jun 3, 2018
10 of 10 tasks complete

@ecnelises ecnelises changed the title [RFC][GSoC] Two factor authentication of RubyGems [RFC] Workflow of multi-factor authentication of RubyGems Aug 21, 2018

@ecnelises ecnelises referenced this issue Sep 1, 2018
4 of 5 tasks complete
@hsbt hsbt referenced this issue Sep 12, 2018
6 of 8 tasks complete

@ecnelises ecnelises closed this Nov 9, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants
You can’t perform that action at this time.