
Developers work with many tools nowadays, from git hosting providers like GitHub/Bitbucket to task management tools like Jira/ClickUp to communication platforms like Slack/Teams to AI IDEs/Agents like Cursor/Claude Code/GitHub Copilot etc and countless other development tools.
With work spread across so many tools, analytics, reporting & insights are also fragmented, making it hard for engineering leaders to get a unified picture of productivity, bottlenecks, and outcomes. This is where GreyMonk helps, by collecting data from multiple sources into one place and extracting additional insights.
The Integration Challenge
Building and maintaining dedicated integrations across multiple platforms (with multi-tenant support) is a daunting task. Every provider has its own philosophy leading to different quirks, token formats & APIs. Without a consistent approach, integrations can quickly become brittle and turn into tomorrow’s tech debt..
OmniAuth
In the Ruby on Rails ecosystem, the OmniAuth gem is the de facto standard for third-party authentication.
OmniAuth is a Rack-based authentication framework that standardizes the way Rails apps connect with external providers. Instead of needing to implement complex OAuth 1.0/2.0 flows, OmniAuth handles the redirects, token exchanges, and callback parsing.
The OmniAuth ecosystem likely has a strategy for nearly any provider you’d want to integrate with. Even if one doesn’t exist, you can create a custom OmniAuth strategy more easily than writing a full OAuth flow from scratch.
Benefits of OmniAuth
- Unify authentication flows across different providers
- Accelerate setup with existing strategies
- Rely on built-in security best practices
- Extend flexibly by writing custom strategies
OmniAuth Architecture
OmniAuth sits between the Rails app and external providers, handling the OAuth flow. It acts as a translator, ensuring that Rails app always gets back a consistent authentication hash, no matter what provider user chooses
Here’s a simple view of how it works:

Setting Up OmniAuth
- Pick a Provider
- Decide between using a community maintained strategy OR building a custom strategy
- Install Gems
- Add OmniAuth to Gemfile
- Add relevant strategy gem (e.g., omniauth-github) if using community maintained strategy
- If not using existing strategy, build a custom strategy
- Configure OmniAuth
- Add initializer with provider credentials and other settings
- Add Routes & Handle Callback
- Setup callback to your session controller OR any other controller responsible for handling provider callback
Example 1: Using an Existing OmniAuth Provider (GitHub Login)
There are many existing community maintained OmniAuth strategies. Let’s integrate GitHub login as an example.
Add Gems
# Gemfile
gem 'omniauth'
gem 'omniauth-github'
Code language: PHP (php)
Configure OmniAuth
# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_CLIENT_ID'], ENV['GITHUB_CLIENT_SECRET'], scope: "user:email"
end
Code language: PHP (php)
Add Routes
# config/routes.rb
get '/auth/:provider/callback', to: 'sessions#create'
Code language: PHP (php)
Handle the Callback
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
auth = request.env['omniauth.auth']
user = User.find_or_create_by(provider: auth['provider'], uid: auth['uid']) do |u|
u.email = auth['info']['email']
u.name = auth['info']['name']
end
session[:user_id] = user.id
redirect_to root_path, notice: "Signed in with GitHub!"
end
end
Code language: HTML, XML (xml)
That’s it, Github authentication is set up for the Rails app. Scopes can be tweaked based on use case, for example adding scopes to read repositories for authenticated user, etc
Example 2: Writing Custom OmniAuth Strategy
Sometimes there are no existing strategies for some providers. In that case, a custom OmniAuth strategy can be written to handle OAuth.
Why build your own strategy?
- To integrate with niche or less common providers where the community hasn’t built a gem yet
- Existing Gem for the provider is outdated
- To connect with internal systems or proprietary APIs used inside your company
- To support enterprise-specific SSO flows that require custom handling
In GreyMonk while looking to integrate Bitbucket we found some existing omniauth strategies for it, but they were outdated and did not fulfil our requirements. So we build our own custom strategy. Let’s write a custom strategy for Bitbucket
Create a new strategy file
# lib/omniauth/strategies/bitbucket_oauth2.rb
require 'omniauth'
require 'omniauth-oauth2'
module OmniAuth
module Strategies
class BitbucketOauth2 < OmniAuth::Strategies::OAuth2
option :name, 'bitbucket_oauth2'
option :client_options,
site: 'https://bitbucket.org',
authorize_url: '/site/oauth2/authorize',
token_url: '/site/oauth2/access_token'
uid { raw_info[:uuid] }
info do
{
username: raw_info[:username],
email: primary_email,
name: raw_info[:display_name]
}
end
def raw_info
@raw_info ||= deep_symbolize(access_token.get('/api/2.0/user').parsed)
end
end
end
end
Code language: HTML, XML (xml)
Register the strategy
# config/initializers/omniauth.rb
require 'omniauth/strategies/bitbucket_oauth2'
Rails.application.config.middleware.use OmniAuth::Builder do
provider :bitbucket_oauth2, ENV['BITBUCKET_CLIENT_ID'], ENV['BITBUCKET_CLIENT_SECRET']
end
Code language: PHP (php)
Add Route if not already added
# config/routes.rbget '/auth/:provider/callback', to: 'sessions#create'
Code language: PHP (php)
Handle it like any other Provider
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
auth = request.env['omniauth.auth']
user = User.find_or_create_by(provider: auth['provider'], uid: auth['uid']) do |u|
u.email = auth['info']['email']
u.name = auth['info']['name']
end
session[:user_id] = user.id
redirect_to root_path, notice: "Signed in with Bitbucket!"
end
end
Code language: HTML, XML (xml)
That’s it, Bitbucket authentication is set up for the Rails app. There are many more things that can be done with custom OmniAuth strategies as compared to using functionalities by existing ones, tradeoff being custom strategies need to be self maintained
Wrapping Up
OmniAuth takes the pain out of dealing with different providers by offering a consistent, secure, and extensible framework for authentication. With its large ecosystem of strategies and the ability to roll your own when needed, it saves Rails developers from reinventing OAuth flows again and again.
Whether you’re setting up a quick GitHub login or building a custom integration, OmniAuth helps you focus on the features that matter while keeping authentication reliable.
Want to try GreyMonk?
Tell us and we will take care of everything. We will connect the tools, set the scopes, and you will start seeing clear, fair signals you can act on.