How to implement SAML SSO using Ruby on Rails
Not many people read SAML tutorials for fun, so if you’re here, you’re probably a software developer that:
- Has an existing Ruby on Rails application
- Needs to support SAML single sign-on (SSO) in your Rails app
And, if you’re anything like most software developers, you’ve never worked with SAML before. That’s not a problem. By the end of this tutorial, you’ll have a working prototype of SAML SSO.
But first, you should probably check out one of these resources we compiled to help software developers understand SAML:
- A gentle introduction to SAML: a minimally technical, conceptual overview of SAML single sign-on; you may find this helpful if you don’t really know where to start
- SAML, a technical primer: more technical and more detailed, this primer aims to share more than you’ll need to know for any practical implementation
The details that follow skip over some conceptual treatment of SAML. If at any point, you start to feel a bit lost, you might want to revisit one of the above links. Alternatively, you could spend some time perusing our documentation.
With that said, I still can’t help but discuss the basics. Broadly speaking, you’ll use SAML to log users in indirectly. Instead of, say, having your users present usernames and passwords, you’ll instead rely on claims that you receive from a centralized authentication service (called an identity provider) that your customer controls.
Exactly how that works can be pretty convoluted, but here’s what it looks like in a sequence diagram:

Best SAML service for Rails: introducing SSOReady
SAML’s hard. It’s complex and time-consuming. If you’re not intensely careful, it can also be really dangerous. Lots of open source packages, like ruby-saml, have had some severe vulnerabilities.
SSOReady’s a free, open source middleware service that makes SAML a lot easier. It’s pretty typical to finish an implementation within a day or two. SSOReady also anticipates and protects you from a few common security issues (e.g., taking precautions against replay attacks).
Here’s what things look like:

In short, you can set up full-fledged SAML support without wrangling any XML or dealing with any cryptography. You just have to write a few lines of code.
SAML in Ruby: the SSOReady SDK
We’ve built out an SDK for Ruby developers. It just makes use of our API a little bit tidier.
You just have to run:
gem install ssoready
Pretty straightforward!
SAML in Ruby on Rails: getting started with an example app
We put together an example app with Rails on GitHub here. It has its own README over there that’s honestly better than this blog post. If you’re not deeply familiar with Rails, you might find our Sinatra app a little bit easier to follow, at least to start.
To reproduce the app locally, just run the following:
git clone https://github.com/ssoready/ssoready-example-app-ruby-rails-saml
cd ssoready-example-app-ruby-rails-saml
bundle install
bundle exec rails s
You’ll have a working SAML app running on localhost:3000. It’s just rendering some static HTML and implementing two important endpoints over some pretty standard Rails stuff. We’ll talk about those endpoints in a moment.
SAML in Ruby on Rails: just two endpoints and you’re done
Assuming you’ve reproduced our Rails app locally, you’ll want to pay attention to two endpoints in particular: the SAML Redirect endpoint and the SSOReady callback endpoint. These are doing nearly all of the work.
Let’s take a look at the SAML Redirect endpoint first. You’ll find it at /app/controllers/home_controller.rb
It looks like this:
def saml_redirect
get_redirect_result = ssoready.saml.get_saml_redirect_url(
organization_external_id: params[:email].split("@").last
) # just pretending that we use email domains as company IDs
redirect_to(get_redirect_result.redirect_url, allow_other_host: true)
end
This endpoint has basically two jobs:
- It gets a redirect URL from SSOReady. This is just a URL that points to a given user’s corporate identity provider. (Please our conceptual explanations of SAML if this doesn’t yet make sense to you!)
- It redirects the user to visit the redirect URL.
The user will have to authenticate with their corporate identity provider (e.g., Microsoft Entra ID, Okta, OneLogin, etc.). Assuming they do so successfully, the corporate identity provider will redirect the user back to a route that SSOReady controls, simultaneously passing a SAML message.
SSOReady processes the SAML on your behalf – this isn’t apparent to the user. Upon processing the message, SSOReady assigns it a saml_access_code
. SSOReady redirects the user back to your SSOReady callback endpoint with the saml_access_code
as a query parameter.
Your SSOReady callback endpoint then has basically two jobs:
- It passes the
saml_access_code
back to SSOReady in exchange for the user’s details - It establishes an authentication context (i.e., a session) for the user based on the details it receives from SSOReady.
Here’s the SSOReady callback looks like:
def ssoready_callback
redeem_result = ssoready.saml.redeem_saml_access_code(
saml_access_code: params[:saml_access_code]
)
user = User.find_or_create_by(email: redeem_result.email)
sign_in(user)
redirect_to("/")
end
This app uses Devise, but you can use whatever tools you prefer. SSOReady imposes no limitations on the other tools you use to manage authentication. Just please make sure that you implement sessions safely!
Once you have these two endpoints, you’re pretty much done. Pretty simple, right?
Next steps
This example application is almost absurdly simple. It doesn’t do much. You’ll need to take some steps to get SAML working in production.
A few ideas on places to start:
- Read the SAML quickstart docs for SSOReady
- Check out how to integrate SAML with login UI
- Sign up for SSOReady to get your own API key; you can get unlimited use for free.