Configuration

AdminSuite is configured via an initializer:

  • config/initializers/admin_suite.rb (generated by bin/rails g admin_suite:install)

All configuration lives on AdminSuite.config (an AdminSuite::Configuration instance).

Minimal secure configuration

# config/initializers/admin_suite.rb
AdminSuite.configure do |config|
  config.authenticate = ->(controller) do
    # Example: require an admin user
    controller.redirect_to(controller.main_app.root_path) unless controller.respond_to?(:current_user) && controller.current_user&.admin?
  end

  config.current_actor = ->(controller) do
    controller.respond_to?(:current_user) ? controller.current_user : nil
  end
end

Defaults

These are the defaults in AdminSuite::Configuration / AdminSuite::Engine:

  • authenticate: nil
  • current_actor: nil
  • authorize: nil
  • auth_strategy: nil
  • auth_options: {}
  • allow_unauthenticated: false
  • skip_host_before_actions: [:require_authentication]
  • logout_path: nil
  • logout_method: :delete
  • logout_label: "Log out"
  • resource_globs: defaults to:
    • Rails.root/config/admin_suite/resources/*.rb
    • Rails.root/app/admin/resources/*.rb
  • action_globs: defaults to:
    • Rails.root/config/admin_suite/actions/*.rb
    • Rails.root/app/admin/actions/*.rb
  • portal_globs: defaults to:
    • Rails.root/config/admin_suite/portals/*.rb
    • Rails.root/app/admin/portals/*.rb
    • Rails.root/app/admin_suite/portals/*.rb
  • dashboard_globs: defaults to:
    • Rails.root/config/admin_suite/dashboard.rb
    • Rails.root/config/admin_suite/dashboard/*.rb
    • Rails.root/app/admin_suite/dashboard.rb
    • Rails.root/app/admin_suite/dashboard/*.rb

Note: AdminSuite definition files (resources, actions, portals) often don’t follow Zeitwerk’s path-to-constant naming conventions. To prevent eager-load Zeitwerk::NameErrors in production, the engine only configures Zeitwerk to ignore these directories and load them via globs instead:

  • app/admin_suite
  • app/admin/portals (when portal DSL usage is detected)

Other app/admin/* directories (such as app/admin/resources, app/admin/actions, and app/admin/base) are not ignored by default and may be treated as normal Zeitwerk autoload paths if they are added to the loader (for example, via loader.push_dir("app/admin") in the host app). Do not rely on these directories being ignored for autoloading; instead, keep files there Zeitwerk-compatible.

We recommend placing non-Zeitwerk-compatible definition files under config/admin_suite/* or app/admin_suite/* for clearer separation from standard Rails autoloading.

  • portals: default portal metadata for :ops, :email, :ai, :assistant
  • custom_renderers: {}
  • icon_renderer: nil (uses lucide-rails by default when available)
  • docs_url: nil
  • docs_path: Rails.root.join("docs")
  • partials: {}
  • theme: { primary: :indigo, secondary: :purple }
  • host_stylesheet: nil
  • on_action_executed: nil
  • resolve_action_handler: nil

Options

authenticate

Called as a before_action inside the engine.

  • Type: Proc or nil
  • Signature: ->(controller) { ... }

If neither an authentication strategy nor this legacy hook is configured, AdminSuite denies requests.

current_actor

Used by actions/auditing hooks to identify “who initiated this”.

  • Type: Proc or nil
  • Signature: ->(controller) { current_user }

authorize

Authorization hook (you can wire Pundit/CanCan/ActionPolicy/etc). AdminSuite calls it automatically as a before_action on every resource controller action — you don’t need to call it yourself.

  • Type: Proc or nil
  • Signature: ->(actor:, action:, resource:, record:, context:) { true/false }
  • Default: nil (authenticated web requests are allowed; MCP serves nothing)

action is one of :read, :create, :update, :destroy, :execute, mapped from the controller action (e.g. index/show → :read, edit/update/toggle → :update). A false or nil return from the hook renders 403 Forbidden and must not disclose or mutate data. See Authentication & authorization for the full verb table and the read_only mutation guard.

auth_strategy

Selects the authentication strategy AdminSuite uses for every request (before_action). Takes precedence over the legacy authenticate lambda.

  • Type: Symbol (registered strategy name, e.g. :http_basic) or Class (a subclass of AdminSuite::Auth::Strategy)
  • Default: nil

See Authentication & authorization.

auth_options

Options hash passed to auth_strategy.new(...) — e.g. :http_basic credentials.

  • Type: Hash
  • Default: {}

allow_unauthenticated

Runs AdminSuite without checking authentication. Ignored in production regardless of value — intended for local development and test only.

  • Type: true/false
  • Default: false

skip_host_before_actions

Host before_action filter names (declared on the host’s own ApplicationController) that AdminSuite skips on its own controllers, since it authenticates itself via auth_strategy/authenticate.

  • Type: Array<Symbol>
  • Default: [:require_authentication]

logout_path

Optional sign-out action shown in the top bar.

  • Type: Proc, String, Symbol, or nil
  • Proc signature: ->(view_context) { ... }

Example:

config.logout_path = ->(view) { view.main_app.internal_developer_logout_path }

logout_method

HTTP method for the topbar sign-out button.

  • Type: Symbol or String
  • Default: :delete

logout_label

Button label for the topbar sign-out action.

  • Type: String (or Proc for dynamic label)
  • Default: "Log out"

resource_globs

Where AdminSuite should load resource definition files from.

  • Type: Array<String>

Example:

config.resource_globs = [
  Rails.root.join("app/admin/resources/**/*.rb").to_s
]

action_globs

Where AdminSuite should load action handler files from (files that define custom action handlers, typically subclasses of Admin::Base::ActionHandler).

  • Type: Array<String>

Example:

config.action_globs = [
  Rails.root.join("app/admin/actions/**/*.rb").to_s
]

portal_globs

Where AdminSuite should load portal definition files from (files typically call AdminSuite.portal(:key) { ... }).

  • Type: Array<String>

dashboard_globs

Where AdminSuite should load the root dashboard definition file(s) from (files typically call AdminSuite.root_dashboard { ... }).

  • Type: Array<String>

root_dashboard_title

Optional title shown on the root dashboard.

  • Type: String, Proc, or nil
  • Proc signature: ->(controller) { "Admin Suite" }

root_dashboard_description

Optional description shown on the root dashboard.

  • Type: String, Proc, or nil
  • Proc signature: ->(controller) { "..." }

portals

Portal metadata used for navigation (label/icon/color/order). This is separate from the portal DSL and can be used alone.

  • Type: Hash{Symbol => Hash}

Example:

config.portals = {
  ops: { label: "Ops", icon: "settings", color: :amber, order: 10 },
  billing: { label: "Billing", icon: "credit-card", color: :emerald, order: 20 }
}

Breaking change in 0.4.0: assigning config.portals = {} now suppresses the gem’s built-in default portals (:ops, :email, :ai, :assistant) instead of re-applying them. Before 0.4.0, {} was treated as blank and the defaults were applied on top of it regardless — so a host that explicitly cleared its portals still saw the four built-in portals in navigation. If you want the built-ins alongside your own, merge them explicitly rather than assigning an empty hash — the built-ins are:

config.portals = {
  ops: { label: "Ops Portal", icon: "settings", color: :amber, order: 10 },
  email: { label: "Email Portal", icon: "inbox", color: :emerald, order: 20 },
  ai: { label: "AI Portal", icon: "cpu", color: :cyan, order: 30 },
  assistant: { label: "Assistant Portal", icon: "message-circle", color: :violet, order: 40 }
}.merge(
  billing: { label: "Billing", icon: "credit-card", color: :emerald, order: 50 }
)

theme

Two-color theme used to set CSS variables scoped to AdminSuite.

  • Type: Hash with :primary and :secondary
  • Values: Tailwind-ish color names (:indigo, :emerald, …) or a hex string ("#4f46e5")

See Theming & assets.

host_stylesheet

If set, AdminSuite will include your host app stylesheet after its own styles in the engine layout.

  • Type: Symbol or String (passed to stylesheet_link_tag)
  • Example: config.host_stylesheet = :app

docs_url

If set, shows a “Docs” link in the AdminSuite sidebar.

  • Type: String or nil

docs_path

Filesystem path where the docs viewer reads markdown from.

  • Type: Pathname, String, or Proc
  • Proc signature: ->(controller) { Rails.root.join("docs") }

partials

Override specific engine partials.

  • Type: Hash

Example:

config.partials[:flash] = "shared/flash"
config.partials[:panel_stat] = "admin/panels/stat"

custom_renderers

Register custom show-section renderers (used when a show panel uses render: :your_key).

Deprecated as of 0.4.0 — still works, but new panel renderers should be AdminSuite::Renderer subclasses under app/admin/renderers/*.rb instead. See Renderers for the full API and a before/after migration example.

  • Type: Hash{Symbol => Proc}
  • Proc signature: ->(record, view_context) { ... }

Example:

config.custom_renderers[:billing_snapshot] = ->(record, view) do
  view.render(partial: "admin/billing_snapshot", locals: { record: record })
end

A legacy proc registered under a key always takes precedence over a Renderer class registered (or autoloaded) under the same key, so you can migrate one panel at a time.

icon_renderer

Replace the default icon provider (lucide-rails).

  • Type: Proc or nil
  • Proc signature: ->(name, view_context, **opts) { ... }

resolve_action_handler

Override how AdminSuite finds action handler classes.

  • Type: Proc or nil
  • Proc signature: ->(resource_class, action_name) { handler_class_or_nil }

See Actions.

on_action_executed

Hook called after action execution (success or failure).

  • Type: Proc or nil
  • Proc signature: ->(actor:, action_name:, resource_class:, subject:, params:, result:) { ... }

MCP (0.6.0)

config.mcp.enabled defaults to true; config.mcp.max_page_size defaults to 100. MCP still requires both an actor and an authorization hook. See Admin MCP.