songkick-oauth2-provider implements OAuth 2.0 draft-10 and refuses to move
Simple OAuth 2.0 provider toolkit
At a glance
- What is it?
- This Ruby gem handles the OAuth 2.0 provider role for a Rails or Sinatra application, storing clients and authorizations in ActiveRecord and exposing a Rack-based API. Its most interesting decision is a deliberate refusal: it targets draft 10 of the specification and the maintainers decided not to track later drafts, so the version number tells you which semantics you are running.
- Who is it for?
- Adopt songkick-oauth2-provider if you are adding OAuth to a Ruby application and specifically want the draft-10 behaviour, and if you are prepared to own the parts the gem does not do, the client registration UI, the grant flow and the protected resources. Do not adopt it if you need the finalised specification's behaviour, since the maintainers explicitly decided not to track later drafts, and expect to write the client registration screen yourself.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 137 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the gem takes over
The gem provides a toolkit for adding OAuth 2.0 provider capabilities to a Ruby web app, and it handles most of the protocol for you.
The design intent is stated as an abstraction property: it is designed to provide a sufficient level of abstraction that it can implement updates to the protocol without affecting your application code at all. All you have to deal with is authenticating your users and letting them grant access to client apps.
That is a narrower and more honest description of what an OAuth provider library can do. The parts of the protocol that are pure mechanics, the authorization endpoint, the token endpoint, the grant exchange, the storage of clients and authorizations, the revocation, are what a library can absorb. The parts that are policy, which applications exist, what a user is told when they are asked for access, what your users see, cannot be abstracted away, because that is your product.
The README's own list of what you have to provide confirms the division. You need some UI to register client applications, the OAuth request endpoint, a flow for logged-in users to grant access to clients, and resources protected by access tokens.
Two implementation choices are worth noting. It is designed to be usable within any web frontend, at least those of Rails and Sinatra, and its API uses Rack request-environment hashes rather than framework-specific request objects, though you can pass those in and their `request.env` property will be used internally. So the gem sits at the Rack layer rather than the Rails layer, and the same code works in a Sinatra app.
And it stores the clients and authorizations using ActiveRecord, so the data lives in your application's database rather than in a separate store.
The project is Ruby, MIT licensed, with the tags 0.10.5 from 2025-12-02, 0.10.4 from 2023-03-15 and 0.10.3 from 2017-10-24, and the last push on 2026-06-09.
The versioning policy explains the version number
The note on versioning is the most useful paragraph in the README, and it explains something that would otherwise look like neglect.
The library is based on draft-10 of the OAuth 2.0 specification, which was current when the authors began writing it. Having observed the development of the OAuth 2.0 spec over time, they decided not to upgrade to later drafts until the spec is finalized. The reason given is that there is not enough meaningful change going on to merit migrating to every draft version, since it would simply create a lot of turbulence and make it hard to reason about exactly what semantics the library supports.
That is a considered position rather than an oversight. A library that tracked every draft would have shipped a sequence of breaking changes, and the thing an integrator needs most is to know which semantics apply, so freezing is a service to the reader.
The scheme it uses during the draft state is that the gem version indicates which draft it implements using the minor version. So 0.10.2 means the second bug-fix release for draft 10.
In practice that means the 0.10.x line is a patch line, and a 0.11 would signal a different draft. The current release history is consistent with that: 0.10.3 in 2017, 0.10.4 in 2023 and 0.10.5 in 2025, all the same minor version and therefore all the same draft semantics.
The practical consequence for an integrator is that this gem gives you OAuth 2.0 as it was specified in 2012. That predates much of what followed, including the mandatory use of PKCE for public clients, the device authorization grant, and the security best current practice that later made the implicit grant unusable in a browser. If you are integrating a modern third-party client, that gap is the thing to check first.
Setting the realm and enforcing HTTPS
The first piece of configuration is the realm, which is the display name shown to users during the grant flow. You declare it somewhere in your application, for example in `application.rb` or an initializer:
require 'songkick/oauth2/provider'
Songkick::OAuth2::Provider.realm = 'My OAuth app'The second is the transport requirement, and it is the more important of the two.
Your application should ensure that any endpoint that receives or returns OAuth data is only accessible over a secure transport such as the `https:` protocol, and the gem can enforce this to make it easier to keep your users' data secure. You set `Songkick::OAuth2::Provider.enforce_ssl = true` in the same place where you declared the app name.
The README then lists the three behaviours that setting produces, and they are worth reading in full because they go beyond refusing the request.
The `Songkick::OAuth2::Provider.parse` method produces error responses and does not process the incoming request unless the request was made using the `https:` protocol. An access token constructed using `Songkick::OAuth2::Provider.access_token` returns `false` for `#valid?` unless the request was made over `https:`. And any access token received over an insecure connection is immediately destroyed to prevent eavesdroppers getting access to the user's resources, with the client making an insecure request having to send the user through the authorization process again to get a new token.
That third behaviour is the one that distinguishes this from a simple guard. A token that has leaked over an unencrypted connection is not merely untrusted, it is deleted, so an attacker holding it has nothing. The cost is that a misconfigured client which sends one request over plain HTTP invalidates a token the user legitimately obtained, and the client then has to run the whole authorization flow again.
That is a deliberate fail-safe, and it means you should turn the flag on before you have real clients registered rather than after.
Schema, and the two mixins you add to your models
The gem brings its own database tables, and they are installed with a migration call:
Songkick::OAuth2::Model::Schema.migrate
I, [2012-10-31T14:52:33.801428 #7002] INFO -- : Migrating to SongkickOauth2SchemaOriginalSchema (20120828112156)
== SongkickOauth2SchemaOriginalSchema: migrating =============================
-- create_table(:oauth2_clients)
-> 0.0029s
-- add_index(:oauth2_clients, [:client_id])
-> 0.0009s
...The call runs all the gem's migrations that have not yet been applied to your database, and to roll them back there is a corresponding `Songkick::OAuth2::Model::Schema.rollback`. The table names are prefixed, `oauth2_clients` for instance, and the `client_id` is indexed because it is looked up on every request.
Then there are two mixins to include in your models. `Songkick::OAuth2::Model::ClientOwner` goes on whichever model owns the apps, and `Songkick::OAuth2::Model::ResourceOwner` goes on whichever model is the entity that selectively shares its data.
They can be the same model, which is the usual case:
class User < ActiveRecord::Base
include Songkick::OAuth2::Model::ResourceOwner
include Songkick::OAuth2::Model::ClientOwner
has_many :interesting_pieces_of_data
endOr they can be two different models, where one user owns the applications of a company:
include Songkick::OAuth2::Model::ResourceOwner
has_many :interesting_pieces_of_data include Songkick::OAuth2::Model::ClientOwner
belongs_to :userThe split matters when a platform has both individual users and organisations, since the OAuth concepts then map onto two different entities. The README points at `lib/oauth2/model/client_owner.rb` and `lib/oauth2/model/resource_owner.rb` for the associations and methods each mixin adds.
Registering client applications is yours to build
Clients are modelled by the `Songkick::OAuth2::Model::Client` class, which is an ActiveRecord model, and the gem gives you a data structure rather than a screen. The README's example builds the screen in a Sinatra app:
get '/oauth/apps/new' do
@client = Songkick::OAuth2::Model::Client.new
erb :new_client
end
post '/oauth/apps' do
@client = Songkick::OAuth2::Model::Client.new(params)
@client.save ? erb(:show_client) : erb(:new_client)
endThat is a create form and a create action, and it is the whole of what the gem asks for here, which is why the requirement list said you need some UI to register client applications.
The rules around the client fields are where the care is. Client applications must have a `name` and a `redirect_uri`, so provide fields for editing those, but do not allow the other fields to be edited since they are the client's access credentials.
When you have created the client, you should show its details to the user registering the client: its `name`, its `redirect_uri`, its `client_id` and its `client_secret`, with the last two generated for you.
That instruction carries the security logic of the whole feature. The client id and secret are generated rather than chosen, the secret is shown once at creation rather than being editable afterwards, and the redirect uri is editable because clients legitimately need to change it. It also means the gem's job ends where the UI begins: the secret is your responsibility to display once and then protect, and to revoke if it leaks.
The repository carries a complete example application under `example/`, with `application.rb`, `config.ru`, `environment.rb`, `models/`, `views/`, `public/` and a `schema.rb`, plus a `README.rdoc` in that directory, and the README points at `example/application.rb` as the basic example.
Where this sits against the alternatives
The alternative approaches to being an OAuth 2.0 provider come down to three, and the differences are in the protocol version and in how much you write.
The first is another Ruby library that implements the finalised specification. The difference in approach is the semantics: a current library gives you PKCE, the device grant, and the security practices that later drafts and the current best practice require, and it will track the specification as it settles. What you give up is the guarantee that a given version means a given set of semantics, and you inherit whatever the other library's version history implies.
The second is a hosted identity provider, where you delegate the whole provider role. The difference is where the client registry and the authorization records live: in someone else's database, which removes the code and the maintenance and removes your control over the redirect uri rules, the token lifetimes and the revocation behaviour.
The third is implementing the provider endpoints yourself in your application. That is what this gem saves you from, and the saving is real: the authorization code exchange, the token generation, the signature verification and the storage are all code that is easy to get subtly wrong.
The case for songkick-oauth2-provider specifically is that it is small, it is Rack-based so it does not force a framework, and it is frozen at a known specification version. The case against is the age of that version and the age of the code itself, with the last release from December 2025 and the previous one from March 2023, on an ActiveRecord-based stack that has moved on in the years since 2012.
For a long-lived internal integration with a fixed client, where the clients are yours and you control them, draft-10 semantics are adequate. For a public API with third-party developers, the gap between draft-10 and the current specification is the deciding factor.
Editorial conclusion
Adopt songkick-oauth2-provider if you are adding OAuth to a Ruby application and specifically want the draft-10 behaviour, and if you are prepared to own the parts the gem does not do, the client registration UI, the grant flow and the protected resources. Do not adopt it if you need the finalised specification's behaviour, since the maintainers explicitly decided not to track later drafts, and expect to write the client registration screen yourself. Verify first that the ActiveRecord schema migration runs cleanly on your version of Rails, that you enable `enforce_ssl` before you have real clients registered, and that the version you install is 0.10.5 from 2025-12-02, the most recent tag, with the last push on 2026-06-09.
Frequently asked questions
What does the songkick-oauth2-provider gem do?
It provides a toolkit for adding OAuth 2.0 provider capabilities to a Ruby web app, handling most of the protocol so that the application only has to authenticate users and let them grant access to client apps. It uses Rack request-environment hashes so it works with Rails, Sinatra and other Rack frontends, and stores clients and authorizations with ActiveRecord.
Which version of the OAuth 2.0 specification does the gem implement?
Draft 10, which was current when the authors began writing it. They decided not to upgrade to later drafts until the spec is finalized, since there was not enough meaningful change to merit migrating to every draft. During draft state the minor version indicates the draft, so 0.10.2 is the second bug-fix release for draft 10.
How do I install and set up the gem?
Run `gem install songkick-oauth2-provider`, require it and set the realm, then run the schema migration with `Songkick::OAuth2::Model::Schema.migrate` to add the gem's tables, with `Songkick::OAuth2::Model::Schema.rollback` to undo them. Then include the ClientOwner and ResourceOwner mixins in your models.
What does enforce_ssl change?
With `Songkick::OAuth2::Provider.enforce_ssl = true`, the parse method produces error responses and does not process requests that are not over https, an access token returns false for `#valid?` on a non-https request, and any access token received over an insecure connection is immediately destroyed so a client has to run the authorization process again.
What do I have to build myself?
Four things: some UI to register client applications, the OAuth request endpoint, a flow for logged-in users to grant access to clients, and resources protected by access tokens. The client model is provided as an ActiveRecord class, and the README's Sinatra example shows the registration form being built on top of it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/songkick-oauth2-provider)Was this useful?