Keratin AuthN
Keratin AuthN is an authentication service that keeps you in control of the experience without forcing you to be an expert in web security.
This gem provides utilities to help integrate with the backend of a Ruby application. You will also need a client for your frontend, such as keratin/authn-js.
Installation
Add this line to your application's Gemfile:
gem 'keratin-authn'
Usage
Configure your integration from a file such as config/initializers/keratin.rb
:
Keratin::AuthN.config.tap do |config|
# The AUTHN_URL of your Keratin AuthN server. This will be used to verify tokens created by AuthN,
# and will also be used for API calls unless `config.authn_url` is also set (see below).
config.issuer = 'https://authn.myapp.com'
# The domain of your application (no protocol). This domain should be listed in the APP_DOMAINS of
# your Keratin AuthN server.
config.audience = 'myapp.com'
# Credentials for AuthN's private endpoints. These will be used to execute admin actions using the
# `Keratin.authn` client provided by this library.
#
# TIP: make them extra secure in production!
config.username = 'secret'
config.password = 'secret'
# OPTIONAL: enables debugging for the JWT verification process
# config.logger = Rails.logger
# OPTIONAL: Send private API calls to AuthN using private network routing. This can be necessary
# if your environment has a firewall to limit public endpoints.
# config.authn_url = 'https://authn.internal.dns/
end
Reading the Session
Use Keratin::AuthN.subject_from(params[:authn])
to fetch an account_id
from the session if and
only if the session is valid.
Modifying Accounts
-
Keratin.authn.update(account_id, username: 'new@example.tech')
: will synchronize an email change with the AuthN server. -
Keratin.authn.lock(account_id)
: will lock an account, revoking all sessions (when they time out) and disallowing any new logins. Intended for user moderation actions. -
Keratin.authn.unlock(account_id)
: will unlock an account, restoring normal functionality. -
Keratin.authn.archive(account_id)
: will wipe all personal information, including username and password. Intended for user deletion routine. -
Keratin.authn.expire_password(account_id)
: will force the account to reset their password on the next login, and revoke all current sessions. Intended for use when password is deemed insecure or otherwise expired.
Other
-
Keratin.authn.import(username: user.email, password: user.password, locked: false)
: will create an account in Keratin. Intended for importing data from a legacy system. Returns anaccount_id
, or raises on validation errors.
Example: Sessions
You should store the token in a cookie (the keratin/authn-js integration can do this automatically) and continue using it to verify a logged-in session:
class ApplicationController
private
def logged_in?
!! current_account_id
end
def current_user
return @current_user if defined? @current_user
@current_user = User.find_by_account_id(current_account_id)
end
def current_account_id
Keratin::AuthN.subject_from(cookies[:authn])
end
end
Example: Signup
class UsersController
def create
@user = User.new(params.require(:user).permit(:name, :email))
@user.account_id = current_account_id
# ...
end
end
Example: Login
class SessionsController
def create
@user = current_user
# ...
end
end
Example: Multiple Domains
When working with multiple frontend domains it may be beneficial to use a referrer header as your audience instead of a static configuration. You can do this by providing an additional parameter to the subject_from
method.
class ApplicationController
private
def current_user
return @current_user if defined? @current_user
@current_user = User.find_by_account_id(current_account_id)
end
def current_account_id
Keratin::AuthN.subject_from(cookies[:authn], audience: URI.parse(request.referer).host)
end
end
Testing Your App
AuthN provides helpers for working with tokens in your application's controller and integration tests.
In your test/test_helper.rb
or equivalent:
# Configuring AuthN to use the MockKeychain will stop your tests from attempting to connect to the
# remote issuer during tests. The MockKeychain creates a single weak key, for speedy tests.
Keratin::AuthN.keychain = Keratin::AuthN::MockKeychain.new
# Including the Test::Helpers module grants access to `id_token_for(user.account_id)`, so that you
# can test your system with real tokens.
module ActionDispatch
class IntegrationTest
include Keratin::AuthN::Test::Helpers
end
end
Developing AuthN
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/keratin/authn-rb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.