# OmniAuth: Rack middleware that returns an auth hash and leaves the rest to you

> OmniAuth standardizes multi provider authentication for Ruby web applications by making every provider a Rack middleware and every login a redirect to /auth/:provider followed by an auth hash on the callback request. It deliberately does not touch your user model, which is both its flexibility and its responsibility.

**omniauth/omniauth** — OmniAuth is a flexible authentication system utilizing Rack middleware.

- Repository: https://github.com/omniauth/omniauth
- Stars: 8,105 · Forks: 972
- Language: Ruby
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/omniauth-omniauth

## Every provider is a Rack middleware, so onboarding one is a use call

The architecture is stated in one line and everything else follows from it: each OmniAuth strategy is a Rack middleware, usable the way you use any other Rack middleware. The Sinatra example in the documentation is two requires and two use calls inside the application class. Because the library is built for multi-provider authentication, the built-in OmniAuth::Builder class exists so you can leave room for several strategies, and the documentation is explicit that there is no difference between the builder form and using each strategy individually as middleware. The suggested place for that code is a Rails initializer at config/initializers/omniauth.rb, and the example registers the developer provider outside production and a Twitter provider with credentials taken from the environment. The point worth internalising is that a provider is not a special object with its own lifecycle. It is middleware that sits in the stack, which means the security posture of your login flow is partly a property of where you put that middleware in the stack and how you configure it, not only of the provider gem.

## Strategies are separate gems, and the built-in Developer strategy is a stub

OmniAuth itself does not contain Facebook, GitHub, Google or LDAP integrations. Those live in strategy gems released individually as RubyGems, and a community maintained list of them is kept in the project wiki. You pick the ones you need and you read each provider's own documentation for its specific initialization requirements, which is the sentence the project uses to hand responsibility for the details back to you. One strategy does ship with OmniAuth: Developer, which the documentation describes as completely insecure and not usable in production, and which directly prompts the user for authentication information and passes it straight through. Its intended use is as a placeholder at the start of development so you can swap in a real strategy later. The example code follows that intent by guarding it with a check on the environment, such as a unless clause on production, or an if clause on development. The trap here is obvious but common: a development-only provider that is registered unconditionally will happily accept any credentials, so the environment check has to be in the code rather than in a deployment habit.

## The request phase is protected by default, and the callback is your responsibility

OmniAuth protects the request phase, the POST to /auth/:provider, against cross-site request forgery by default. The mechanism is a class named OmniAuth::AuthenticityTokenProtection, which subclasses Rack::Protection::AuthenticityToken from the rack-protection gem, and the reasoning is specific: an attacker who can make a browser submit the request phase can log a user into the attacker's account. The documentation also tells you how to align this with your own token storage. Rack::Protection::AuthenticityToken options can be passed to match how your app stores its token, with a documented example for rack_csrf that sets a key of csrf.token and an authenticity_param of _csrf. If your app handles CSRF tokens differently, the allow_if option is there for a custom check. The subtle point is that the default protection stops at the request phase, and the callback is where the identity actually arrives, so an application that does not verify the state or nonce carried through the flow has a gap that no middleware setting here will close for you.

## Rails integration takes a gem line, an initializer and one validation setting

The Rails path is documented in a short section titled Rails (without Devise), which tells you the scope plainly. You add the gem to the Gemfile, insert OmniAuth as middleware in an initializer, and set the request validation phase so OmniAuth checks the token Rails already keeps in the session. The three pieces are below, taken from the documentation.

```ruby
gem 'omniauth'
```

```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :developer if Rails.env.development?
end

OmniAuth.config.request_validation_phase = OmniAuth::AuthenticityTokenProtection.new(key: :_csrf_token)
```

The last line is the part that makes the request phase share the same CSRF token as your forms, because Rails stores that token in the session under the name given in the key. The section title matters for expectation setting: the documentation is written for people who are not using Devise. If your application already uses Devise, adding OmniAuth alongside it means two authentication systems in one app, and the documentation does not describe how to reconcile them, so you would be inventing that integration yourself. The same initializer pattern applies outside Rails, since it is ordinary middleware configuration.

## The auth hash is the whole contract, and the callback is yours to implement

What OmniAuth hands back is a hash called the Authentication Hash, set on the Rack environment of the request to the callback URL. The omniauth.auth key provides it, and it contains a unique id, the name of the strategy the user authenticated with, and personal details such as name and email address as available. The project links an Auth Hash Schema wiki page for the field by field description, and that is the page to read before you write the mapping code, because which fields are present depends on the provider. The boundary is stated plainly: OmniAuth does not perform any actions beyond setting some environment information on the callback request, and it is entirely up to you how to implement the particulars of your application's authentication flow. It was intentionally built not to automatically associate with a User model and not to make assumptions about how many authentication methods you might want or what to do with the data afterwards. That restraint is the design, not an omission. The cost lands on you as a set of decisions about account linking, email as an identifier, what happens when a provider returns no email, and how a returning user is matched to an existing record.

## Where OmniAuth is the wrong size of tool

The same restraint that makes OmniAuth flexible makes it the wrong choice in some situations. If you want a login that also provisions a user record, assigns roles, sends a welcome email and keeps sessions, OmniAuth gives you a hash and leaves all four of those to you, so you are writing the same amount of code that a higher level library would have given you. If your application already standardizes on Devise, adding OmniAuth means two session systems, and the documentation for OmniAuth does not cover that. If you need to support an identity provider that speaks SAML rather than OAuth, that is not a strategy problem OmniAuth solves here, since the strategies it lists run from Facebook to LDAP and are a separate set of gems you would have to evaluate. There is also a deployment angle worth naming: strategies are third party gems that receive your application's traffic and your provider credentials, so each additional strategy is an additional dependency with its own release history and its own default settings, and the project does not present a per strategy upgrade path. For a single provider with an existing well known gem, the value of standardizing is thin. The value grows with the number of providers and with the desire to keep provider handling out of your controller layer.

## Maintenance, versioning and the documentation branch you are reading

A detail that affects how you read any page about this project: the documentation states that it is the documentation for the in-development branch, and points to the tree of the latest stable release for the released version. OmniAuth 2.1.4 is the newest release listed, dated 2025-10-01, with 2.1.3 and 2.1.2 both on 2025-02-27, and the last push to the repository was on 2026-10-17, so development continues between releases. The repository carries a gemspec, a Gemfile, a Rakefile, a spec directory, an .rspec file, a .rubocop.yml and a .yardopts file, so it is a normal gem with a test suite and lint configuration, and the README shows CI badges for Ruby, TruffleRuby and JRuby, which is a signal that the library is expected to run on all three runtimes. The licence is MIT, which is permissive and covers commercial use, modification and redistribution with attribution, and there is a SECURITY.md at the root for disclosure. Because the version tags and the in-development branch can differ, pin the gem version in your Gemfile rather than tracking master, and read the documentation for the release you actually depend on.

## Conclusion

Adopt OmniAuth if you are running a Rack or Rails application that needs to accept credentials from several external identity providers and you want the provider integration to be a middleware line rather than a set of hand written OAuth flows. Do not adopt it if you want authentication to create and manage your user records for you, because the library sets no user model and performs no actions beyond populating the environment hash on the callback. Before you ship, read the Auth Hash Schema wiki page for the provider you use, confirm the CSRF token option matches the token your app already stores, and set a request validation phase, since the default protection only covers the request phase and not the callback.

## FAQ

### How do I add OmniAuth to a Rails application?

Add gem 'omniauth' to the Gemfile, then insert the middleware in an initializer with Rails.application.config.middleware.use OmniAuth::Builder and register providers inside the block. The documentation also shows setting OmniAuth.config.request_validation_phase so the request phase uses the CSRF token Rails stores in the session.

### Where do I get the OAuth providers such as Google or LDAP?

They are not part of OmniAuth. Strategies are released separately as RubyGems and a community maintained list of them lives in the project wiki, and the documentation says to look at each provider's own documentation for its initialization requirements.

### What does OmniAuth do after a user authenticates?

It sets the Authentication Hash on the Rack environment of the request to the callback URL, reachable through the omniauth.auth key, containing a unique id, the strategy name and personal details such as name and email. OmniAuth performs no further actions and does not associate with a User model, so your callback endpoint must do that work.

### Is the built-in Developer strategy safe for production?

No. The documentation describes it as a completely insecure, non-production-usable strategy that prompts a user for credentials and passes them straight through, intended as a placeholder in development that you swap for a real strategy later.

### Does OmniAuth protect against CSRF on the callback?

The documented default protects the request phase, the POST to /auth/:provider, using OmniAuth::AuthenticityTokenProtection, a subclass of Rack::Protection::AuthenticityToken. The callback is not covered by that default, so an application must handle its own validation there.

## Sources

- [Issues](https://github.com/omniauth/omniauth/issues)
- [License: MIT](https://github.com/omniauth/omniauth/blob/master/LICENSE)
- [omniauth/omniauth on GitHub](https://github.com/omniauth/omniauth)
- [README](https://github.com/omniauth/omniauth/blob/master/README.md)
- [Releases](https://github.com/omniauth/omniauth/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/omniauth-omniauth
