Yauth

Yauth is a extremely simple authentication solution for prototypes, and provides a drop-in solution for http basic authentication. It uses a yaml file to store usernames and hashed password combined with the http basic authentication. The whole gem provides a better-than-nothing security, and it was designed with small prototypes in mind. It is entirely developed as a github.com/hassox/warden strategy, the same library on which the popular Devise is based.

Yauth resolves one well defined problem: protecting a web application that is going to be accessed by a few users. As adding new users requires manual intervention (only launching a command, see below), it’s a good choice for single-users web applications or prototypes. In this way you can password-protect your app easily and expose it to your clients on the web.

Installation

First, install the gem:

gem install yauth

Or if you are using Bundler:

echo "gem 'yauth'" >> Gemfile
bundle install

Add the first user (username ‘bar’ and password ‘foo’):

yauth add bar foo

Check the ‘config/users.yml’ into your version control system:

git add config/users.yml
git commit -m "Added user 'bar'."

Configuration

Yauth requires almost no configuration, 5 lines of code.

Sinatra

In your application.rb, simply put:

Yauth::Strategy.install!

use Warden::Manager do |manager|
  manager.default_strategies :yauth_users
  manager.failure_app = Yauth::FailureApp.new("Your Realm")
end

To require authentication inside an action, simply call:

get '/' do
  request.env['warden'].authenticate! # execution stop and auth is required
  "hello world\n"
end

Rails 3

In your config/application.rb file put:

Yauth::Strategy.install!

config.middleware.use Warden::Manager do |manager|
  manager.default_strategies :yauth_users
  manager.failure_app = Yauth::FailureApp.new("Your Realm")
end

To require authentication inside an action, add this method to app/controllers/application_controller.rb:

private
def authenticate
  env['warden'].authenticate!
end

Then, you can use the authenticate method as a before filter for every method that requires authentication:

before_filter :authenticate, :only => :your_method_here

Adding and removing users

If you want to add the user ‘foo’, with password ‘bar’, just launch:

yauth add foo bar

Then, if you want to change ‘foo’ password to ‘oof’, just launch:

yauht add foo oof

Finally, to remove ‘foo’ user:

yauth rm foo

Security Considerations

Users are stored in the ‘config/users.yml’ file, with the password stored using BCrypt (github.com/codahale/bcrypt-ruby). In this way it’s safe to add the ‘config/users.yml’ to the version control system.

You can see an example of the ‘config/users.yml’ file:

--- 
- user: 
    username: admin
    password: !str:BCrypt::Password 
      str: $2a$10$UMR/fB5Jn5oRNe.OV9VicOLrg9BnPyN6Vc3S/noI5LWzfMKK2Zj0q
      "@checksum": Lrg9BnPyN6Vc3S/noI5LWzfMKK2Zj0q
      "@cost": 10
      "@salt": $2a$10$UMR/fB5Jn5oRNe.OV9VicO
      "@version": !str:BCrypt::Password 2a

Upgrading from version 0.1 to 0.2

YOU MUST RECREATE your users.yml file when migrating from 0.1 to 0.2, as I changed the encryption function to BCrypt. Unfortunately it’s pretty cheap to crack a password encrypted inside an hash, as stated in this article: codahale.com/how-to-safely-store-a-password. And one of the main goals of this project it’s to store passwords securely. Beware that it might be slower to compute, but it is much safer with BCrypt.

This has been done thanks to Gabriele Renzi, that has pointed me in the right direction.

TODO

Future versions will include:

  • drop-in api key solution, i.e. user might have a key for API prototypation;

  • hash function independence;

  • authentication scopes, as defined in warden.

Contributing to yauth

  • Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet

  • Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it

  • Fork the project

  • Start a feature/bugfix branch

  • Commit and push until you are happy with your contribution

  • Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright © 2011 Matteo Collina. See LICENSE.txt for further details.