Skip to content
Kenta Ishizaki edited this page Jun 15, 2026 · 4 revisions

Configuration

Make sure you've configured Doorkeeper before continuing.

Verify your settings in config/initializers/doorkeeper.rb:

  • resource_owner_authenticator
    • This callback needs to returns a falsey value if the current user can't be determined:

      resource_owner_authenticator do
        if current_user
          current_user
        else
          redirect_to(new_user_session_url)
          nil
        end
      end
  • grant_flows
    • If you want to use id_token or id_token token response types you need to add implicit_oidc to grant_flows:

      grant_flows %w(authorization_code implicit_oidc)

The following settings are required in config/initializers/doorkeeper_openid_connect.rb:

  • issuer

    • Identifier for the issuer of the response (i.e. your application URL). The value is a case sensitive URL using the https scheme that contains scheme, host, and optionally, port number and path components and no query or fragment components.

    • You can either pass a string value, or a block to generate the issuer dynamically. The block receives resource_owner, application, and request so that the same configuration can serve both ID token issuance (where resource_owner and application are available) and the discovery endpoint (where only request is available):

      # config/initializers/doorkeeper_openid_connect.rb
      Doorkeeper::OpenidConnect.configure do
        # ...
        issuer do |resource_owner, application, request|
          request&.base_url || "https://default.example.com"
        end
      end
    • For backward compatibility, blocks with arity 0, 1, or 2 are also accepted. An arity-1 block receives request from the discovery endpoint and resource_owner from the ID token context, while an arity-2 block always receives resource_owner and application.

  • subject

    • Identifier for the resource owner (i.e. the authenticated user). A locally unique and never reassigned identifier within the issuer for the end-user, which is intended to be consumed by the client. The value is a case-sensitive string and must not exceed 255 ASCII characters in length.

    • The database ID of the user is an acceptable choice if you don't mind leaking that information.

    • If you want to provide a different subject identifier to each client, use pairwise subject identifier with configurations like below.

      # config/initializers/doorkeeper_openid_connect.rb
      Doorkeeper::OpenidConnect.configure do
      # ...
        subject_types_supported [:pairwise]
      
        subject do |resource_owner, application|
          Digest::SHA256.hexdigest("#{resource_owner.id}#{URI.parse(application.redirect_uri).host}#{'your_secret_salt'}")
        end
      # ...
      end
  • signing_key

  • signing_algorithm

    • The signing algorithm used for the ID token, which defaults to :rs256. The list of supported algorithms can be found here
  • resource_owner_from_access_token

    • Defines how to translate the Doorkeeper access token to a resource owner model.

Note

Both signing_key and signing_algorithm also accept callable objects (e.g. a lambda), which are evaluated on each call — useful for multi-tenant setups where the key or algorithm varies per request:

signing_key -> { current_tenant.private_key }
signing_algorithm -> { current_tenant.algorithm }

Note

signing_key also accepts an array for key rotation. The first entry is the active key used to sign newly issued ID tokens; the remaining entries are still published in the JWKS so clients can validate tokens signed with a retired key during a rotation window. Callable forms returning an array are also supported.

signing_key [
  File.read("config/keys/current.pem"),  # active, signs new tokens
  File.read("config/keys/previous.pem"), # retired, exposed in JWKS only
]

The following settings are optional, but recommended for better client compatibility:

  • auth_time_from_resource_owner
    • Returns the time of the user's last login, this can be a Time, DateTime, or any other class that responds to to_i
    • Used to populate the auth_time claim on the ID Token.
    • Used as a fallback for max_age enforcement when auth_time_from_session is not configured. Note: for multi-session deployments this is insecure (it returns the most recent login on any device), and emits a deprecation warning — prefer auth_time_from_session below.
  • auth_time_from_session
    • Returns the time the user authenticated for the current session. Required for correct max_age enforcement when the same user can hold multiple concurrent sessions (e.g. PC + smartphone) — auth_time_from_resource_owner cannot distinguish between sessions and would let a stale session inherit a fresh login from another device.

    • The block is executed in the controller's scope and receives (session, request). Return value can be a Time, DateTime, or anything responding to to_i. Return nil to force reauthentication.

      # Example: capture auth_time on the session at login,
      # and surface it here for the OIDC max_age check.
      auth_time_from_session do |session, _request|
        session[:auth_time]
      end
  • auth_time_from_access_token
    • Derives the auth_time claim from the access token (i.e. per grant) instead of from the resource owner (per user). Useful when you store auth_time in a custom authentication-context record linked to the access token.

    • The block receives the access token and the return value can be a Time, DateTime, or anything responding to to_i. When configured, it takes precedence over auth_time_from_resource_owner for populating the auth_time claim on the ID Token.

    • Note: this only affects the auth_time claim on the ID Token; it is not used for max_age enforcement, which still resolves auth_time via auth_time_from_session / auth_time_from_resource_owner.

      auth_time_from_access_token do |access_token|
        access_token.your_custom_authentication_context_record.auth_time
      end
  • reauthenticate_resource_owner
    • Defines how to trigger reauthentication for the current user (e.g. display a password prompt, or sign-out the user and redirect to the login form).
    • Required to support the max_age and prompt=login parameters.
    • The block is executed in the controller's scope, so you have access to methods like params, redirect_to etc.
  • select_account_for_resource_owner
    • Defines how to trigger account selection to choose the current login user.
    • Required to support the prompt=select_account parameter.
    • The block is executed in the controller's scope, so you have access to methods like params, redirect_to etc.

The following settings are optional:

  • expiration

    • Expiration time after which the ID Token must not be accepted for processing by clients.
    • The default is 120 seconds, it can be configured using a value or block.
      # config/initializers/doorkeeper_openid_connect.rb
      Doorkeeper::OpenidConnect.configure do
        # ...
        expiration do |resource_owner, application|
          # You will have to ensure the application model implements an expiration method
          application.expiration
        end
        # ...
      end
  • protocol

    • The protocol to use when generating URIs for the discovery endpoints.
    • The default is https for production, and http for all other environments
    • Note that the OIDC specification mandates HTTPS, so you shouldn't change this for production environments unless you have a really good reason!
  • end_session_endpoint

    • The URL that the user is redirected to after ending the session on the client.
    • Used by implementations like https://github.com/IdentityModel/oidc-client-js.
    • The block is executed in the controller's scope, so you have access to your route helpers.
  • discovery_url_options

    • The URL options for every available endpoint to use when generating the endpoint URL in the discovery response. Available endpoints: authorization, token, revocation, introspection, userinfo, jwks, dynamic_client_registration.

    • This option requires option keys with an available endpoint and URL options as value.

    • The default is to use the request host, just like all the other URLs in the discovery response.

    • This is useful when you want endpoints to use a different URL than other requests. For example, if your Doorkeeper server is behind a firewall with other servers, you might want other servers to use an "internal" URL to communicate with Doorkeeper, but you want to present an "external" URL to end-users for authentication requests. Note that this setting does not actually change the URL that your Doorkeeper server responds on - that is outside the scope of Doorkeeper.

      # config/initializers/doorkeeper_openid_connect.rb
      Doorkeeper::OpenidConnect.configure do
      # ...
        discovery_url_options do |request|
          {
            authorization: { host: 'host.example.com' },
            jwks:          { protocol: request.ssl? ? :https : :http }
          }
        end
      # ...
      end
  • apply_prompt_to_non_oidc_requests

    • Whether to honor the prompt authorization parameter (none, login, consent, select_account) on plain OAuth requests that do not include the openid scope.

    • Defaults to false, which preserves the historical behavior of silently ignoring prompt outside of OIDC requests.

    • max_age enforcement remains OIDC-only regardless of this option, since it is defined by OIDC Core.

      # config/initializers/doorkeeper_openid_connect.rb
      Doorkeeper::OpenidConnect.configure do
        # ...
        apply_prompt_to_non_oidc_requests true
        # ...
      end

See also

Clone this wiki locally