doorkeeper-gem/doorkeeper

uninitialized constant for access_token_model when using custom_access_token_attributes config

matthewheath opened this issue ยท 3 comments

I am trying to configure custom_access_token_attributes in doorkeeper.rb to look for a custom attribute of company_id, but Doorkeeper config fails to constantize my custom model classes when this option is enabled. When the option is disabled, everything works perfectly: Doorkeeper can find my custom model classes, this only happens when that config option is enabled.

We auto-load the relevant models from a backend/modules folder like so, from an initializers/autoloaded_paths.rb file in Rails config/:

Rails.autoloaders.main.tap do |loader|
  loader.push_dir("#{Rails.root}/backend/modules")
  loader.collapse("#{Rails.root}/backend/modules/*/models")
end

So a model like backend/modules/public_api/models/oauth_access_grant.rb would be available as PublicAPI::OauthAccessGrant. Rails correctly constantizes that class when fully loaded, but Doorkeeper can't seem to look it up properly when custom_access_token_attributes is set in doorkeeper.rb

Is this because those classes simply aren't auto-loaded and available at the time Doorkeeper runs? Is there a best practice way of making those custom classes available to Doorkeeper?

The backtrace is:

backtrace content
NameError: uninitialized constant PublicAPI

      Object.const_get(camel_cased_word)
            ^^^^^^^^^^
Did you mean?  PublicSuffix
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/inflector/methods.rb:280:in `constantize'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config.rb:434:in `access_token_model'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:59:in `block in validate_custom_access_token_attributes'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:58:in `each'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:58:in `validate_custom_access_token_attributes'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/validations.rb:14:in `validate!'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper/config/abstract_builder.rb:23:in `build'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/doorkeeper-5.6.5/lib/doorkeeper.rb:121:in `configure'
/Users/matthew/code/anywhere/config/initializers/doorkeeper.rb:3:in `<main>'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:39:in `load'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:667:in `block in load_config_initializer'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/activesupport-7.0.4.3/lib/active_support/notifications.rb:208:in `instrument'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:666:in `load_config_initializer'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:620:in `block (2 levels) in <class:Engine>'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:619:in `each'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/engine.rb:619:in `block in <class:Engine>'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `instance_exec'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `run'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:61:in `block in run_initializers'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:50:in `each'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:50:in `tsort_each_child'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/initializable.rb:60:in `run_initializers'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/application.rb:372:in `initialize!'
/Users/matthew/code/anywhere/config/environment.rb:7:in `<main>'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/bootsnap-1.11.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:38:in `require'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/application.rb:348:in `require_environment!'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/railties-7.0.4.3/lib/rails/application.rb:511:in `block in run_tasks_blocks'
/Users/matthew/code/anywhere/vendor/nix/gems/ruby/3.1.0/gems/sentry-ruby-core-5.2.1/lib/sentry/rake.rb:24:in `execute'

System configuration

Doorkeeper initializer:

doorkeeper.rb content
# config/initializers/doorkeeper.rb
# frozen_string_literal: true

Doorkeeper.configure do
  # Change the ORM that doorkeeper will use (requires ORM extensions installed).
  # Check the list of supported ORMs here: https://github.com/doorkeeper-gem/doorkeeper#orms
  orm :active_record

  # This block will be called to check whether the resource owner is authenticated or not.
  resource_owner_authenticator do
    current_user || warden.authenticate!(scope: :user)
    # Put your resource owner authentication logic here.
    # Example implementation:
    #   User.find_by(id: session[:user_id]) || redirect_to(new_user_session_url)
  end

  # If you didn't skip applications controller from Doorkeeper routes in your application routes.rb
  # file then you need to declare this block in order to restrict access to the web interface for
  # adding oauth authorized applications. In other case it will return 403 Forbidden response
  # every time somebody will try to access the admin web interface.
  #
  # admin_authenticator do
  #   # Put your admin authentication logic here.
  #   # Example implementation:
  #
  #   if current_user
  #     head :forbidden unless current_user.admin?
  #   else
  #     redirect_to sign_in_url
  #   end
  # end

  # You can use your own model classes if you need to extend (or even override) default
  # Doorkeeper models such as `Application`, `AccessToken` and `AccessGrant.
  #
  # Be default Doorkeeper ActiveRecord ORM uses it's own classes:
  #
  # access_token_class "Doorkeeper::AccessToken"
  # access_grant_class "Doorkeeper::AccessGrant"
  # application_class "Doorkeeper::Application"
  #
  # Don't forget to include Doorkeeper ORM mixins into your custom models:
  #
  #   *  ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken - for access token
  #   *  ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant - for access grant
  #   *  ::Doorkeeper::Orm::ActiveRecord::Mixins::Application - for application (OAuth2 clients)
  #
  # For example:
  #
  # access_token_class "MyAccessToken"
  #
  # class MyAccessToken < ApplicationRecord
  #   include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken
  #
  #   self.table_name = "hey_i_wanna_my_name"
  #
  #   def destroy_me!
  #     destroy
  #   end
  # end
  access_grant_class "PublicAPI::OauthAccessGrant"
  access_token_class "PublicAPI::OauthAccessToken"
  application_class "PublicAPI::OauthApplication"

  # Enables polymorphic Resource Owner association for Access Tokens and Access Grants.
  # By default this option is disabled.
  #
  # Make sure you properly setup you database and have all the required columns (run
  # `bundle exec rails generate doorkeeper:enable_polymorphic_resource_owner` and execute Rails
  # migrations).
  #
  # If this option enabled, Doorkeeper will store not only Resource Owner primary key
  # value, but also it's type (class name). See "Polymorphic Associations" section of
  # Rails guides: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations
  #
  # [NOTE] If you apply this option on already existing project don't forget to manually
  # update `resource_owner_type` column in the database and fix migration template as it will
  # set NOT NULL constraint for Access Grants table.
  #
  # use_polymorphic_resource_owner

  # If you are planning to use Doorkeeper in Rails 5 API-only application, then you might
  # want to use API mode that will skip all the views management and change the way how
  # Doorkeeper responds to a requests.
  #
  api_only

  # Enforce token request content type to application/x-www-form-urlencoded.
  # It is not enabled by default to not break prior versions of the gem.
  #
  enforce_content_type

  # Authorization Code expiration time (default: 10 minutes).
  #
  # authorization_code_expires_in 10.minutes

  # Access token expiration time (default: 2 hours).
  # If you want to disable expiration, set this to `nil`.
  #
  # access_token_expires_in 2.hours

  # Assign custom TTL for access tokens. Will be used instead of access_token_expires_in
  # option if defined. In case the block returns `nil` value Doorkeeper fallbacks to
  # +access_token_expires_in+ configuration option value. If you really need to issue a
  # non-expiring access token (which is not recommended) then you need to return
  # Float::INFINITY from this block.
  #
  # `context` has the following properties available:
  #
  #   * `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
  #   * `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
  #   * `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
  #   * `resource_owner` - authorized resource owner instance (if present)
  #
  # custom_access_token_expires_in do |context|
  #   context.client.additional_settings.implicit_oauth_expiration
  # end

  # Use a custom class for generating the access token.
  # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
  #
  # access_token_generator '::Doorkeeper::JWT'

  # The controller +Doorkeeper::ApplicationController+ inherits from.
  # Defaults to +ActionController::Base+ unless +api_only+ is set, which changes the default to
  # +ActionController::API+. The return value of this option must be a stringified class name.
  # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
  #
  # base_controller 'ApplicationController'

  # Reuse access token for the same resource owner within an application (disabled by default).
  #
  # This option protects your application from creating new tokens before old **valid** one becomes
  # expired so your database doesn't bloat. Keep in mind that when this option is enabled Doorkeeper
  # doesn't update existing token expiration time, it will create a new token instead if no active matching
  # token found for the application, resources owner and/or set of scopes.
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
  #
  # You can not enable this option together with +hash_token_secrets+.
  #
  # reuse_access_token

  # In case you enabled `reuse_access_token` option Doorkeeper will try to find matching
  # token using `matching_token_for` Access Token API that searches for valid records
  # in batches in order not to pollute the memory with all the database records. By default
  # Doorkeeper uses batch size of 10 000 records. You can increase or decrease this value
  # depending on your needs and server capabilities.
  #
  # token_lookup_batch_size 10_000

  # Set a limit for token_reuse if using reuse_access_token option
  #
  # This option limits token_reusability to some extent.
  # If not set then access_token will be reused unless it expires.
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
  #
  # This option should be a percentage(i.e. (0,100])
  #
  # token_reuse_limit 100

  # Only allow one valid access token obtained via client credentials
  # per client. If a new access token is obtained before the old one
  # expired, the old one gets revoked (disabled by default)
  #
  # When enabling this option, make sure that you do not expect multiple processes
  # using the same credentials at the same time (e.g. web servers spanning
  # multiple machines and/or processes).
  #
  # revoke_previous_client_credentials_token

  # Hash access and refresh tokens before persisting them.
  # This will disable the possibility to use +reuse_access_token+
  # since plain values can no longer be retrieved.
  #
  # Note: If you are already a user of doorkeeper and have existing tokens
  # in your installation, they will be invalid without adding 'fallback: :plain'.
  #
  # hash_token_secrets
  # By default, token secrets will be hashed using the
  # +Doorkeeper::Hashing::SHA256+ strategy.
  #
  # If you wish to use another hashing implementation, you can override
  # this strategy as follows:
  #
  # hash_token_secrets using: '::Doorkeeper::Hashing::MyCustomHashImpl'
  #
  # Keep in mind that changing the hashing function will invalidate all existing
  # secrets, if there are any.

  # Hash application secrets before persisting them.
  #
  # hash_application_secrets
  #
  # By default, applications will be hashed
  # with the +Doorkeeper::SecretStoring::SHA256+ strategy.
  #
  # If you wish to use bcrypt for application secret hashing, uncomment
  # this line instead:
  #
  # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt'

  # When the above option is enabled, and a hashed token or secret is not found,
  # you can allow to fall back to another strategy. For users upgrading
  # doorkeeper and wishing to enable hashing, you will probably want to enable
  # the fallback to plain tokens.
  #
  # This will ensure that old access tokens and secrets
  # will remain valid even if the hashing above is enabled.
  #
  # This can be done by adding 'fallback: plain', e.g. :
  #
  # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt', fallback: :plain

  # Issue access tokens with refresh token (disabled by default), you may also
  # pass a block which accepts `context` to customize when to give a refresh
  # token or not. Similar to +custom_access_token_expires_in+, `context` has
  # the following properties:
  #
  # `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
  # `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
  # `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
  #
  use_refresh_token

  # Provide support for an owner to be assigned to each registered application (disabled by default)
  # Optional parameter confirmation: true (default: false) if you want to enforce ownership of
  # a registered application
  # NOTE: you must also run the rails g doorkeeper:application_owner generator
  # to provide the necessary support
  #
  enable_application_owner confirmation: true

  # Define access token scopes for your provider
  # For more information go to
  # https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
  #
  # default_scopes  :public
  # optional_scopes :write, :update
  default_scopes :read

  # Allows to restrict only certain scopes for grant_type.
  # By default, all the scopes will be available for all the grant types.
  #
  # Keys to this hash should be the name of grant_type and
  # values should be the array of scopes for that grant type.
  # Note: scopes should be from configured_scopes (i.e. default or optional)
  #
  # scopes_by_grant_type password: [:write], client_credentials: [:update]

  # Forbids creating/updating applications with arbitrary scopes that are
  # not in configuration, i.e. +default_scopes+ or +optional_scopes+.
  # (disabled by default)
  #
  # enforce_configured_scopes

  # Change the way client credentials are retrieved from the request object.
  # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
  # falls back to the `:client_id` and `:client_secret` params from the `params` object.
  # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated
  # for more information on customization
  #
  # client_credentials :from_basic, :from_params

  # Change the way access token is authenticated from the request object.
  # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
  # falls back to the `:access_token` or `:bearer_token` params from the `params` object.
  # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated
  # for more information on customization
  #
  # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param

  # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
  # by default in non-development environments). OAuth2 delegates security in
  # communication to the HTTPS protocol so it is wise to keep this enabled.
  #
  # Callable objects such as proc, lambda, block or any object that responds to
  # #call can be used in order to allow conditional checks (to allow non-SSL
  # redirects to localhost for example).
  #
  # force_ssl_in_redirect_uri !Rails.env.development?
  #
  # force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }

  # Specify what redirect URI's you want to block during Application creation.
  # Any redirect URI is allowed by default.
  #
  # You can use this option in order to forbid URI's with 'javascript' scheme
  # for example.
  #
  # forbid_redirect_uri { |uri| uri.scheme.to_s.downcase == 'javascript' }

  # Allows to set blank redirect URIs for Applications in case Doorkeeper configured
  # to use URI-less OAuth grant flows like Client Credentials or Resource Owner
  # Password Credentials. The option is on by default and checks configured grant
  # types, but you **need** to manually drop `NOT NULL` constraint from `redirect_uri`
  # column for `oauth_applications` database table.
  #
  # You can completely disable this feature with:
  #
  # allow_blank_redirect_uri false
  #
  # Or you can define your custom check:
  #
  # allow_blank_redirect_uri do |grant_flows, client|
  #   client.superapp?
  # end
  allow_blank_redirect_uri false

  # Specify how authorization errors should be handled.
  # By default, doorkeeper renders json errors when access token
  # is invalid, expired, revoked or has invalid scopes.
  #
  # If you want to render error response yourself (i.e. rescue exceptions),
  # set +handle_auth_errors+ to `:raise` and rescue Doorkeeper::Errors::InvalidToken
  # or following specific errors:
  #
  #   Doorkeeper::Errors::TokenForbidden, Doorkeeper::Errors::TokenExpired,
  #   Doorkeeper::Errors::TokenRevoked, Doorkeeper::Errors::TokenUnknown
  #
  # handle_auth_errors :raise

  # Customize token introspection response.
  # Allows to add your own fields to default one that are required by the OAuth spec
  # for the introspection response. It could be `sub`, `aud` and so on.
  # This configuration option can be a proc, lambda or any Ruby object responds
  # to `.call` method and result of it's invocation must be a Hash.
  #
  # custom_introspection_response do |token, context|
  #   {
  #     "sub": "Z5O3upPC88QrAjx00dis",
  #     "aud": "https://protected.example.net/resource",
  #     "username": User.find(token.resource_owner_id).username
  #   }
  # end
  #
  # or
  #
  # custom_introspection_response CustomIntrospectionResponder

  # Specify what grant flows are enabled in array of Strings. The valid
  # strings and the flows they enable are:
  #
  # "authorization_code" => Authorization Code Grant Flow
  # "implicit"           => Implicit Grant Flow
  # "password"           => Resource Owner Password Credentials Grant Flow
  # "client_credentials" => Client Credentials Grant Flow
  #
  # If not specified, Doorkeeper enables authorization_code and
  # client_credentials.
  #
  # implicit and password grant flows have risks that you should understand
  # before enabling:
  #   https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.2
  #   https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.3
  #
  grant_flows %w[authorization_code]

  # Allows to customize OAuth grant flows that +each+ application support.
  # You can configure a custom block (or use a class respond to `#call`) that must
  # return `true` in case Application instance supports requested OAuth grant flow
  # during the authorization request to the server. This configuration +doesn't+
  # set flows per application, it only allows to check if application supports
  # specific grant flow.
  #
  # For example you can add an additional database column to `oauth_applications` table,
  # say `t.array :grant_flows, default: []`, and store allowed grant flows that can
  # be used with this application there. Then when authorization requested Doorkeeper
  # will call this block to check if specific Application (passed with client_id and/or
  # client_secret) is allowed to perform the request for the specific grant type
  # (authorization, password, client_credentials, etc).
  #
  # Example of the block:
  #
  #   ->(flow, client) { client.grant_flows.include?(flow) }
  #
  # In case this option invocation result is `false`, Doorkeeper server returns
  # :unauthorized_client error and stops the request.
  #
  # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
  # @return [Boolean] `true` if allow or `false` if forbid the request
  #
  # allow_grant_flow_for_client do |grant_flow, client|
  #   # `grant_flows` is an Array column with grant
  #   # flows that application supports
  #
  #   client.grant_flows.include?(grant_flow)
  # end

  # If you need arbitrary Resource Owner-Client authorization you can enable this option
  # and implement the check your need. Config option must respond to #call and return
  # true in case resource owner authorized for the specific application or false in other
  # cases.
  #
  # Be default all Resource Owners are authorized to any Client (application).
  #
  # authorize_resource_owner_for_client do |client, resource_owner|
  #   resource_owner.admin? || client.owners_allowlist.include?(resource_owner)
  # end

  # Allows additional data fields to be sent while granting access to an application,
  # and for this additional data to be included in subsequently generated access tokens.
  # The 'authorizations/new' page will need to be overridden to include this additional data
  # in the request params when granting access. The access grant and access token models
  # will both need to respond to these additional data fields, and have a database column
  # to store them in.
  #
  # Example:
  # You have a multi-tenanted platform and want to be able to grant access to a specific
  # tenant, rather than all the tenants a user has access to. You can use this config
  # option to specify that a ':tenant_id' will be passed when authorizing. This tenant_id
  # will be included in the access tokens. When a request is made with one of these access
  # tokens, you can check that the requested data belongs to the specified tenant.
  #
  # Default value is an empty Array: []
  # custom_access_token_attributes [:tenant_id]
  custom_access_token_attributes [:company_id]

  # Hook into the strategies' request & response life-cycle in case your
  # application needs advanced customization or logging:
  #
  # before_successful_strategy_response do |request|
  #   puts "BEFORE HOOK FIRED! #{request}"
  # end
  #
  # after_successful_strategy_response do |request, response|
  #   puts "AFTER HOOK FIRED! #{request}, #{response}"
  # end

  # Hook into Authorization flow in order to implement Single Sign Out
  # or add any other functionality. Inside the block you have an access
  # to `controller` (authorizations controller instance) and `context`
  # (Doorkeeper::OAuth::Hooks::Context instance) which provides pre auth
  # or auth objects with issued token based on hook type (before or after).
  #
  # before_successful_authorization do |controller, context|
  #   Rails.logger.info(controller.request.params.inspect)
  #
  #   Rails.logger.info(context.pre_auth.inspect)
  # end
  #
  # after_successful_authorization do |controller, context|
  #   controller.session[:logout_urls] <<
  #     Doorkeeper::Application
  #       .find_by(controller.request.params.slice(:redirect_uri))
  #       .logout_uri
  #
  #   Rails.logger.info(context.auth.inspect)
  #   Rails.logger.info(context.issued_token)
  # end

  # Under some circumstances you might want to have applications auto-approved,
  # so that the user skips the authorization step.
  # For example if dealing with a trusted application.
  #
  # skip_authorization do |resource_owner, client|
  #   client.superapp? or resource_owner.admin?
  # end

  # Configure custom constraints for the Token Introspection request.
  # By default this configuration option allows to introspect a token by another
  # token of the same application, OR to introspect the token that belongs to
  # authorized client (from authenticated client) OR when token doesn't
  # belong to any client (public token). Otherwise requester has no access to the
  # introspection and it will return response as stated in the RFC.
  #
  # Block arguments:
  #
  # @param token [Doorkeeper::AccessToken]
  #   token to be introspected
  #
  # @param authorized_client [Doorkeeper::Application]
  #   authorized client (if request is authorized using Basic auth with
  #   Client Credentials for example)
  #
  # @param authorized_token [Doorkeeper::AccessToken]
  #   Bearer token used to authorize the request
  #
  # In case the block returns `nil` or `false` introspection responses with 401 status code
  # when using authorized token to introspect, or you'll get 200 with { "active": false } body
  # when using authorized client to introspect as stated in the
  # RFC 7662 section 2.2. Introspection Response.
  #
  # Using with caution:
  # Keep in mind that these three parameters pass to block can be nil as following case:
  #  `authorized_client` is nil if and only if `authorized_token` is present, and vice versa.
  #  `token` will be nil if and only if `authorized_token` is present.
  # So remember to use `&` or check if it is present before calling method on
  # them to make sure you doesn't get NoMethodError exception.
  #
  # You can define your custom check:
  #
  # allow_token_introspection do |token, authorized_client, authorized_token|
  #   if authorized_token
  #     # customize: require `introspection` scope
  #     authorized_token.application == token&.application ||
  #       authorized_token.scopes.include?("introspection")
  #   elsif token.application
  #     # `protected_resource` is a new database boolean column, for example
  #     authorized_client == token.application || authorized_client.protected_resource?
  #   else
  #     # public token (when token.application is nil, token doesn't belong to any application)
  #     true
  #   end
  # end
  #
  # Or you can completely disable any token introspection:
  #
  # allow_token_introspection false
  #
  # If you need to block the request at all, then configure your routes.rb or web-server
  # like nginx to forbid the request.
  allow_token_introspection false

  # WWW-Authenticate Realm (default: "Doorkeeper").
  #
  # realm "Doorkeeper"
end

Ruby version: 3.1.0

Gemfile.lock:

Gemfile.lock content
GIT
  remote: https://github.com/heartcombo/devise.git
  revision: 025b1c873491908b346e4d394f54481ec18fb02c
  specs:
    devise (4.8.1)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 4.1.0)
      responders
      warden (~> 1.2.3)

GIT
  remote: https://github.com/oysterhr/hellosign-api.git
  revision: 280481725850274de6d3f777bb6ae568d5fd9276
  specs:
    hellosign-api (1.0.7)
      faraday (>= 2.0.0)
      faraday-multipart (>= 1.0.0)
      mime-types (>= 3.0.0)
      multi_json (>= 1.0.0)

PATH
  remote: engines/brain
  specs:
    brain (0.1.0)
      activejob
      airrecord (~> 1.0, >= 1.0.11)
      countries
      money-rails
      oyster-action
      pg
      rails (~> 7.0.4.3)
      strong_migrations

PATH
  remote: engines/codat
  specs:
    codat (0.1.0)
      argo
      hairtrigger
      net-smtp
      oyster-action
      oyster-events
      rails (~> 7.0.2)
      strong_migrations

PATH
  remote: engines/dealer
  specs:
    dealer (0.1.0)
      aasm (~> 5.0, >= 5.2.0)
      docusign_esign (~> 3.0, >= 3.19.0)
      faraday (>= 2.0)
      faraday-retry
      oyster-action
      oyster-common
      oyster-events
      paper_trail
      pdf-reader (~> 2.10)
      pg
      rails (~> 7.0.2)
      strong_migrations

PATH
  remote: engines/expensify
  specs:
    expensify (0.1.0)
      argo
      oyster-action
      oyster-events
      rails (~> 7.0.2)
      sidekiq (~> 6.4.1)
      sidekiq-unique-jobs
      strong_migrations

PATH
  remote: engines/iam
  specs:
    iam (0.1.0)
      oso-cloud (~> 1.0.0)
      pg
      rails (~> 7.0.4)

PATH
  remote: engines/oyster-events
  specs:
    oyster-events (0.1.0)
      oyster-action
      rails (>= 7.0.2)
      rails_event_store
      ruby_event_store-rspec

PATH
  remote: gems/argo
  specs:
    argo (0.1.0)
      activesupport
      webmock

PATH
  remote: gems/oyster-action
  specs:
    oyster-action (0.1.0)
      activesupport

PATH
  remote: gems/oyster-common
  specs:
    oyster-common (0.1.0)
      activemodel
      activesupport
      zeitwerk

PATH
  remote: gems/sage-decision
  specs:
    sage-decision (0.1.0)
      activesupport
      rubytree

GEM
  remote: https://******@gems.contribsys.com/
  specs:
    sidekiq-pro (5.3.1)
      sidekiq (>= 6.3.0)

GEM
  remote: https://rubygems.org/
  specs:
    Ascii85 (1.1.0)
    aasm (5.2.0)
      concurrent-ruby (~> 1.0)
    actioncable (7.0.4.3)
      actionpack (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailbox (7.0.4.3)
      actionpack (= 7.0.4.3)
      activejob (= 7.0.4.3)
      activerecord (= 7.0.4.3)
      activestorage (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      mail (>= 2.7.1)
      net-imap
      net-pop
      net-smtp
    actionmailer (7.0.4.3)
      actionpack (= 7.0.4.3)
      actionview (= 7.0.4.3)
      activejob (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      mail (~> 2.5, >= 2.5.4)
      net-imap
      net-pop
      net-smtp
      rails-dom-testing (~> 2.0)
    actionpack (7.0.4.3)
      actionview (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      rack (~> 2.0, >= 2.2.0)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.2.0)
    actiontext (7.0.4.3)
      actionpack (= 7.0.4.3)
      activerecord (= 7.0.4.3)
      activestorage (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      globalid (>= 0.6.0)
      nokogiri (>= 1.8.5)
    actionview (7.0.4.3)
      activesupport (= 7.0.4.3)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.1, >= 1.2.0)
    activejob (7.0.4.3)
      activesupport (= 7.0.4.3)
      globalid (>= 0.3.6)
    activemodel (7.0.4.3)
      activesupport (= 7.0.4.3)
    activerecord (7.0.4.3)
      activemodel (= 7.0.4.3)
      activesupport (= 7.0.4.3)
    activestorage (7.0.4.3)
      actionpack (= 7.0.4.3)
      activejob (= 7.0.4.3)
      activerecord (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      marcel (~> 1.0)
      mini_mime (>= 1.1.0)
    activesupport (7.0.4.3)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 1.6, < 2)
      minitest (>= 5.1)
      tzinfo (~> 2.0)
    addressable (2.8.1)
      public_suffix (>= 2.0.2, < 6.0)
    administrate (0.17.0)
      actionpack (>= 5.0)
      actionview (>= 5.0)
      activerecord (>= 5.0)
      datetime_picker_rails (~> 0.0.7)
      jquery-rails (>= 4.0)
      kaminari (>= 1.0)
      momentjs-rails (~> 2.8)
      sassc-rails (~> 2.1)
      selectize-rails (~> 0.6)
    administrate-field-active_storage (0.4.1)
      administrate (>= 0.2.2)
      rails (>= 7.0)
    administrate-field-enum (0.0.9)
      administrate (~> 0.12)
    administrate-field-jsonb (0.4.6)
      administrate (< 1.0.0)
      rails (>= 4.2)
    administrate-field-nested_has_many (1.3.0)
      administrate (> 0.8, < 1)
      cocoon (~> 1.2, >= 1.2.11)
    afm (0.2.2)
    after_commit_everywhere (0.1.5)
      activerecord (>= 4.2)
    aggregate_root (2.4.1)
      ruby_event_store (= 2.4.1)
    airrecord (1.0.11)
      faraday (>= 1.0, < 3.0)
      faraday-net_http_persistent
      net-http-persistent
    akami (1.3.1)
      gyoku (>= 0.4.0)
      nokogiri
    analytics-ruby (2.0.13)
    arkency-command_bus (0.4.1)
      concurrent-ruby
    ast (2.4.2)
    awesome_print (1.8.0)
    aws-eventstream (1.1.0)
    aws-partitions (1.418.0)
    aws-sdk-core (3.111.2)
      aws-eventstream (~> 1, >= 1.0.2)
      aws-partitions (~> 1, >= 1.239.0)
      aws-sigv4 (~> 1.1)
      jmespath (~> 1.0)
    aws-sdk-kms (1.41.0)
      aws-sdk-core (~> 3, >= 3.109.0)
      aws-sigv4 (~> 1.1)
    aws-sdk-s3 (1.87.0)
      aws-sdk-core (~> 3, >= 3.109.0)
      aws-sdk-kms (~> 1)
      aws-sigv4 (~> 1.1)
    aws-sigv4 (1.2.2)
      aws-eventstream (~> 1, >= 1.0.2)
    backport (1.2.0)
    bcrypt (3.1.16)
    benchmark (0.2.0)
    bindex (0.8.1)
    bootsnap (1.11.1)
      msgpack (~> 1.2)
    brpoplpush-redis_script (0.1.3)
      concurrent-ruby (~> 1.0, >= 1.0.5)
      redis (>= 1.0, < 6)
    builder (3.2.4)
    bundle-audit (0.1.0)
      bundler-audit
    bundler-audit (0.9.1)
      bundler (>= 1.2.0, < 3)
      thor (~> 1.0)
    byebug (11.1.3)
    capybara (3.37.1)
      addressable
      matrix
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (>= 1.5, < 3.0)
      xpath (~> 3.2)
    capybara-lockstep (1.2.1)
      activesupport (>= 3.2)
      capybara (>= 2.0)
      ruby2_keywords
      selenium-webdriver (>= 3)
    childprocess (4.1.0)
    cocoon (1.2.15)
    code_owners (2.0.1)
      pathspec
      rake
    coderay (1.1.3)
    combine_pdf (1.0.22)
      matrix
      ruby-rc4 (>= 0.1.5)
    concurrent-ruby (1.2.0)
    config (3.1.0)
      deep_merge (~> 1.2, >= 1.2.1)
      dry-validation (~> 1.0, >= 1.0.0)
    connection_pool (2.3.0)
    cookiejar (0.3.3)
    countries (5.3.0)
      unaccent (~> 0.3)
    crack (0.4.5)
      rexml
    crass (1.0.6)
    datadog_api_client (2.1.0)
      httparty (~> 0.20, >= 0.20.0)
      zeitwerk (~> 2.6, >= 2.6.0)
    datetime_picker_rails (0.0.7)
      momentjs-rails (>= 2.8.1)
    db-query-matchers (0.11.0)
      activesupport (>= 4.0, < 7.1)
      rspec (>= 3.0)
    ddtrace (1.5.0)
      debase-ruby_core_source (>= 0.10.16, <= 0.10.17)
      libdatadog (~> 0.7.0.1.1)
      libddwaf (~> 1.3.0.2.0)
      msgpack
    debase-ruby_core_source (0.10.17)
    deep_merge (1.2.1)
    devise-pwned_password (0.1.9)
      devise (~> 4)
      pwned (~> 2.0.0)
    diff-lcs (1.5.0)
    digest (3.1.0)
    docile (1.3.5)
    docusign_esign (3.19.0)
      addressable (~> 2.7, >= 2.7.0)
      json (~> 2.1, >= 2.1.0)
      jwt (~> 2.2, >= 2.2.1)
      typhoeus (~> 1.0, >= 1.0.1)
    dogstatsd-ruby (5.5.0)
    domain_name (0.5.20190701)
      unf (>= 0.0.5, < 1.0.0)
    doorkeeper (5.6.5)
      railties (>= 5)
    dotenv (2.7.6)
    dotenv-rails (2.7.6)
      dotenv (= 2.7.6)
      railties (>= 3.2)
    down (5.3.1)
      addressable (~> 2.8)
    dry-cli (0.7.0)
    dry-configurable (0.13.0)
      concurrent-ruby (~> 1.0)
      dry-core (~> 0.6)
    dry-container (0.9.0)
      concurrent-ruby (~> 1.0)
      dry-configurable (~> 0.13, >= 0.13.0)
    dry-core (0.7.1)
      concurrent-ruby (~> 1.0)
    dry-inflector (0.2.1)
    dry-initializer (3.0.4)
    dry-logic (1.2.0)
      concurrent-ruby (~> 1.0)
      dry-core (~> 0.5, >= 0.5)
    dry-schema (1.8.0)
      concurrent-ruby (~> 1.0)
      dry-configurable (~> 0.13, >= 0.13.0)
      dry-core (~> 0.5, >= 0.5)
      dry-initializer (~> 3.0)
      dry-logic (~> 1.0)
      dry-types (~> 1.5)
    dry-types (1.5.1)
      concurrent-ruby (~> 1.0)
      dry-container (~> 0.3)
      dry-core (~> 0.5, >= 0.5)
      dry-inflector (~> 0.1, >= 0.1.2)
      dry-logic (~> 1.0, >= 1.0.2)
    dry-validation (1.7.0)
      concurrent-ruby (~> 1.0)
      dry-container (~> 0.7, >= 0.7.1)
      dry-core (~> 0.5, >= 0.5)
      dry-initializer (~> 3.0)
      dry-schema (~> 1.8, >= 1.8.0)
    e2mmap (0.1.0)
    em-http-request (1.1.7)
      addressable (>= 2.3.4)
      cookiejar (!= 0.3.1)
      em-socksify (>= 0.3)
      eventmachine (>= 1.0.3)
      http_parser.rb (>= 0.6.0)
    em-socksify (0.3.2)
      eventmachine (>= 1.0.0.beta.4)
    em-synchrony (1.0.6)
      eventmachine (>= 1.0.0.beta.1)
    erubi (1.11.0)
    et-orbi (1.2.6)
      tzinfo
    ethon (0.15.0)
      ffi (>= 1.15.0)
    eventmachine (1.2.7)
    eventmachine_httpserver (0.2.1)
    factory_bot (6.2.0)
      activesupport (>= 5.0.0)
    factory_bot_rails (6.2.0)
      factory_bot (~> 6.2.0)
      railties (>= 5.0.0)
    faker (2.20.0)
      i18n (>= 1.8.11, < 2)
    faraday (2.5.2)
      faraday-net_http (>= 2.0, < 3.1)
      ruby2_keywords (>= 0.0.4)
    faraday-multipart (1.0.4)
      multipart-post (~> 2)
    faraday-net_http (3.0.2)
    faraday-net_http_persistent (2.1.0)
      faraday (~> 2.5)
      net-http-persistent (~> 4.0)
    faraday-retry (2.0.0)
      faraday (~> 2.0)
    fast_excel (0.4.0)
      ffi (> 1.9, < 2)
    ffi (1.15.5)
    ffi-compiler (1.0.1)
      ffi (>= 1.0.0)
      rake
    formatador (1.1.0)
    fugit (1.5.2)
      et-orbi (~> 1.1, >= 1.1.8)
      raabro (~> 1.4)
    globalid (1.0.1)
      activesupport (>= 5.0)
    gon (6.4.0)
      actionpack (>= 3.0.20)
      i18n (>= 0.7)
      multi_json
      request_store (>= 1.0)
    good_migrations (0.2.1)
      activerecord (>= 3.1)
      railties (>= 3.1)
    google-protobuf (3.21.7)
    graphql (2.0.14)
    graphql-batch (0.5.1)
      graphql (>= 1.10, < 3)
      promise.rb (~> 0.7.2)
    graphql-pagination (2.0.1)
      graphql (~> 2.0)
    graphql-rails_logger (1.2.3)
      actionpack (> 5.0)
      activesupport (> 5.0)
      railties (> 5.0)
      rouge (~> 3.0)
    guard (2.18.0)
      formatador (>= 0.2.4)
      listen (>= 2.7, < 4.0)
      lumberjack (>= 1.0.12, < 2.0)
      nenv (~> 0.1)
      notiffany (~> 0.0)
      pry (>= 0.13.0)
      shellany (~> 0.0)
      thor (>= 0.18.1)
    guard-compat (1.2.1)
    guard-rspec (4.7.3)
      guard (~> 2.1)
      guard-compat (~> 1.1)
      rspec (>= 2.99.0, < 4.0)
    guard-rubocop (1.5.0)
      guard (~> 2.0)
      rubocop (< 2.0)
    gyoku (1.4.0)
      builder (>= 2.1.2)
      rexml (~> 3.0)
    hairtrigger (0.2.25)
      activerecord (>= 5.0, < 8)
      ruby2ruby (~> 2.4)
      ruby_parser (~> 3.10)
    hashdiff (1.0.1)
    hashery (2.1.2)
    hashie (5.0.0)
    http (5.1.0)
      addressable (~> 2.8)
      http-cookie (~> 1.0)
      http-form_data (~> 2.2)
      llhttp-ffi (~> 0.4.0)
    http-cookie (1.0.5)
      domain_name (~> 0.5)
    http-form_data (2.3.0)
    http_parser.rb (0.6.0)
    httparty (0.21.0)
      mini_mime (>= 1.0.0)
      multi_xml (>= 0.5.2)
    httpi (3.0.1)
      rack
    hubspot-api-client (14.5.2)
      json (~> 2.1, >= 2.1.0)
      require_all (~> 3.0.0)
      typhoeus (~> 1.4.0)
    humanize (2.5.1)
    i18n (1.12.0)
      concurrent-ruby (~> 1.0)
    ibandit (1.9.0)
      i18n
    ice_nine (0.11.2)
    image_processing (1.12.2)
      mini_magick (>= 4.9.5, < 5)
      ruby-vips (>= 2.0.17, < 3)
    inflection (1.0.0)
    intercom-rails (0.4.2)
      activesupport (> 3.0)
    jaro_winkler (1.5.4)
    jmespath (1.6.1)
    jquery-rails (4.5.0)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    json (2.6.2)
    json-schema (2.8.1)
      addressable (>= 2.4)
    jwt (2.6.0)
    kaminari (1.2.2)
      activesupport (>= 4.1.0)
      kaminari-actionview (= 1.2.2)
      kaminari-activerecord (= 1.2.2)
      kaminari-core (= 1.2.2)
    kaminari-actionview (1.2.2)
      actionview
      kaminari-core (= 1.2.2)
    kaminari-activerecord (1.2.2)
      activerecord
      kaminari-core (= 1.2.2)
    kaminari-core (1.2.2)
    knapsack (4.0.0)
      rake
    kramdown (2.4.0)
      rexml
    kramdown-parser-gfm (1.1.0)
      kramdown (~> 2.0)
    language_server-protocol (3.17.0.3)
    launchdarkly-server-sdk (6.4.0)
      concurrent-ruby (~> 1.1)
      http (>= 4.4.0, < 6.0.0)
      json (~> 2.3)
      ld-eventsource (= 2.2.1)
      semantic (~> 1.6)
    ld-eventsource (2.2.1)
      concurrent-ruby (~> 1.0)
      http (>= 4.4.1, < 6.0.0)
    libdatadog (0.7.0.1.1)
    libddwaf (1.3.0.2.0)
      ffi (~> 1.0)
    licensed (3.9.1)
      bundler (>= 1.10)
      json (>= 2.6.2)
      licensee (>= 9.15.2, < 10.0.0)
      parallel (>= 0.18.0)
      pathname-common_prefix (~> 0.0.1)
      reverse_markdown (>= 1, < 3)
      ruby-xxHash (~> 0.4)
      thor (>= 0.19)
      tomlrb (>= 1.2, < 3.0)
    licensee (9.15.3)
      dotenv (~> 2.0)
      octokit (>= 4.20, < 7.0)
      reverse_markdown (>= 1, < 3)
      rugged (>= 0.24, < 2.0)
      thor (>= 0.19, < 2.0)
    listen (3.7.1)
      rb-fsevent (~> 0.10, >= 0.10.3)
      rb-inotify (~> 0.9, >= 0.9.10)
    llhttp-ffi (0.4.0)
      ffi-compiler (~> 1.0)
      rake (~> 13.0)
    lograge (0.11.2)
      actionpack (>= 4)
      activesupport (>= 4)
      railties (>= 4)
      request_store (~> 1.0)
    loofah (2.19.1)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    lumberjack (1.2.8)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    marcel (1.0.2)
    matrix (0.4.2)
    method_source (1.0.0)
    mime-types (3.4.1)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2022.0105)
    mini_magick (4.11.0)
    mini_mime (1.1.2)
    mini_portile2 (2.8.1)
    minitest (5.16.3)
    momentjs-rails (2.29.1.1)
      railties (>= 3.1)
    monetize (1.12.0)
      money (~> 6.12)
    money (6.16.0)
      i18n (>= 0.6.4, <= 2)
    money-rails (1.15.0)
      activesupport (>= 3.0)
      monetize (~> 1.9)
      money (~> 6.13)
      railties (>= 3.0)
    msgpack (1.6.0)
    multi_json (1.15.0)
    multi_xml (0.6.0)
    multipart-post (2.2.3)
    mustermann (3.0.0)
      ruby2_keywords (~> 0.0.1)
    nenv (0.3.0)
    net-http-persistent (4.0.1)
      connection_pool (~> 2.2)
    net-imap (0.2.3)
      digest
      net-protocol
      strscan
    net-pop (0.1.1)
      digest
      net-protocol
      timeout
    net-protocol (0.1.3)
      timeout
    net-smtp (0.3.1)
      digest
      net-protocol
      timeout
    netsuite (0.9.2)
      savon (>= 2.3.0, != 2.13.0)
    nio4r (2.5.8)
    nokogiri (1.13.10)
      mini_portile2 (~> 2.8.0)
      racc (~> 1.4)
    nori (2.6.0)
    notiffany (0.1.3)
      nenv (~> 0.1)
      shellany (~> 0.0)
    oauth2 (1.4.11)
      faraday (>= 0.17.3, < 3.0)
      jwt (>= 1.0, < 3.0)
      multi_json (~> 1.3)
      multi_xml (~> 0.5)
      rack (>= 1.2, < 4)
    octokit (6.0.1)
      faraday (>= 1, < 3)
      sawyer (~> 0.9)
    omniauth (2.1.1)
      hashie (>= 3.4.6)
      rack (>= 2.2.3)
      rack-protection
    omniauth-google-oauth2 (0.8.1)
      jwt (>= 2.0)
      oauth2 (~> 1.1)
      omniauth (>= 1.1.1)
      omniauth-oauth2 (>= 1.6)
    omniauth-oauth2 (1.7.1)
      oauth2 (~> 1.4)
      omniauth (>= 1.9, < 3)
    omniauth-okta (2.0.0)
      omniauth (~> 2.0)
      omniauth-oauth2 (~> 1.7, >= 1.7.1)
    omniauth-rails_csrf_protection (1.0.0)
      actionpack (>= 4.2)
      omniauth (~> 2.0)
    orm_adapter (0.5.0)
    oso-cloud (1.0.0)
      faraday (~> 2.5.2)
      faraday-retry (~> 2.0.0)
    paper_trail (12.3.0)
      activerecord (>= 5.2)
      request_store (~> 1.1)
    parallel (1.22.1)
    parallel_tests (3.8.1)
      parallel
    paranoia (2.6.0)
      activerecord (>= 5.1, < 7.1)
    parser (3.2.1.1)
      ast (~> 2.4.1)
    pathname-common_prefix (0.0.1)
    pathspec (1.1.3)
    pdf-core (0.9.0)
    pdf-inspector (1.3.0)
      pdf-reader (>= 1.0, < 3.0.a)
    pdf-reader (2.10.0)
      Ascii85 (~> 1.0)
      afm (~> 0.2.1)
      hashery (~> 2.0)
      ruby-rc4
      ttfunk
    pg (1.3.4)
    phone (1.2.3)
    plaid (17.2.0)
      faraday (>= 1.0.1, < 3.0)
      faraday-multipart (>= 1.0.1, < 2.0)
    possessive (1.0.1)
    postmark (1.22.0)
      json
    postmark-rails (0.22.0)
      actionmailer (>= 3.0.0)
      postmark (>= 1.21.3, < 2.0)
    prawn (2.4.0)
      pdf-core (~> 0.9.0)
      ttfunk (~> 1.7)
    prawn-table (0.2.2)
      prawn (>= 1.3.0, < 3.0.0)
    promise.rb (0.7.4)
    pry (0.13.1)
      coderay (~> 1.1)
      method_source (~> 1.0)
    pry-byebug (3.9.0)
      byebug (~> 11.0)
      pry (~> 0.13.0)
    pry-rails (0.3.9)
      pry (>= 0.10.4)
    public_suffix (5.0.1)
    puffing-billy (3.0.2)
      addressable (~> 2.5)
      em-http-request (~> 1.1, >= 1.1.0)
      em-synchrony
      eventmachine (~> 1.2)
      eventmachine_httpserver
      http_parser.rb (~> 0.6.0)
      multi_json
    puma (5.6.4)
      nio4r (~> 2.0)
    pwned (2.0.2)
    raabro (1.4.0)
    racc (1.6.2)
    rack (2.2.6.4)
    rack-attack (6.6.1)
      rack (>= 1.0, < 3)
    rack-cors (1.1.1)
      rack (>= 2.0.0)
    rack-protection (3.0.4)
      rack
    rack-proxy (0.7.4)
      rack
    rack-test (2.0.2)
      rack (>= 1.3)
    rack-timeout (0.6.0)
    rails (7.0.4.3)
      actioncable (= 7.0.4.3)
      actionmailbox (= 7.0.4.3)
      actionmailer (= 7.0.4.3)
      actionpack (= 7.0.4.3)
      actiontext (= 7.0.4.3)
      actionview (= 7.0.4.3)
      activejob (= 7.0.4.3)
      activemodel (= 7.0.4.3)
      activerecord (= 7.0.4.3)
      activestorage (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      bundler (>= 1.15.0)
      railties (= 7.0.4.3)
    rails-controller-testing (1.0.5)
      actionpack (>= 5.0.1.rc1)
      actionview (>= 5.0.1.rc1)
      activesupport (>= 5.0.1.rc1)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.4.4)
      loofah (~> 2.19, >= 2.19.1)
    rails_event_store (2.4.1)
      activejob (>= 3.0)
      activemodel (>= 3.0)
      activesupport (>= 3.0)
      aggregate_root (= 2.4.1)
      arkency-command_bus (>= 0.4)
      rails_event_store_active_record (= 2.4.1)
      ruby_event_store (= 2.4.1)
      ruby_event_store-browser (= 2.4.1)
    rails_event_store_active_record (2.4.1)
      activerecord (>= 6.0)
      ruby_event_store (= 2.4.1)
    railties (7.0.4.3)
      actionpack (= 7.0.4.3)
      activesupport (= 7.0.4.3)
      method_source
      rake (>= 12.2)
      thor (~> 1.0)
      zeitwerk (~> 2.5)
    rainbow (3.1.1)
    rake (13.0.6)
    rb-fsevent (0.11.1)
    rb-inotify (0.10.1)
      ffi (~> 1.0)
    redis (4.8.0)
    redis-namespace (1.8.2)
      redis (>= 3.0.4)
    regexp_parser (2.7.0)
    request_store (1.5.1)
      rack (>= 1.4)
    require_all (3.0.0)
    responders (3.0.1)
      actionpack (>= 5.0)
      railties (>= 5.0)
    reverse_markdown (2.1.1)
      nokogiri
    rexml (3.2.5)
    roo (2.9.0)
      nokogiri (~> 1)
      rubyzip (>= 1.3.0, < 3.0.0)
    rouge (3.30.0)
    rspec (3.11.0)
      rspec-core (~> 3.11.0)
      rspec-expectations (~> 3.11.0)
      rspec-mocks (~> 3.11.0)
    rspec-core (3.11.0)
      rspec-support (~> 3.11.0)
    rspec-expectations (3.11.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.11.0)
    rspec-github (2.3.1)
      rspec-core (~> 3.0)
    rspec-github-actions-formatter (0.2.0)
    rspec-mocks (3.11.0)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.11.0)
    rspec-rails (5.1.1)
      actionpack (>= 5.2)
      activesupport (>= 5.2)
      railties (>= 5.2)
      rspec-core (~> 3.10)
      rspec-expectations (~> 3.10)
      rspec-mocks (~> 3.10)
      rspec-support (~> 3.10)
    rspec-retry (0.6.2)
      rspec-core (> 3.3)
    rspec-support (3.11.0)
    rspec_junit_formatter (0.5.1)
      rspec-core (>= 2, < 4, != 2.12.0)
    rubocop (1.44.1)
      json (~> 2.3)
      parallel (~> 1.10)
      parser (>= 3.2.0.0)
      rainbow (>= 2.2.2, < 4.0)
      regexp_parser (>= 1.8, < 3.0)
      rexml (>= 3.2.5, < 4.0)
      rubocop-ast (>= 1.24.1, < 2.0)
      ruby-progressbar (~> 1.7)
      unicode-display_width (>= 2.4.0, < 3.0)
    rubocop-ast (1.27.0)
      parser (>= 3.2.1.0)
    rubocop-performance (1.15.2)
      rubocop (>= 1.7.0, < 2.0)
      rubocop-ast (>= 0.4.0)
    rubocop-rails (2.14.2)
      activesupport (>= 4.2.0)
      rack (>= 1.1)
      rubocop (>= 1.7.0, < 2.0)
    rubocop-rspec (2.10.0)
      rubocop (~> 1.19)
    ruby-calendarific (1.0.1)
    ruby-progressbar (1.13.0)
    ruby-rc4 (0.1.5)
    ruby-vips (2.1.4)
      ffi (~> 1.12)
    ruby-xxHash (0.4.0.2)
    ruby2_keywords (0.0.5)
    ruby2ruby (2.4.4)
      ruby_parser (~> 3.1)
      sexp_processor (~> 4.6)
    rubyXL (3.4.24)
      nokogiri (>= 1.10.8)
      rubyzip (>= 1.3.0)
    ruby_event_store (2.4.1)
      concurrent-ruby (~> 1.0, >= 1.1.6)
    ruby_event_store-browser (2.4.1)
      ruby_event_store (= 2.4.1)
      sinatra
    ruby_event_store-rspec (2.4.1)
      rspec (~> 3.0)
    ruby_parser (3.19.0)
      sexp_processor (~> 4.16)
    rubytree (2.0.0)
      json (~> 2.0, > 2.3.1)
    rubyzip (2.3.2)
    rufus-scheduler (3.8.1)
      fugit (~> 1.1, >= 1.1.6)
    rugged (1.5.0.1)
    sassc (2.4.0)
      ffi (~> 1.9)
    sassc-rails (2.1.2)
      railties (>= 4.0.0)
      sassc (>= 2.0)
      sprockets (> 3.0)
      sprockets-rails
      tilt
    savon (2.14.0)
      akami (~> 1.2)
      builder (>= 2.1.2)
      gyoku (~> 1.2)
      httpi (>= 2.4.5)
      mail (~> 2.5)
      nokogiri (>= 1.8.1)
      nori (~> 2.4)
      wasabi (~> 3.4)
    sawyer (0.9.2)
      addressable (>= 2.3.5)
      faraday (>= 0.17.3, < 3)
    scenic (1.6.0)
      activerecord (>= 4.0.0)
      railties (>= 4.0.0)
    scientist (1.6.3)
    selectize-rails (0.12.6)
    selenium-webdriver (4.6.1)
      childprocess (>= 0.5, < 5.0)
      rexml (~> 3.2, >= 3.2.5)
      rubyzip (>= 1.2.2, < 3.0)
      websocket (~> 1.0)
    semantic (1.6.1)
    sentry-rails (5.2.1)
      railties (>= 5.0)
      sentry-ruby-core (~> 5.2.1)
    sentry-ruby (5.2.1)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      sentry-ruby-core (= 5.2.1)
    sentry-ruby-core (5.2.1)
      concurrent-ruby
    sentry-sidekiq (5.2.1)
      sentry-ruby-core (~> 5.2.1)
      sidekiq (>= 3.0)
    sexp_processor (4.16.0)
    shellany (0.0.1)
    shoulda-matchers (5.1.0)
      activesupport (>= 5.2.0)
    sidekiq (6.4.2)
      connection_pool (>= 2.2.2)
      rack (~> 2.0)
      redis (>= 4.2.0)
    sidekiq-failures (1.0.1)
      sidekiq (>= 4.0.0)
    sidekiq-scheduler (3.1.1)
      e2mmap
      redis (>= 3, < 5)
      rufus-scheduler (~> 3.2)
      sidekiq (>= 3)
      thwait
      tilt (>= 1.4.0)
    sidekiq-unique-jobs (7.1.29)
      brpoplpush-redis_script (> 0.1.1, <= 2.0.0)
      concurrent-ruby (~> 1.0, >= 1.0.5)
      redis (< 5.0)
      sidekiq (>= 5.0, < 7.0)
      thor (>= 0.20, < 3.0)
    simplecov (0.21.2)
      docile (~> 1.1)
      simplecov-html (~> 0.11)
      simplecov_json_formatter (~> 0.1)
    simplecov-html (0.12.3)
    simplecov_json_formatter (0.1.2)
    sinatra (3.0.4)
      mustermann (~> 3.0)
      rack (~> 2.2, >= 2.2.4)
      rack-protection (= 3.0.4)
      tilt (~> 2.0)
    slack-notifier (2.4.0)
    solargraph (0.47.2)
      backport (~> 1.2)
      benchmark
      bundler (>= 1.17.2)
      diff-lcs (~> 1.4)
      e2mmap
      jaro_winkler (~> 1.5)
      kramdown (~> 2.3)
      kramdown-parser-gfm (~> 1.1)
      parser (~> 3.0)
      reverse_markdown (>= 1.0.5, < 3)
      rubocop (>= 0.52)
      thor (~> 1.0)
      tilt (~> 2.0)
      yard (~> 0.9, >= 0.9.24)
    spring (3.1.1)
    spring-commands-rspec (1.0.4)
      spring (>= 0.9.1)
    sprockets (4.1.1)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.4.2)
      actionpack (>= 5.2)
      activesupport (>= 5.2)
      sprockets (>= 3.0.0)
    standard (1.24.3)
      language_server-protocol (~> 3.17.0.2)
      rubocop (= 1.44.1)
      rubocop-performance (= 1.15.2)
    stripe (5.30.0)
    strong_migrations (1.1.0)
      activerecord (>= 5.2)
    strscan (3.0.3)
    thor (1.2.1)
    thwait (0.2.0)
      e2mmap
    tilt (2.0.11)
    timeout (0.3.0)
    tomlrb (2.0.3)
    ttfunk (1.7.0)
    typhoeus (1.4.0)
      ethon (>= 0.9.0)
    tzinfo (2.0.5)
      concurrent-ruby (~> 1.0)
    tzinfo-data (1.2022.3)
      tzinfo (>= 1.0.0)
    unaccent (0.4.0)
    unf (0.1.4)
      unf_ext
    unf_ext (0.0.8.2)
    unicode-display_width (2.4.2)
    vcr (6.1.0)
    vite_rails (3.0.13)
      railties (>= 5.1, < 8)
      vite_ruby (~> 3.0, >= 3.2.2)
    vite_ruby (3.2.13)
      dry-cli (~> 0.7.0)
      rack-proxy (~> 0.6, >= 0.6.1)
      zeitwerk (~> 2.2)
    warden (1.2.9)
      rack (>= 2.0.9)
    wasabi (3.8.0)
      addressable
      httpi (~> 3.0)
      nokogiri (>= 1.4.2)
    web-console (4.2.0)
      actionview (>= 6.0.0)
      activemodel (>= 6.0.0)
      bindex (>= 0.4.0)
      railties (>= 6.0.0)
    webdrivers (5.2.0)
      nokogiri (~> 1.6)
      rubyzip (>= 1.3.0)
      selenium-webdriver (~> 4.0)
    webmock (3.18.1)
      addressable (>= 2.8.0)
      crack (>= 0.3.2)
      hashdiff (>= 0.4.0, < 2.0.0)
    webrick (1.7.0)
    websocket (1.2.9)
    websocket-driver (0.7.5)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    wisper (2.0.1)
    wisper-rspec (1.1.0)
    write_xlsx (1.09.3)
      rubyzip (>= 1.0.0)
      zip-zip
    xpath (3.2.0)
      nokogiri (~> 1.8)
    yard (0.9.28)
      webrick (~> 1.7.0)
    zeitwerk (2.6.6)
    zendesk_api (1.38.0.rc1)
      faraday (> 2.0.0)
      faraday-multipart
      hashie (>= 3.5.2, < 6.0.0)
      inflection
      mini_mime
      multipart-post (~> 2.0)
    zip-zip (0.3)
      rubyzip (>= 1.0.0)

PLATFORMS
  ruby

DEPENDENCIES
  aasm (~> 5.0, >= 5.2.0)
  administrate
  administrate-field-active_storage
  administrate-field-enum
  administrate-field-jsonb
  administrate-field-nested_has_many
  after_commit_everywhere (~> 0.1, >= 0.1.5)
  analytics-ruby (~> 2.0.0)
  argo!
  awesome_print
  aws-sdk-s3
  bootsnap (>= 1.4.2)
  brain!
  bundle-audit
  byebug
  capybara (>= 3.37.1)
  capybara-lockstep
  codat!
  code_owners
  combine_pdf
  config
  connection_pool
  countries
  datadog_api_client (~> 2.1.0)
  db-query-matchers
  ddtrace (~> 1.0)
  dealer!
  devise!
  devise-pwned_password
  dogstatsd-ruby
  doorkeeper
  dotenv-rails
  down
  expensify!
  factory_bot_rails
  faker
  faraday (~> 2.0)
  fast_excel
  fugit
  gon
  good_migrations
  google-protobuf (~> 3.21)
  graphql
  graphql-batch
  graphql-pagination
  graphql-rails_logger
  guard
  guard-rspec
  guard-rubocop
  hairtrigger
  hellosign-api!
  httparty
  hubspot-api-client
  humanize
  iam!
  ibandit (~> 1.9.0)
  ice_nine (~> 0.11.2)
  image_processing
  intercom-rails
  json-schema (~> 2.8)
  jwt
  kaminari-activerecord
  knapsack
  launchdarkly-server-sdk
  licensed
  lograge
  mail
  matrix
  money
  money-rails
  multipart-post (~> 2.1)
  net-imap
  net-pop
  net-smtp
  netsuite
  omniauth (>= 2.1.0)
  omniauth-google-oauth2
  omniauth-okta
  omniauth-rails_csrf_protection
  oyster-action!
  oyster-common!
  oyster-events!
  paper_trail
  parallel_tests
  paranoia
  parser
  pdf-inspector
  pg (>= 0.18, < 2.0)
  phone
  plaid
  possessive (~> 1.0, >= 1.0.1)
  postmark-rails
  prawn
  prawn-table
  pry-byebug
  pry-rails
  puffing-billy
  puma (~> 5.6)
  rack-attack
  rack-cors
  rack-timeout
  rails (~> 7.0.4, >= 7.0.4.3)
  rails-controller-testing
  rails_event_store
  rainbow
  redis
  redis-namespace
  roo (~> 2.9.0)
  rspec-github
  rspec-github-actions-formatter
  rspec-rails (~> 5.1.1)
  rspec-retry
  rspec_junit_formatter
  rubocop
  rubocop-rails
  rubocop-rspec (~> 2.8)
  ruby-calendarific (~> 1.0)
  rubyXL (>= 3.4.24, < 4.0)
  rubyzip
  sage-decision!
  scenic
  scientist
  selenium-webdriver
  sentry-rails (~> 5.2.1)
  sentry-ruby (~> 5.2.0)
  sentry-sidekiq (~> 5.2.1)
  shoulda-matchers
  sidekiq-failures
  sidekiq-pro!
  sidekiq-scheduler
  sidekiq-unique-jobs (~> 7.1.29)
  simplecov
  slack-notifier
  solargraph
  spring (~> 3.1)
  spring-commands-rspec
  standard (~> 1.10)
  stripe (~> 5.30.0)
  strong_migrations
  tzinfo-data
  vcr
  vite_rails
  web-console (>= 4.2.0)
  webdrivers
  webmock (>= 3.18.1)
  wisper (~> 2.0.1)
  wisper-rspec (~> 1.1)
  write_xlsx (~> 1.09)
  zendesk_api (= 1.38.0.rc1)

RUBY VERSION
   ruby 3.1.2p20

BUNDLED WITH
   2.3.7

I've had to add this to get around the error:

Doorkeeper::Config::Validations.prepend(Module.new do
  def validate_custom_access_token_attributes; end
end)
raivil commented

Seems the same/related to #1642

nbulaj commented

Should be fixed with 5.6.6 release @matthewheath