Skip to content

ADR 012: Admins are users

  • Status: Accepted
  • Date: 2026-10-24
  • Deciders: Owner
  • Technical Context: apps/server (users.admin, Admin::BaseController, Devise removed); spec admin.md

Context

The admin area had its own sign-in: Devise with email and password on a separate admin_users table, a 12-hour idle timeout and its own profile page for changing the password. The owner signs in to the logbook with a passkey or magic link anyway, so there were two accounts, two sign-ins and a password to keep, and Devise was in the app only for this.

Decision

  • One kind of account. An admin is a user with users.admin = true. /admin checks it on every request; everyone else gets a 404, signed-out visitors the normal sign-in page with the way back.
  • Same session. Admins sign in with a passkey or magic link and keep the 60-day session like every user (owner's choice; no separate admin timeout).
  • No UI for admin rights. A migration made the owner's account the first admin; users:make_admin / users:revoke_admin on the server grant and take it away. An admin can't delete their own account from the admin users list.
  • Devise, AdminUser, the admin sign-in page and the admin password are removed. The admin_users table is dropped in a later migration, once both VMs run the new code (ADR 011: the worker deploys the mailers on its own timing).

Consequences

  • One sign-in for the owner; the account menu links to /admin.
  • Admin access is as strong as the user sign-in: passkey or a link to the admin's mailbox. Whoever controls the admin's email account controls the admin area.
  • No admin password to leak or reset; one gem less.
  • Admin notices go to the users with admin; with none, they aren't sent (as before with no admin user).