member_center/docs/ADMIN_AUTHORIZATION.md
2026-07-03 15:42:49 +09:00

3.9 KiB

Admin Authorization

Purpose

The admin authorization model separates a user's organizational role from the individual admin capabilities granted to that role. The schema supports multiple roles even though the initial non-superuser role is only admin.

Core Rules

  1. superuser is a hard-coded emergency and governance role.

    • It does not depend on database permission mappings.
    • It bypasses all admin permission checks.
    • Creating a replacement superuser or resetting its password remains an installer responsibility.
    • Superuser-only account governance actions continue to require the Superuser authorization policy.
  2. Normal admin access uses Role-Based Access Control.

    • A user may have one or more Identity roles through user_roles.
    • A role may have one or more admin permissions through admin_role_permissions.
    • A user's effective permissions are the union of permissions assigned to all of the user's roles.
  3. Roles and role-permission mappings are database data.

    • Existing ASP.NET Core Identity roles and user_roles tables remain the source of role membership.
    • admin_permissions stores the known permission catalog.
    • admin_role_permissions maps any Identity role to any admin permission.
    • Adding roles such as support, auditor, or security_admin does not require another schema change.
  4. Permission definitions are owned by application code.

    • Permission keys are declared in AdminPermissions.
    • Startup and installer seeding synchronize those known definitions into the database.
    • The database decides which roles receive known permissions; it must not be used to invent capabilities that have no application implementation.
  5. Permissions are action-oriented.

    • Controllers require a module permission such as admin.tenants.
    • Actions also require a capability permission such as admin.tenants.create or admin.tenants.delete.
    • Operations with materially different authorization boundaries must be separate actions and separate permission keys.
  6. Server-side checks are authoritative.

    • Admin controllers retain [Authorize(Policy = "Admin")] as the outer admin boundary.
    • Controllers and actions use AdminPermissionAttribute for database-backed permission checks.
    • Non-admin access to /admin/* continues to return HTTP 404.
    • Missing action permissions also return HTTP 404 so inaccessible admin capabilities are not exposed.
  7. Navigation and operation links use the same permission catalog.

    • Admin menus reference the same AdminPermissions constants used by the corresponding controller actions.
    • Buttons and links are hidden when the current user lacks the target action permission.
    • UI visibility is only a usability measure; direct requests are always protected by controller/action checks.

Initial Mapping

The initial admin role receives every known permission except permissions marked as superuser-only. This preserves current behavior while allowing the mapping to be divided among more roles later.

The initial superuser-only permissions are:

  • admin.accounts.set_admin
  • admin.accounts.set_disabled
  • admin.accounts.reset_password

No role or permission maintenance UI is included yet. Until one is introduced, the permission catalog is updated in code and role-permission mappings may be managed through controlled database changes or future installer commands.

Adding an Admin Capability

  1. Add a constant and definition to AdminPermissions.
  2. Apply the module permission to the controller.
  3. Apply the capability permission to every relevant action.
  4. Use the same action permission for related menu items, links, and buttons.
  5. Add or update role-permission mappings through the approved seed or administrative workflow.
  6. Verify direct access, navigation visibility, admin, and superuser behavior.